Finished with checkpoint 2 adding docstrings

When I write code, Im focused on how to make something work and making sure everything runs correctly.
But when I write docstrings Im thinking about how to explain the purpose of the method and how it works
in a way another person could understand.
This commit is contained in:
tsmith37
2025-11-18 19:22:13 -05:00
parent 4ff8ebc6a3
commit c9f215b5d6

View File

@@ -10,6 +10,11 @@ class Yahtzee:
self.dice = [Die() for num in range(5)] self.dice = [Die() for num in range(5)]
def play(self): 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!") print("Welcome to Yachtzee!")
self.score = 0 self.score = 0
for goal in self.goals: for goal in self.goals:
@@ -19,6 +24,16 @@ class Yahtzee:
print(f"Your final score was {self.score}") print(f"Your final score was {self.score}")
def play_round(self): def play_round(self):
"""
Plays a single round of the game.
This method resets the number of rolls left, rolls all dice once,
and displays the current game status to the player. It then prompts
the player to choose a scoring goal for the round, marks that goal
as used, and updates the player's total score based on the dice
rolled. The method manages the full sequence of actions required
to complete one round from start to finish.
"""
print("=" * 80) print("=" * 80)
self.rolls_left = 3 self.rolls_left = 3
for die in self.dice: for die in self.dice:
@@ -28,11 +43,31 @@ class Yahtzee:
goal.used = True goal.used = True
self.score += goal.score(self.dice) self.score += goal.score(self.dice)
def show_status(self): def show_status(self):
"""
Displays the current game status to the player.
This method gathers the values of all dice, formats them into a
readable string, and prints the player's current score, the number
of rolls remaining, and the current state of the dice. It is used
to give the player a clear snapshot of their progress during a round.
"""
dice = ', '.join([str(die) for die in self.dice]) dice = ', '.join([str(die) for die in self.dice])
print(f"Score: {self.score}. Rolls left: {self.rolls_left}. Dice: {dice}.") print(f"Score: {self.score}. Rolls left: {self.rolls_left}. Dice: {dice}.")
def choose_goal(self): def choose_goal(self):
"""
Prompts the player to choose a scoring goal or re-roll.
This method gathers all unused scoring goals and displays them as
options for the player, along with a “Re-roll” option if rolls are
still available. It uses the player's choice to either trigger a
re-roll—after which it shows the updated status and recursively
prompts again—or to return the selected scoring goal. This method
manages the full decision-making process for selecting how the
current dice should be scored.
"""
options = [] options = []
unused_goals = self.get_unused_goals() unused_goals = self.get_unused_goals()
for goal in unused_goals: for goal in unused_goals:
@@ -48,7 +83,18 @@ class Yahtzee:
else: else:
return unused_goals[choice] return unused_goals[choice]
def get_choice(self, options): def get_choice(self, options):
"""
Gets a valid choice from the player based on a list of options.
This method prints a numbered list of available options and prompts
the player for an input. It repeatedly checks the player's response
using `option_choice_is_valid()` and continues asking until a valid
selection is entered. Once validated, the method returns the chosen
option as an integer index that can be used to access the selected
item in the options list.
"""
print("What would you like to do?") print("What would you like to do?")
for i, option in enumerate(options): for i, option in enumerate(options):
print(f"{i}. {option}") print(f"{i}. {option}")
@@ -59,6 +105,15 @@ class Yahtzee:
return int(choice) return int(choice)
def option_choice_is_valid(self, choice, options): def option_choice_is_valid(self, choice, options):
"""
Checks whether the player's menu choice is valid.
This method verifies that the player's input is a digit and then
converts it to an integer to ensure it falls within the valid range
of option indices. It returns False if the input is not numeric,
negative, or exceeds the number of available options. Otherwise,
it returns True, indicating that the choice can be safely used.
"""
if not choice.isdigit(): if not choice.isdigit():
return False return False
if int(choice) < 0: if int(choice) < 0:
@@ -68,23 +123,62 @@ class Yahtzee:
return True return True
def count_unused_goals(self): def count_unused_goals(self):
"""
Returns the number of scoring goals that have not been used yet.
This method calls `get_unused_goals()` to retrieve the list of all
goals that are still available for scoring and returns the length
of that list. It serves as a quick way to track how many scoring
options remain in the game.
"""
return len(self.get_unused_goals()) return len(self.get_unused_goals())
def get_unused_goals(self): def get_unused_goals(self):
"""
Returns a list of all scoring goals that have not been used yet.
This method iterates through the full collection of goals and checks
each ones `used` attribute. Any goal that has not been marked as used
is added to a new list, which is returned at the end. This provides the
game with an up-to-date list of scoring options still available to the
player.
"""
unused_goals = [] unused_goals = []
for goal in self.goals: for goal in self.goals:
if not goal.used: if not goal.used:
unused_goals.append(goal) unused_goals.append(goal)
return unused_goals return unused_goals
def reroll(self): def reroll(self):
"""
Performs a reroll of selected dice during the round.
This method decreases the number of rolls left, retrieves the list of
dice indices the player is allowed to reroll, and then determines which
dice the player actually wants to reroll by calling `get_dice_to_reroll()`.
It then loops through the chosen dice and rolls each one. This function
manages the full reroll process, updating both the game state and the dice.
"""
self.rolls_left -= 1 self.rolls_left -= 1
choices = self.get_reroll_choices() choices = self.get_reroll_choices()
dice_to_reroll = self.get_dice_to_reroll(choices) dice_to_reroll = self.get_dice_to_reroll(choices)
for die in dice_to_reroll: for die in dice_to_reroll:
die.roll() die.roll()
def get_dice_to_reroll(self, choice_ints): def get_dice_to_reroll(self, choice_ints):
"""
Determines which dice the player wants to reroll based on their choices.
This method receives a list of integers representing the dice faces the
player selected for rerolling. It iterates through all dice in the game,
checks whether each die's current face value appears in the list, and if
so, removes that value from the list and adds the die to the reroll list.
This ensures that each selected face value corresponds to one die only.
The method returns a list of dice objects that should be rerolled.
"""
dice_to_reroll = [] dice_to_reroll = []
for die in self.dice: for die in self.dice:
if die.face in choice_ints: if die.face in choice_ints:
@@ -92,7 +186,18 @@ class Yahtzee:
dice_to_reroll.append(die) dice_to_reroll.append(die)
return dice_to_reroll return dice_to_reroll
def get_reroll_choices(self): def get_reroll_choices(self):
"""
Prompts the player to choose which dice they want to reroll.
This method asks the player to enter the face values of the dice they
wish to reroll as a string of digits. It repeatedly validates the input
using `reroll_choices_are_valid()` and continues prompting until the
entered choices meet the required format. Once validated, the method
converts each character in the input string into an integer and returns
the resulting list of selected face values.
"""
print("Which dice do you want to re-roll?") print("Which dice do you want to re-roll?")
choices = input("> ") choices = input("> ")
while not self.reroll_choices_are_valid(choices): while not self.reroll_choices_are_valid(choices):
@@ -101,7 +206,20 @@ class Yahtzee:
choice_ints = [int(digit) for digit in choices] choice_ints = [int(digit) for digit in choices]
return choice_ints return choice_ints
def reroll_choices_are_valid(self, choices_str): def reroll_choices_are_valid(self, choices_str):
"""
Validates the player's input for selecting dice to reroll.
This method first checks that the player's input consists only of
digits. It then converts each digit into an integer representing a
desired die face. The method verifies these selections by matching
each requested face value to an existing die face in the current set
of dice. For every valid match, that face value is removed from the
list of choices. If, after processing all dice, no unmatched values
remain, the input is considered valid. Otherwise, the method returns
False to indicate an invalid selection.
"""
if not choices_str.isdigit(): if not choices_str.isdigit():
return False return False
choice_ints = [int(digit) for digit in choices_str] choice_ints = [int(digit) for digit in choices_str]