generated from mwc/lab_dice
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:
118
yahtzee.py
118
yahtzee.py
@@ -10,6 +10,11 @@ class Yahtzee:
|
||||
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!")
|
||||
self.score = 0
|
||||
for goal in self.goals:
|
||||
@@ -19,6 +24,16 @@ class Yahtzee:
|
||||
print(f"Your final score was {self.score}")
|
||||
|
||||
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)
|
||||
self.rolls_left = 3
|
||||
for die in self.dice:
|
||||
@@ -28,11 +43,31 @@ class Yahtzee:
|
||||
goal.used = True
|
||||
self.score += goal.score(self.dice)
|
||||
|
||||
|
||||
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])
|
||||
print(f"Score: {self.score}. Rolls left: {self.rolls_left}. Dice: {dice}.")
|
||||
|
||||
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 = []
|
||||
unused_goals = self.get_unused_goals()
|
||||
for goal in unused_goals:
|
||||
@@ -48,7 +83,18 @@ class Yahtzee:
|
||||
else:
|
||||
return unused_goals[choice]
|
||||
|
||||
|
||||
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?")
|
||||
for i, option in enumerate(options):
|
||||
print(f"{i}. {option}")
|
||||
@@ -59,6 +105,15 @@ class Yahtzee:
|
||||
return int(choice)
|
||||
|
||||
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():
|
||||
return False
|
||||
if int(choice) < 0:
|
||||
@@ -68,23 +123,62 @@ class Yahtzee:
|
||||
return True
|
||||
|
||||
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())
|
||||
|
||||
|
||||
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 one’s `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 = []
|
||||
for goal in self.goals:
|
||||
if not goal.used:
|
||||
unused_goals.append(goal)
|
||||
return unused_goals
|
||||
|
||||
|
||||
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
|
||||
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):
|
||||
"""
|
||||
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 = []
|
||||
for die in self.dice:
|
||||
if die.face in choice_ints:
|
||||
@@ -92,7 +186,18 @@ class Yahtzee:
|
||||
dice_to_reroll.append(die)
|
||||
return dice_to_reroll
|
||||
|
||||
|
||||
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?")
|
||||
choices = input("> ")
|
||||
while not self.reroll_choices_are_valid(choices):
|
||||
@@ -101,7 +206,20 @@ class Yahtzee:
|
||||
choice_ints = [int(digit) for digit in choices]
|
||||
return choice_ints
|
||||
|
||||
|
||||
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():
|
||||
return False
|
||||
choice_ints = [int(digit) for digit in choices_str]
|
||||
|
||||
Reference in New Issue
Block a user