Hello, if you have any need, please feel free to consult us, this is my wechat: wx91due
1. Upgraded Cheese Shop (2 marks)
This question requires contents from Week 6.
Write your solutions into shop.py .
You must only run your code in shop.py if the expression if __name__ == '__main__' is True .
Failure to do so will cause your program to not pass any of the test cases.
The Cheese Shop now carries two additional type of cheese: Marble and Swiss . Each costs 50 and 100 gold respectively.
1.1 Update Cheese Menu
Modify the shop.py from Assignment 1 to include these new cheese and their prices when players visit The Cheese Shop. The program should now display:
Welcome to The Cheese Shop!
Cheddar - 10 gold
Marble - 50 gold
Swiss - 100 gold
How can I help ye?
1. Buy cheese
2. View inventory
3. Leave shop
In the code scaffold, you are given each type of cheese and its price in the variable CHEESE_MENU . You must not change or modify this variable.
1.2. Upgrade Buying Process
Update the function buy_cheese to repeatedly allow users to continue making purchases unless they enter the command back . The function receives one parameter, an int to represent the current gold the player has.
The function returns a tuple with 2 elements. The first element is an int of the amount of gold spent. The second element is a tuple with the amount of each type of cheese bought in the same order as that given in the CHEESE_MENU in the code scaffold. As an example, if the user has 75 gold and buys 2 cheddar and 1 marble, the return value would be (70, (2, 1, 0)) .
def buy_cheese(gold: int) -> tuple:
'''
Feature for players to buy cheese from shop
Parameters:
gold: int, amount of gold that player has
Returns:
gold_spent: int, amount of gold spent
cheese_bought: tuple, amount of each type of cheese bought
'''
pass
If the player enters a cheese that is not sold by the shop, the program displays We don't sell {player_request} ! where {player_request} is replaced with the player's requested cheese in lowercase and the program prompts for another cheese and quantity input from the user. Otherwise, it will continue to check the following:
Missing quantity. : If users does not enter a quantity.
Invalid quantity. : If users enters an invalid number as the quantity e.g. one , wahid .
Must purchase positive amount of cheese. : If users enters 0 or a negative number as the quantity.
There should only ever be one error message per input if the input is invalid, and the error messages are in order of how they have been listed. So as example, an input such as info1110 would display We don't sell info1110! but not also display Missing quantity. . Another example, if the user enters both an invalid cheese and quantity e.g. brie one , the former takes priority i.e. it will display the error message We don't sell brie! and continue asking for input.
There is now a change to the shop. When buying cheese, regardless of whether it is a valid or invalid command, players are prompted to buy more cheese. The only way to return back to main menu of The Cheese Shop is if they enter the back command.
All commands when buying cheese are case insensitive, so as examples, back and BACK are both valid commands that will move the players back to the shop menu. cheddar 10 and CHEDdaR 10 will buy 10 cheddar, assuming the player has sufficient gold. For this question, you may assume that all cheeses in the Cheese Shop is a single word.
This is an example input/outputs produced by the updated game:
Welcome to The Cheese Shop!
Cheddar - 10 gold
Marble - 50 gold
Swiss - 100 gold
How can I help ye?
1. Buy cheese
2. View inventory
3. Leave shop
#1
You have 125 gold to spend.
State [cheese quantity]: #brie
We don't sell brie!
You have 125 gold to spend.
State [cheese quantity]: #marble
Missing quantity.
You have 125 gold to spend.
State [cheese quantity]: #marble 10
Insufficient gold.
You have 125 gold to spend.
State [cheese quantity]: #marble 1
Successfully purchase 1 marble.
You have 75 gold to spend.
State [cheese quantity]: #back
How can I help ye?
1. Buy cheese
2. View inventory
3. Leave shop
From the example above, the buy_cheese function is responsible for showing this output:
You have 125 gold to spend.
State [cheese quantity]: #brie
We don't sell brie!
You have 125 gold to spend.
State [cheese quantity]: #marble
Missing quantity.
You have 125 gold to spend.
State [cheese quantity]: #marble 10
Insufficient gold.
You have 125 gold to spend.
State [cheese quantity]: #swiss 1
Successfully purchase 1 swiss.
You have 25 gold to spend.
State [cheese quantity]: #cheddar 2
Successfully purchase 2 cheddar.
You have 5 gold to spend.
State [cheese quantity]: #back
The function would return (120, (2, 0, 1)) as the player spent 120 gold, and bought 2 cheddar and 1 swiss.
You may be asking "Why are we using tuples and not lists for the return value?"
Tuples are immutable, meaning once it's instantiated it cannot be changed. The idea behind it is that if a function returns you a tuple, it's a definite answer and cannot be changed at any point in the program. If there were to be any accidental changes on this return value, whether it be from the user or even the function itself, it would raise an error. This guarantees the user is using the intended values returned from the function.
In simple words, it's good design.
In the template, you've been provided two things. First, you have a cheese menu:
CHEESE_MENU = (("Cheddar", 10), ("Marble", 50), ("Swiss", 100))
This is the menu for the shop. Each inner tuple contains both the name of the cheese and its price. This specific structure ensures the cheese menu does not change.
Secondly, you've been provided your own cheese:
cheese = [["Cheddar", 0], ["Marble", 0], ["Swiss", 0]]
These are the initial quantities of each cheese, as the player starts with 0 of each. This specific structure allows you to freely change the quantities for each cheese when you wish.
You do not have to use either of these in your solution, however it would likely make your program easier to read if you were to use containers.
1.3. Update Inventory View
The inventory must be updated to show the quantity of each type of cheese. If a player doesn't have any of that particular cheese, it must show 0 . The gold and quantity of each type of cheese can never be negative numbers.
Update the function display_inventory to receive three parameters of type int , list , and str , being the gold, cheese and trap respectively.
def display_inventory(gold: int, cheese: list, trap: str) -> None:
'''
Displays contents of inventory
Parameters:
gold: int, amount of gold that player has
cheese: list, amount of each type of cheese that player has
trap: str, name of trap that player that player has
'''
pass
At the start of the game, players will have 125 gold and no cheese. This is an example of the input/output produced by the program of the view of the inventory before and after buying 1 marble and 1 cheddar from the shop.
Welcome to The Cheese Shop!
Cheddar - 10 gold
Marble - 50 gold
Swiss - 100 gold
How can I help ye?
1. Buy cheese
2. View inventory
3. Leave shop
2
Gold - 125
Cheddar - 0
Marble - 0
Swiss - 0
Trap - Cardboard and Hook TrapHow can I help ye?
1. Buy cheese
2. View inventory
3. Leave shop
#1
You have 125 gold to spend.
State [cheese quantity]: #marble 1
Successfully purchase 1 marble.
You have 75 gold to spend.
State [cheese quantity]: #cheddar 1
Successfully purchase 1 cheddar.
You have 65 gold to spend.
State [cheese quantity]: #back
How can I help ye?
1. Buy cheese
2. View inventory
3. Leave shop
#2
Gold - 65
Cheddar - 1
Marble - 1
Swiss - 0
Trap - Cardboard and Hook Trap
How can I help ye?
1. Buy cheese
2. View inventory
3. Leave shop
#3
From the example above, the display_inventory function would be responsible for showing this output:
Gold - 125
Cheddar - 0
Marble - 0
Swiss - 0
Trap - Cardboard and Hook Trap
This function would then be called again later in the program to display the next output:
Gold - 65
Cheddar - 1
Marble - 1
Swiss - 0
Trap - Cardboard and Hook Trap2. New Game Features (2 marks)
This question requires contents from Week 7.
Write your solutions into train.py and game.py . Read the question carefully to identify the correct location to place your solution!
You must only run your code in game.py if the expression if __name__ == '__main__' is True .
You must only run your code in train.py if the expression if __name__ == '__main__' is True . All your code that executes must be inside a main function.
Failure to do so will cause your program to not pass any of the test cases.
Write Python codes to build the following features on top of the original Mousehunt game from Assignment 1.
2.1 Skip Feature
The developers received feedback that the training module is annoying to type skip every time and have requested for a quicker way to skip. You are asked to modify the current program to additionally enable players to skip training by entering ESC+Enter at any time. Even if they repeat the training, they can still enter ESC+Enter .
Modify train.py to check whether the user has entered ESC+Enter during each user prompt. This user prompt is not inclusive of the "skip" prompt given at the very start.
Additionally, all commands in this game feature are case insensitive and ignore trailing and leading whitespaces in the command. Ensure you update game.py such that these changes are reflected.
Hint: All symbols have an equivalent numeric value. Try an Internet search on the ASCII table to see what its value is, and see how it will help you!
When users enter ESC , it will appear as ^[ in the terminal.
Ideally, if you've imported the code from train.py into game.py , you wouldn't need to change a single line in game.py for this game feature. It's only required if you're duplicating code.
These are example input/outputs in which players can skip training for different scenarios during training. Note that players can't enter ^[ when prompted to skip and it will not be tested. The first snippet below is when they can begin entering ^[ .
Skip training when prompted to travel to the Meadow.
Larry: I'm Larry. I'll be your hunting instructor.
Larry: Let's go to the Meadow to begin your training!
Press Enter to travel to the Meadow...#^[
Skip training when prompted to view traps.
Larry: I'm Larry. I'll be your hunting instructor.
Larry: Let's go to the Meadow to begin your training!
Press Enter to travel to the Meadow...
Travelling to the Meadow...
Larry: This is your camp. Here you'll set up your mouse trap.
Larry: Let's get your first trap...
Press Enter to view traps that Larry is holding...#^[
Skip training when prompted to select traps
Larry: I'm Larry. I'll be your hunting instructor.
Larry: Let's go to the Meadow to begin your training!
Press Enter to travel to the Meadow...
Travelling to the Meadow...
Larry: This is your camp. Here you'll set up your mouse trap.
Larry: Let's get your first trap...
Press Enter to view traps that Larry is holding...
Larry is holding...
Left: High Strain Steel Trap
Right: Hot Tub Trap
Select a trap by typing "left" or "right": #^[
Skip training when prompted to sound horn.
Larry: I'm Larry. I'll be your hunting instructor.
Larry: Let's go to the Meadow to begin your training!
Press Enter to travel to the Meadow...#
Travelling to the Meadow...
Larry: This is your camp. Here you'll set up your mouse trap.
Larry: Let's get your first trap...
Press Enter to view traps that Larry is holding...#
Larry is holding...
Left: High Strain Steel Trap
Right: Hot Tub Trap
Select a trap by typing "left" or "right": #
Invalid command! No trap selected.
Larry: Odds are slim with no trap!
Sound the horn to call for the mouse...
Sound the horn by typing "yes": #^[
Skip training when prompted to continue training.
Larry: I'm Larry. I'll be your hunting instructor.
Larry: Let's go to the Meadow to begin your training!Press Enter to travel to the Meadow...#
Travelling to the Meadow...
Larry: This is your camp. Here you'll set up your mouse trap.
Larry: Let's get your first trap...
Press Enter to view traps that Larry is holding...#
Larry is holding...
Left: High Strain Steel Trap
Right: Hot Tub Trap
Select a trap by typing "left" or "right": #
Invalid command! No trap selected.
Larry: Odds are slim with no trap!
Sound the horn to call for the mouse...
Sound the horn by typing "yes": #yes
Nothing happens.
To catch a mouse, you need both trap and cheese!
Press Enter to continue training and "no" to stop training: #^[
The train.py file must have a main function that only executes if the __name__ value is '__main__' .
def main():
'''
Implement your code here.
'''
pass
if __name__ == '__main__':
main()
2.2 How do I arm my trap with new cheese?
Add another option to the main menu called 4. Change Cheese . When players select this option, the game displays the current quantity of cheese that are in the player's inventory and then prompts the user to provide the type of cheese that they intend to arm their trap with.
If the player enters the command back , the game returns to the main menu. The game must be able to recognize any of the cheese that the Cheese Shop stocks, i.e. cheddar , marble and swiss . If an invalid cheese is provided or players attempt to arm a cheese that don't possess, the game displays an appropriate warning message (see table 1), displays the player's inventory again and re-prompts for another cheese.
Table 1: Troubleshooting errors when arming cheese
All commands in this game feature is case insensitive and ignores trailing and leading whitespaces in the command. In short, CHEDDAR and cheddar are valid commands for cheddar cheese.
All the functionality for the Change Cheese section should be completed in the function change_cheese . You should call this function when the user wants to change cheese, and the function should end once they have either successfully armed the trap or have exited out of changing cheese. The function should return a tuple with the first element being a bool object representing the trap status, and the second element being a str object representing the type of cheese in the trap. If players exit the function without arming the trap successfully, there should be no cheese in the trap. This is represented by returning the None object.
def change_cheese(hunter_name: str, trap: str, cheese: list, e_flag: bool = False) -> tuple:
'''
Handles the inputs and ouputs of the change cheese feature.
Parameters:
hunter_name: str, the name of the player.
trap: str, the trap name.
cheese: list, all the cheese and its quantities the player
currently possesses.
e_flag: bool, if the trap is enchanted, this will be True.
default value is False.
Returns:
trap_status: bool, True if armed and False otherwise.
trap_cheese: str | None, the type of cheese in the trap. if player
exits the function without without arming
trap succesfully, this value is None.
'''
pass
This is an example input/output of the game when player Bob enter this game feature from the main menu without any cheese in their inventory and attempts to arm brie and cheddar . These output snippets start from the game menu. We skip the game title, name input, and training for your convenience.
What do ye want to do now, Hunter Bob?
1. Exit game
2. Join the Hunt
3. The Cheese Shop
4. Change Cheese
#4
Hunter Bob, you currently have:
Cheddar - 0
Marble - 0
Swiss - 0
Type cheese name to arm trap: #brie
No such cheese!
Hunter Bob, you currently have:
Cheddar - 0
Marble - 0
Swiss - 0
Type cheese name to arm trap: #cheddar
Out of cheese!
Hunter Bob, you currently have:
Cheddar - 0
Marble - 0
Swiss - 0
Type cheese name to arm trap: #back
What do ye want to do now, Hunter Bob?
1. Exit game
2. Join the Hunt
3. The Cheese Shop
4. Change Cheese
#1
If players provide a valid cheese that they have present in their inventory, the game proceeds to confirm whether the player intends to arm the trap with the selected cheese by displaying the message Do you want to arm the trap with {cheese_type}? where {cheese_type} is the cheese that the player has selected. Even if the player already has the same cheese type armed, it will still prompt them if want to arm it.
If players enter back , the game returns to main menu. If players enter no , the game does nothing, displays the player's inventory again and re-prompts for another cheese. If players enter yes , the game confirms that their existing trap is armed with the given cheese and returns to the main menu. The following is an example input/output for player Bob attempting to arm their Cardboard and Hook Trap trap with Cheddar and only successfully doing arming their trap during the second attempt.
In this example, we will go through what the function should be outputting and what it should be returning. Keep in mind, we skip a few steps. Assume this is a point of the game when the user has 6 cheddar and 1 marble. If we started from scratch, we would need to catch a few mouses before we can get to this point.
What do ye want to do now, Hunter Bob?
1. Exit game
2. Join the Hunt
3. The Cheese Shop
4. Change Cheese
#4
Hunter Bob, you currently have:
Cheddar - 6
Marble - 1
Swiss - 0
Type cheese name to arm trap: #CHEDDAR
Do you want to arm your trap with Cheddar? #NO
Hunter Bob, you currently have:
Cheddar - 6
Marble - 1
Swiss - 0
Type cheese name to arm trap: #MARBLE
Do you want to arm your trap with Marble? #YES
Cardboard and Hook Trap is now armed with Marble!
What do ye want to do now, Hunter Bob?
1. Exit game
2. Join the Hunt
3. The Cheese Shop
4. Change Cheese
#4
Hunter Bob, you currently have:
Cheddar - 6
Marble - 1
Swiss - 0
Type cheese name to arm trap: #BACK
What do ye want to do now, Hunter Bob?
1. Exit game
2. Join the Hunt
3. The Cheese Shop
4. Change Cheese
#1
From the example above, the change_cheese function is responsible for showing this output:
Hunter Bob, you currently have:
Cheddar - 6
Marble - 1
Swiss - 0
Type cheese name to arm trap: #CHEDDAR
Do you want to arm your trap with Cheddar? #NO
Hunter Bob, you currently have:
Cheddar - 6
Marble - 1
Swiss - 0
Type cheese name to arm trap: #MARBLE
Do you want to arm your trap with Marble? #YES
Cardboard and Hook Trap is now armed with Marble!
The function would return (True, 'Marble') as the trap is armed and the cheese armed is marble .
This function would then be called again later in the program to display the next output:
Hunter Bob, you currently have:
Cheddar - 6
Marble - 1
Swiss - 0
Type cheese name to arm trap: #BACK
The function would return (False, None) as the trap is not armed and there's no cheese armed. Please note that we are using the None object which is a separate data type to represents absence of values. It is not a string with the value 'None' .
None # correct
'None' # incorrect
You do not have to arm the trap after every single hunt.
Example: If you have 10 cheddar, arming the trap with cheddar will allow you to hunt 10 times (assuming valid inputs) until you can no longer hunt.
Since you must now arm the trap, it means you cannot immediately hunt after you buy cheese. You must first arm the trap.