# You must make sure to run all cells in sequence using shift + enter or you might encounter errors
from pykubegrader.initialize import initialize_assignment
responses = initialize_assignment("homework_4", "week_4", "homework", assignment_points = 35.0, assignment_tag = 'week4-homework')
# Initialize Otter
import otter
grader = otter.Notebook("homework_4.ipynb")
๐ ๐งโโ๏ธ๐ Casting Spells and Conditional Loops: Homework That Taps Your Mana!#
Question 1: Card Rarity Detector#
Card Rarity Detector
In Magic: The Gathering, card rarities play a key role in gameplay and deck-building. Rarities include common, uncommon, rare, and mythic rare. Cards like โBlack Lotusโ or โJace, the Mind Sculptorโ are examples of mythic rare cards that are prized possessions.
Problem Statement#
Write a Python function card_rarity(score)
that determines the rarity of a Magic: The Gathering card based on its score, following these rules:
95-100: Mythic Rare
90-94: Rare
80-89: Uncommon
70-79: Common
0-69: Basic Land
Additionally:
Scores outside the valid range (0โ100) should return the message
"Invalid card score"
.
Implementation#
Define a function
card_rarity(score)
with an integer input argumentscore
. We provide this function for you.Implement a series of conditions to determine the rarity based on the given score.
Return the corresponding rarity as a string.
If the score is outside the valid range, return the message
"Invalid card score"
.
def card_rarity(score):
...
# Test the function
print(card_rarity(98)) # Mythic Rare
print(card_rarity(92)) # Rare
print(card_rarity(85)) # Uncommon
print(card_rarity(75)) # Common
print(card_rarity(50)) # Basic Land
print(card_rarity(105)) # Invalid card score
grader.check("mtg-card-rarity")
Question 1 (Points: 6.0): ๐งโโ๏ธ Question 2: Magic The Gathering Fibonacci Cards#
In Magic: The Gathering, creatures and spells often have synergistic effects. For example, creating a Fibonacci sequence of tokens represents a creative challenge for deck builders who utilize mechanics like โDoubling Seasonโ or โParallel Livesโ.
Problem Statement#
Create a function that generates a sequence of creature token powers based on a Fibonacci-like growth pattern. For example, โKalonian Hydraโ doubles its counters, and cards like โAether Vialโ enable incremental growth.
Write a function to simulate the Fibonacci sequence for such token growth mechanics.
A Fibonacci sequence is a list of integers in which the \(n\text{th}\) entry \(x_n\) is computed from:
To initiate a Fibbonaci sequence, one must provide values for \(x_0\) and \(x_1\).
For example, if \(x_0 = 0\) and \(x_1 = 1\), the first 10 terms of the sequence are:
Instructions#
Define a function called
fibonacci_tokens
that accepts 3 inputs:x0
: Initial power of the first token.x1
: Initial power of the second token.L
: The total number of tokens to generate in the sequence.
Implement the function to return a list of the first
L
Fibonacci-like token powers starting withx0
andx1
.Define a list
seq
to store the first two initial valuesx0
andx1
, of the sequence.Use a
for
loop to generate the remainingL-2
values of the sequence. I would recommend using therange
function to iterate over the remaining values.Append the new values to the list
seq
at each iteration, by indexing the last 2 elements of the list. Use the built-inappend
method of the list object. hint: This is a perfect opportunity to revisit the negative indexing of lists. Return the sequenceseq
if the input is valid.
If the input
L
is less than 2, print โFibonacci-like growth not possibleโ. Use if statements to enforce that the fibonacci sequence is not generated.
def fibonacci_tokens(x0, x1, L):
...
grader.check("mtg-fibonacci-tokens")
Question 2 (Points: 11.0): ๐งโโ๏ธ Question 3: Find the Best Card to Play#
In Magic The Gathering, choosing the right card to play at the right time can be the difference between victory and defeat. Suppose youโre building a deck that revolves around cards with varying mana costs, power, toughness, and special abilities.
Your task is to determine the best card to play given the available mana and the current game state.
Problem Statement#
Implement a function that evaluates a list of cards and finds the best card to play based on the following criteria:
The cardโs mana cost must not exceed the available mana in any color or the total mana.
The card with the highest combined power and toughness is preferred if multiple cards can be played.
In case of a tie in power and toughness, a card with a special ability (e.g., โTrampleโ) should be prioritized.
Instructions#
We have defined a function
find_best_card_to_play
that accepts the following inputs:available_mana
: A dictionary specifying the available mana in each color.
Example:available_mana = {"green": 3, "red": 2, "colorless": 1}
cards
: A list of dictionaries, where each dictionary represents a card with the following attributes:"name"
: Name of the card."mana_cost"
: A dictionary specifying the cardโs mana cost in each color."power"
: The cardโs power."toughness"
: The cardโs toughness."abilities"
: A list of special abilities (e.g.,["Trample", "Flying"]
).
Example:
cards = [ {"name": "Elf Warrior", "mana_cost": {"green": 2, "red": 0, "colorless": 0}, "power": 2, "toughness": 3, "abilities": []}, {"name": "Goblin Berserker", "mana_cost": {"green": 0, "red": 2, "colorless": 1}, "power": 3, "toughness": 2, "abilities": ["Trample"]}, {"name": "Orc Chieftain", "mana_cost": {"green": 1, "red": 1, "colorless": 1}, "power": 5, "toughness": 3, "abilities": []} ]
Evaluate all cards and find the one that:
Can be played with the available mana.
Has the highest combined power and toughness.
If tied, has at least one special ability.
Return the name of the best card to play. You can do that by assigning the name of the best card to a variable
best_card
, we have provided the return statement for you.If no card can be played, assign
"No card can be played"
to a variablebest_card
.
We have provided some additional inline comments to help you solve the problem.
Example Input:#
available_mana = {"green": 3, "red": 2, "colorless": 1}
cards = [
# Plains (White)
{"name": "Serra Angel", "mana_cost": {"white": 2, "blue": 0, "black": 0, "red": 0, "green": 0, "colorless": 3}, "power": 4, "toughness": 4, "abilities": ["Flying", "Vigilance"]},
{"name": "Loxodon Smiter", "mana_cost": {"white": 1, "blue": 0, "black": 0, "red": 0, "green": 1, "colorless": 1}, "power": 4, "toughness": 4, "abilities": ["Cannot be countered"]},
{"name": "Sun Titan", "mana_cost": {"white": 2, "blue": 0, "black": 0, "red": 0, "green": 0, "colorless": 4}, "power": 6, "toughness": 6, "abilities": ["Vigilance", "When it enters or attacks, return a permanent with mana cost 3 or less from your graveyard to the battlefield"]},
]
Example Output:#
If the best card to play is โGoblin Berserkerโ, the function returns:
"Goblin Berserker"
Tips#
All of the code you need to write is indicated by comments and
...
we have already tab intended the code at the correct level for you. We would advise not changing it.If you encounted a semantic error you might want to use the debugger to help you solve the problem
We provide one valid solution, however there are multiple ways to solve this problem. Our tests are not specific to our solution, however we would recommend following our guide.
# import card_list from cards.py
# cards.py contains a list of dictionaries representing Magic: The Gathering cards
# Use the syntax from module import name to import the card_list function
# Note: You do not need the .py extension when importing a module from a Python file
...
def find_best_card_to_play(available_mana, cards):
"""
Finds the best card to play based on available mana and card attributes using a nested loop structure,
adding unused mana from other colors to the colorless pool.
Args:
- available_mana (dict): Dictionary with available mana in each color.
- cards (list): List of dictionaries representing cards.
Returns:
- str: The name of the best card to play, or "No card can be played" if none are valid.
"""
# initialize variables to store the best card and its combined power and toughness
# Initialize the variable `best_card` to store the best card to play. Set it to None initially.
...
# Initialize the variable `max_combined_power` to store the maximum combined power and toughness of the best card.
# Set it to -1 initially.
...
# loops through each card in the list of cards
# recall that dictionaries are iterable, so you can iterate through the list of cards using a for loop directly.
...
# Check if the card's mana cost can be satisfied
# Create a variable `can_play` and set it to True initially. This variable will be used to check if the card can be played.
...
# Calculate the total unused mana based on the sum of the available mana pool
# Hint: You can use the sum() function to calculate the total unused mana by extracting the values from the available_mana dictionary. Use the values() method to get the values.
...
# iterate through each cards mana cost, checking if it can be satisfied
# To do this you should iterate through each key-value pair in the card's "mana_cost" dictionary. Do this by using the items() method on the dictionary.
...
# Check if the color is not colorless using an if statement
...
# Check if the cost is greater than the available mana for that color
# Use an if statement to check if the cost is greater than the available mana for that color. If it is, set `can_play` to False and break out of the loop.
# You should get the available mana for the specific color using the get() method on the available_mana dictionary, this way if there is no available mana for that color, it can default to 0.
...
# Subtract and assign the total_unused_mana, subtracting the color mana used
...
# Check if colorless mana can be satisfied with unused mana
# Write an if statement that checks that the card can be played (based on prior checks) and that the total unused mana is less than the colorless mana cost of the card.
# If this condition is met, set `can_play` to False, because there is not enough mana to play the card.
...
# If the card can be played, calculate the combined power and toughness by extracting the values from the card dictionary
# If statement to check if the card can be played
...
# Calculate combined power and toughness
...
# Check if the combined power of the current card is greater than the maximum combined power
# If it is, set the `best_card`` to the current card and update the `maximum_combined_power`
...
# else if the combined power is equal to the maximum combined power, prioritize cards with abilities
# Use an elif statement to check if the combined power is equal to the maximum combined power.
...
# Check if the current card has any abilities
# to do this, use a for loop to iterate through each ability in the card's "abilities" list.
...
# If the card has an ability, set it as the best card and break out of the loop.
# hint: you can use an if statement to check if the ability exists, and empty lists evaluate to False in Python. A non-empty list evaluates to True.
...
# Set the best card to the current card and break out of the loop
...
# if a best card is found, i.e. best_card is not None, return the name of the best card
...
# We have provided the return statement for you
return best_card["name"]
# Else return "No card can be played"
...
# We have provided the return statement for you
return "No card can be played"
# Example usage
available_mana = {"red": 3, "white": 2, "colorless": 0}
result = find_best_card_to_play(available_mana, card_list())
print(result) # Expected output: "Serra Angel"
grader.check("mtg-combo-solver")
Submitting Assignment#
Please run the following block of code using shift + enter
to submit your assignment, you should see your score.
from pykubegrader.submit.submit_assignment import submit_assignment
submit_assignment("week4-homework", "homework_4")