Build a helper function name_to_number(name) that converts the string name into a number between 0 and 4 as described above. This function should use an if/elif/else with 5 cases. You can use conditions of the form name == 'paper', etc to distinguish the cases.
Next, you should build a second helper function number_to_name(num) that converts a number in the range 0 to 4 into its corresponding guess as a string.
Build the first part of the main function rpsls(guess) that converts guess into the number player_number between 0 and 4 using the helper function name_to_number.
Build the second part of rpsls(guess) that generates a random number comp_number between 0 and 4 using the function random.randrange(). I suggest experimenting with randrange in a separate CodeSkulptor window before deciding on how to call it to make sure that you do not accidently generate numbers in the wrong range.
Build the last part of rpsls(guess) that determines and prints out the winner. This test is actually very simple if you apply modular arithmetic (% in Python) to the difference between comp_number and player_number. If this is not immediately obvious to you, I would suggest reviewing our discussion of remainder / modular arithmetic and experimenting with the remainder operator % in a separate CodeSkulptor window to understand its behavior.
Using the helper function number_to_name, you should produce four print statements; print a blank line, print out the player's choice, print out the computer's choice and print out the winner.
This will be the only mini-project in the class that is not an interactive game. Since we have not yet learned enough to allow you to play the game interactively, you will simply call your rpsls function repeatedly in the program with different player choices. You will see that we have provided five such calls at the bottom of the template. Running your program repeatedly should generate different computer guesses and different winners each time. While you are testing, feel free to modify those calls, but make sure they are restored when you hand in your mini-project, as your peer assessors will expect them to be there.
The output of running your program should have the following form:
Player chooses rock\\
Computer chooses scissors\\
Player wins!\\
Player chooses Spock\\
Computer chooses lizard\\
Computer wins!\\
Player chooses paper\\
Computer chooses lizard\\
Computer wins!\\
Player chooses lizard\\
Computer chooses scissors\\
Computer wins!\\
Player chooses scissors\\
Computer chooses Spock\\
Computer wins!\\
Tip #1 - Getting started on step one
The program template implements the Card class for you. Before you proceed, take a look at the program below that creates a couple of cards and prints out some information associated with the newly created cards. The class definition includes an initialization method init that is called whenever we create a card via Card(..., ...), several methods for accessing the fields of a Card object and a method str() that is called when we want to print out information about a Card object.
-
Note that we created each card with the initializer Card(). The methods get_rank() and get_suit() extract the two fields in the Card object. The str() method takes a Card object and returns a string that encodes the information in the object and can be displayed in the console via print.
As you implement the Hand class and the Deck classes, you should go through the same testing process for the various methods associated with these classes. Don't rush on to implement the next step without testing first. Note that you don't need to use the canvas to test these methods since we have the str() method available to print out the information about class objects to the console.
Tip #2 - Implementing the basic Hand class
Step one asks you to implement the methods init(), str(), and add_card(...) for the Hand class. Logically, we will think of a hand as a collection cards which we will model in Python as a list of cards. So, to implement the basics of a Hand class, we will need a field in the Hand class to keep track of the list of cards. For the sake of simplicity, let's call that field cards.
The init() method should create an empty hand by assigning an empty list to the cards field. Implementing this method should be one line of code.
The add_card(card) method should take a Card object and append it to the list in the cards field. Implementing this method should be one line of code.
The str() method should compute a list whose entries are the string representations for each card (remember you have a string method for Cards). You should then return the string representation of that list. (For example, if the list is called ans, you should return str(ans).) Implementing this method may take a couple of lines depending on how you decide to implement it.
Before we proceed to step two, let's test your implementation to see if it is correct. Cut and paste your implementation of the Hand class into the following program. Then run the program and see if the output matches that specified in the comments.
-
Tip #3 - Implementing the Deck class
Step two asks you to implement methods for the Deck class. Just as in the case of the Hand class, we suggest modeling a deck as a list of cards and keep track of that list using a single field in the Deck class. The method deal_card() can be implemented in a single line using a common list operation. The shuffle() method can be implemented using random.shuffle(...). I also suggest implementing the str() method to aid in debugging. (This method is identical to the str() method for hands.)
The trickiest method is init() which should return a deck containing all 52 cards. To implement init() for the Deck class, we suggest that you use a pair of nested for-loops or a list comprehension with two for clauses. While building these loops, the first question that you should ask is: “What should these loops be iterating over?”. For a deck of cards, the loops should be iterating over the entries in SUITS and RANKS. One possible list comprehensions would be something like:
[ ..... for suit in SUITS for rank in RANKS]
where the ... expression depends on suit and rank and should return a card object. As in the first step, lets test our implementation of the Deck class before we proceed. Substitute your implementation of the Deck class into this program and check whether the printed results agree with the comments.
-
UPDATE: The elements in your card list should always be card objects i.e; Card(suit, rank), not strings. This is a very common mistake.
Tip #4 - Hitting a hand using the Hand and Deck methods
In step three, you are asked to use the add_card method for the Hand class and the deal_card method for the Deck class to “hit” a Blackjack hand. Given a deck called my_deck and a hand called my_hand, we can transfer a card from my_deck to my_hand via
my_hand.add_card(my_deck.deal_card())
Note that this fairly abstract operation is expressed in a single line of code that reflects the logical structure of “hitting” a Blackjack hand. The Hand class and the Deck class provide us with a layer of abstraction that allows to manipulate hands and deck at a level closer to the true logic of Blackjack. As a final test of your implementations of the Hand and Deck classes, cut and paste your implementation of the Hand and Deck classes into the code below and check whether the output matches the comments.
-
Tip #5 - Implementing the draw method for a hand
Part of the usefulness of object-oriented programming is that we can use a method from one class to implement a method from another class. In the case of the draw method for a hand, we can use the draw method for card object.
The parameter pos will determine where the hand is drawn on the canvas. Note that for this method to work, c must be a card object (not a string or tuple). You need to fill in the remaining code (1 line) to position the individual cards in some reasonable pattern based on pos.
The draw method for a hand would look something like
def draw(self, canvas, pos)
for c in self.cards:
c.draw(canvas, ...)
....
en/python06.html.txt · Last modified: 2025/01/22 05:19 (external edit) · []