Files
lab_dice/yahtzee.py
angelotr d4f0f50c60 What I did for checkpoint 2 was I added docstrings descibing what each function does in yahtzee.py
For checkpoint 2, I have always found it easier to read and describe code rather than actually writing out the code. When writing out the code
I think to myself what the process is doing and how it is doing it. This normally takes the longest for me because it is easier to read what the code
does rather than write code for the procedure. When writing docstring for my code I always pretend to run a simulation in my mind and picture
what is happening which helps me read and understand the code. In future projects I will include writing docstrings because it helps me keep
track of what certain codes do and why it does what it does.
2025-11-11 22:43:53 -05:00

150 lines
5.4 KiB
Python

from die import Die
class Yahtzee:
"""A command-line Yahtzee game.
This version of Yahtzee is initialized with a list of goals.
"""
def __init__(self, goals):
"""Initialize a new game of Yahtzee.
Creates a score of zero, stores the list of goals, and sets up five dice.
"""
self.score = 0
self.goals = goals
self.dice = [Die() for num in range(5)]
def play(self):
"""Play an entire game.
Greets the player, resets the score and goals, and continues playing rounds
until all goals have been used. Prints the final score at the end.
"""
print("Welcome to Yachtzee!")
self.score = 0
for goal in self.goals:
goal.used = False
while self.count_unused_goals() > 0:
self.play_round()
print(f"Your final score was {self.score}")
def play_round(self):
"""Play a single round of Yahtzee.
Rolls all dice, lets the player choose a goal or re-roll, and updates 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):
"""Display the current game status.
Shows the current score, number of rolls left, and the faces of all dice.
"""
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):
"""Prompt the player to choose a goal or re-roll.
Builds a list of unused goals, displays them, and processes the player's choice.
If the player chooses to re-roll, performs a re-roll and re-prompts for a goal.
"""
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):
"""Display available options and get the player's choice.
Validates user input and returns the chosen option as an integer index.
"""
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):
"""Check whether the player's input is a valid choice.
Ensures the input is a number and within the range of available options.
"""
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):
"""Return the number of unused goals left in the game."""
return len(self.get_unused_goals())
def get_unused_goals(self):
"""Return a list of goals that have not yet been used."""
unused_goals = []
for goal in self.goals:
if not goal.used:
unused_goals.append(goal)
return unused_goals
def reroll(self):
"""Re-roll selected dice.
Decreases the number of rolls left, asks the player which dice to re-roll,
and rolls the chosen dice again.
"""
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):
"""Identify which dice to re-roll based on the player's choices.
Matches chosen face values with current dice faces and returns a list of dice to roll again.
"""
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):
"""Ask the player which dice to re-roll.
Prompts for input, validates the choices, and returns them as a list of integers.
"""
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):
"""Validate the player's re-roll choices.
Checks that all characters are digits and correspond to actual dice values.
"""
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