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)]
|
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 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 = []
|
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]
|
||||||
|
|||||||
Reference in New Issue
Block a user