from die import Die class Yachtzee: """A command-line Yahtzee game. This version of Yahtzee is initialized with a list of goals. """ def __init__(self, goals): self.score = 0 self.goals = goals self.dice = [Die() for num in range(5)] def play(self): """Play an entire game. Starts by greeting the user, then plays rounds until all the goals have been used. When the game is over, tells the player their final score. """ print("Welcome to Yachtzee!") while self.count_unused_goals() > 0: self.play_round() print(f"Your final score was {self.score}") def play_round(self): """Play a round of the game. This will reset the rolls, rolls the dice shows the status of the game. Then it allows the player to choose a goal and will then update the score. """ 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) def show_status(self): """Shows the score, rolls left, and faces of the dice. This prints the information for the player. """ dice = ', '.join([str(die) for die in self.dice]) print(f"Score: {self.score}. Rolls left: {self.rolls_left}. Dice: {dice}.") def choose_goal(self): """Let's the player choose a goal or to re roll the dice. It creates a list of options for the player based on previous choices. The player can choose an option.""" 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] def get_choice(self, options): """Has the player choose a choice from the options given. Displays a list of options, and either accepts the option or if it is not a valid option tells the player they cannot choose that. """ 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) def option_choice_is_valid(self, choice, options): """Checks to see if the player's choice is valid. The choice has to be a number in the list of options otherwise it will send the payler the error message.""" if not choice.isdigit(): return False if int(choice) < 0: return False if int(choice) >= len(options): return False return True def count_unused_goals(self): """Counts how many goals are left to be scored. It will return however many unused goals are left. """ return len(self.get_unused_goals()) def get_unused_goals(self): """Gives a list of goals that haven't been scored yet. This will show the player what goals are left and then they can decide how to proceed in tha game. """ unused_goals = [] for goal in self.goals: if not goal.used: unused_goals.append(goal) return unused_goals def reroll(self): """Lets the player re-roll the dice if they choose to. The player can choose which dice to re-roll if they decide to do that in the game. It then reduces the amount of rolls that are left. """ 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() def get_dice_to_reroll(self, choice_ints): """The player can choose which dice to re-roll. The player can pick which dice to re-roll and then the game will change the number for those dice. """ 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 def get_reroll_choices(self): """Asks the player which dice to re-roll. It will ask the player which dice to re-roll if that is the choice they choose. If they enter an invalid option the game sends a clarifying question to make sure the input is valid. """ 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 def reroll_choices_are_valid(self, choices_str): """Checks to see if re-roll choice is valid. Makes sure what the player says matches what is valid in the game. If not valid, it will ask the clarifying question. """ 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