This is a simplified version of a common card game, "21". Blackjack is a better-known variant.
In this game, the dealer deals two "cards" to each player in the very first round, one hidden, so that only
the player who gets it knows what it is, and one face up, so that everyone can see it. In the following
rounds, subsequent cards are added to the visible cards in hand for both players, one card per round,
until the user passes. That is to say, each user will get only one hidden hard, which is assigned to them in
the first round. (Actually, what the other players see is the total of each other player's visible cards, not
the individual cards. Users can know all their own cards and the sum of them.)
There are two players: one human player (the person playing the game) and one computer player. To
play, the players take turns requesting cards, trying to get as close to 21 as possible, but not going over
21. A player may pass (ask for no more cards). Once a player has passed, he or she cannot later ask for
another card. When all players have passed, the game ends.
The winner is the player who has come closest to 21 without exceeding it. In the case of a tie, or if
everyone goes over 21, no one wins.
The game is only played once (so it's actually just one "hand").
The "cards" are the numbers 1 through 10 and they are randomly generated, not drawn from a deck of
limited size. The odds of returning a 10 are four times as likely as any other value (because in an actual
deck of cards, 10, Jack, Queen, and King all count as 10).
Provided program implementation:
We have provided a simple21.py skeleton file which includes:
def main():
● Prints the game instructions by calling print_instructions()
● Gets and sets the user's name dynamically based on user input
● Sets the computer's name to “Computer”
● While the game is running
○ Runs the game by calling run()
○ Asks the user if he/she wants to play the game again by calling ask_yes_or_no("Play
again? (y/n) ")
■ If yes:
● Asks the user if they want to modify their username by calling
ask_yes_or_no("Modify username? (y/n) ")
● Runs the game again by calling run()
■ If no:
● Exits the program
def print_instructions():
● Prints out instructions for the game.
def ask_yes_or_no(prompt):
● Displays the given prompt and asks the user for input. If the user's input starts with 'y', returns
True. If the user's input starts with 'n', returns False.
● For example, calling ask_yes_or_no("Do you want to play again? (y/n)") would display "Do you
want to play again? (y/n)", wait for user input that starts with 'y' or 'n', and return True or False
accordingly.
● Other requirements:
○ If the user types in “y” or “yyyy”, the function returns True anyway.
○ "Yes" or "No" are case-insensitive. That’s to say, “YES” and “Yes” are equal. They’ll both
return True.
○ The function needs to trim leading and trailing whitespace (including “\t”, “\n”) of the
user input. The word “ Yes ” with whitespace will be considered the same as “Yes”.
○ If the user’s input is invalid, prompt the question again until a valid input.
def next_card():
● Returns a random "card", represented by an int between 1 and 10, inclusive.
● The "cards" are the numbers 1 through 10 and they are randomly generated, not drawn from a
deck of limited size. The odds of returning a 10 are four times as likely as any other value
(because in an actual deck of cards, 10, Jack, Queen, and King all count as 10).
● Hint: Think about how to write code that will generate a random number from 1 - 13, but will
only return a number from 1 - 10 from this function.
def take_another_card(computer_total_points, user_visible_card):
● Strategy for computer to take another card or not.
● According to the computer’s own given total points (sum of visible cards + hidden card) and the
user's sum of visible cards, you need to design a game strategy for the computer to win the
game.
● Returns True if the strategy decides to take another card, False if the computer decides not to
take another card.
● Notice that, if the computer decides not to take a card, he will not be able to take the card in the
following rounds until the game is restarted. (Same as the user, if the user decides not to take
cards, he will be marked as passed and will not take cards until the game is restarted.)
def is_game_over(is_user_passed, is_computer_passed):
● Determines if the game is over or not. If the given is_user_passed is set to True, the user has
passed. If the given is_computer_passed is set to True, the computer has passed.
● This function returns True if both the user and the computer have passed, and False if either of
them has not yet passed.
def print_status(is_user, name, hidden_card, visible_card, total_points):
● In each turn, prints out the current status of the game.
● If is_user is set to True, the given player is the user. In this case, print out the user's given name,
his/her hidden card points, visible card points, and total points.
● If is_user is set to False, the given player is the computer. In this case, print out the computer's
given name, and his/her visible card points.
● For example, calling print_status(True, "Brandon", 4, 15, 19) would print:
Brandon has 4 hidden point(s).
Brandon has 15 visible point(s).
Brandon has 19 total point(s).
● As another example, calling print_status(False, "Computer", 1, 19, 20) would print:
Computer has 19 visible point(s).
def print_winner(username, user_total_points, computer_name, computer_total_points):
● Determines who won the game and prints the game results in the following format:
○ User's given name and the given user's total points
○ Computer's given name and the given computer's total points
○ The player who won the game and the total number of points he/she won by, or if it's a
tie, nobody won.
def run(username, computer_name):
● This function controls the overall game and logic for the given user and computer.
● Gives each player, in turn, a chance to take a card, until both the user and computer have
passed. Prints a message when a player passes. Once a player has passed, that player is not
given another chance to take a card
● First, assign the user two random cards, one hidden, and one visible. Print the user’s status.
● Then, assign the computer two random cards, one hidden, and one visible. Print its status.
● While the game is not over, ask the user/computer if they want to take random cards until both
of them pass.
● If both of them passed, print the winner, and the run() function will return.
● Notice that, once a player has passed, that player is not given another chance to take a card.
And the user can choose to ask for more cards even though they have more than 21 points.