from die import Die class Yachtzee: """A command-line Yahtzee game. This version of Yahtzee is initialized with a list of goals. """ """This is the initial method in all classes. For this class, it sets the initial score to zero and then references the goals that the player will try to fullfill in the game. It also sets 5 die referring to the Die function. """ def __init__(self, goals): self.score = 0 self.goals = goals self.dice = [Die() for num in range(5)] """Welcomes the player to the game, then plays a round of the game as long as all the goals have not been met. Also prints the final score at the end of the game.""" def play(self): print("Welcome to Yachtzee!") while self.count_unused_goals() > 0: self.play_round() print(f"Your final score was {self.score}") """Plays a single round of the game. First prints a nice little line made of 80 equal signs, then indicates the number of rolls left, starting with 3. Rolls each dye and refers them to show_status method below. Once a user selects a goal in a round, this method also adds the goal score to the total score.""" def play_round(self): print("=" * 80) self.rolls_left = 3 for die in self.dice: die.roll() self.show_status() goal = self.choose_goal() goal.used = True self.score += goal.score(self.dice) """Takes the dye rolled in play_round and prints them out in a string list separated by a commma. Also prints the score and rolls remaining.""" def show_status(self): dice = ', '.join([str(die) for die in self.dice]) print(f"Score: {self.score}. Rolls left: {self.rolls_left}. Dice: {dice}.") """Provides a list of unused goals to choose from. Starts by creating an empty list called options and then puts any unused goals in that list by referring to the get_unused_goals method. Also provides an option to "Reroll" if all the rolls have not been used. If user rerolls, prints the status again and repeats the process until all the rerolls have been used or the user selects a goal option.""" def choose_goal(self): options = [] unused_goals = self.get_unused_goals() for goal in unused_goals: option = goal.prompt(self.dice) options.append(option) if self.rolls_left > 0: options.append("Re-roll") choice = self.get_choice(options) if options[choice] == "Re-roll": self.reroll() self.show_status() return self.choose_goal() else: return unused_goals[choice] """Starts by asking the user 'what you would like to do?' and then lists the options which include the unused goals and reroll as indicated in the method above. Once user inputs a choice, either returns the choice as an integer or prints an error message if the choice is not one of the available goals based on the printed number of the goal.""" def get_choice(self, options): print("What would you like to do?") for i, option in enumerate(options): print(f"{i}. {option}") choice = input("> ") while not self.option_choice_is_valid(choice, options): print("Sorry, that's not a valid choice.") choice = input("> ") return int(choice) """Checks if a choice for goal or reroll is valid by checking if the number the user enters is greater than 0, is an intger and is one of the available numbered options. Returns True if it is a valid option and False if it is not.""" def option_choice_is_valid(self, choice, options): if not choice.isdigit(): return False if int(choice) < 0: return False if int(choice) >= len(options): return False return True """Determines the length of the unused goals list (defined below) and returns the length of the list, so that this method can be called above (when the unused goals are zero, the game is over). """ def count_unused_goals(self): return len(self.get_unused_goals()) """Makes a list of unused_goals by checking if each goal was used and if not, puts the goal in the unused_goals list and returns the list.""" def get_unused_goals(self): unused_goals = [] for goal in self.goals: if not goal.used: unused_goals.append(goal) return unused_goals """Reduces the number of rolls by 1 every time the method is called. Then sets a list of choices to reroll by referring to the get_reroll_choices method. Also sets a list of dice_to_reroll by referring to the get_dice_to_reroll method. Rolls the die on the list of die to be rerolled.""" def reroll(self): self.rolls_left -= 1 choices = self.get_reroll_choices() dice_to_reroll = self.get_dice_to_reroll(choices) for die in dice_to_reroll: die.roll() """Creates an empty list of dice to re-roll and then for each dye that was rolled, checks if the user input was to reroll that die. If yes, then removes that die face and puts the die in a list called dice_to_reroll.""" def get_dice_to_reroll(self, choice_ints): dice_to_reroll = [] for die in self.dice: if die.face in choice_ints: choice_ints.remove(die.face) dice_to_reroll.append(die) return dice_to_reroll """Asks the user which dice they want to re-roll and then makes a list of choices based on the user input. If the user input does not match a valid reroll choice (refers to reroll_choices_are_valid method) then prints a clarifying statement about which dice to re-roll. This process repeats until valid choices are input. Once valid choices are input, stores those choices as a list called choice_ints, which is referred to in the method above.""" def get_reroll_choices(self): print("Which dice do you want to re-roll?") choices = input("> ") while not self.reroll_choices_are_valid(choices): print("Please enter the numbers on dice you want to re-roll.") choices = input("> ") choice_ints = [int(digit) for digit in choices] return choice_ints """Checks that the choices list the user inputs in the method above are actual dye faces. If the choices are not digits, returns false. If the choices are valid, turns the user input string into integers, and then for each choice removes the value of the die face. Once done returns the length of the choice_ints list to 0""" def reroll_choices_are_valid(self, choices_str): if not choices_str.isdigit(): return False choice_ints = [int(digit) for digit in choices_str] for die in self.dice: if die.face in choice_ints: choice_ints.remove(die.face) return len(choice_ints) == 0