def test_clear_shelf_and_keep_bank(): test_banker = Banker() test_banker.shelf(1000) test_banker.bank() test_banker.clear_shelf() assert test_banker.shelf_points == 0 assert test_banker.bank_points == 1000
def test_clear_shelf(): banker = Banker() banker.shelf(100) banker.bank() banker.shelf(50) banker.clear_shelf() assert banker.balance == 100 assert banker.shelved == 0
class Game: def __init__(self, dice_values=None): self.remaining_dice = 6 self.current_round = 1 self.dice_values = dice_values self.banker = Banker() def welcome(self): gameon = False while not gameon: print("Welcome to Game of Greed") start_game = input("Wanna play?").lower() if start_game == 'y': gameon = True self.player_roll() elif start_game == 'n': gameon = True print("OK. Maybe another time") sys.exit() @staticmethod # Also check that all dice are scoring dice def validation(dice_values, dice_to_shelf): dice_values_to_validate = list(dice_values) #dice roll dice_to_shelf = dice_to_shelf #user input for i in dice_to_shelf: if i in dice_values_to_validate: dice_values_to_validate.remove(i) else: print('Cheater!!! Or possibly made a typo...') return True ctr = Counter(dice_to_shelf) if len(ctr) == 6: return False if len(ctr) == 3 and list(ctr.most_common())[2][1] == 2: return False for i in list(ctr.most_common()): if i[0] == 2 or i[0] == 3 or i[0] == 4 or i[0] == 6: if i[1] < 3: print('Cheater!!! Or possibly made a typo...') return True return False # remember self.fake_roll def player_roll(self): print(f"Starting round {self.current_round}") print(f"Rolling {self.remaining_dice} dice...") if self.dice_values is None: dice_values = GameLogic.roll_dice(self.remaining_dice) else: dice_values = self.dice_values # print("the dice_values are ", dice_values) # REMOVE points_to_bank = GameLogic.calculate_score(dice_values) if points_to_bank == 0: print('Zilch!!! Round over') print(f'You banked 0 points in round {self.current_round}') self.banker.clear_shelf() self.next_round() cheat_check = True while cheat_check: roll_display = "" for x in range(len(dice_values)): roll_display += str(dice_values[x]) + "," print(roll_display[:-1]) select_dice = input("Enter dice to keep (no spaces), or (q)uit: ") print("Nellie's: ", select_dice) # REMOVE if select_dice == 'q': self.quit_game() # dice_to_shelf = list(select_dice) # ORIG # dice_selected = list(select_dice) dice_selected = select_dice # check to make sure these are all integers -> Only if MVP # dice_to_shelf = tuple(map(int, dice_to_shelf)) dice_selected = tuple(dice_selected) # dice_to_shelf = (map(int, dice_to_shelf)) cheat_check = False # cheat_check = Game.validation(dice_values, dice_to_shelf) # points_to_bank = GameLogic.calculate_score(dice_to_shelf) points_to_bank = GameLogic.calculate_score(dice_selected) print(str(points_to_bank)) self.banker.shelf(points_to_bank) # self.remaining_dice -= len(dice_to_shelf) self.remaining_dice -= len(dice_selected) print( f'You have {self.banker.shelf_points} unbanked points and {self.remaining_dice} dice remaining' ) user_choice = input( "(r)oll again, (b)ank your points or (q)uit ").lower() if user_choice == 'r': # this also handles hot dice according to the flow tests if self.remaining_dice == 0: self.remaining_dice = 6 self.player_roll() elif user_choice == 'b': self.banker.bank() print('Your Banked Points: ', self.banker.bank_points) self.next_round() elif user_choice == 'q': self.quit_game() def next_round(self): self.remaining_dice = 6 self.current_round += 1 if self.current_round <= 20: self.player_roll() else: print('Game over') self.quit_game() def quit_game(self): print(f"Total score is {self.banker.bank_points} points") print( f"Thanks for playing. You earned {self.banker.bank_points} points") sys.exit() def play(self): self.welcome()
class GameOfGreed: """Game of Greed class""" def __init__(self, roll_dice=None): self.NUMBER_OF_ROUNDS = 10 self.bank = Banker() self.current_round = 1 self.number_of_dice_to_roll = 6 self.roll_dice = roll_dice if roll_dice else GameLogic.roll_dice # Game messages self.welcome_msg = 'Welcome to Game of Greed' self.wanna_play_msg = 'Wanna play? ' self.invalid_selection_msg = 'Cheater!!! Or possibly made a typo...' self.select_dice_msg = 'Enter dice to keep (no spaces), or (q)uit: ' self.zilch_msg = 'Zilch!!! Round over' self.options_msg = '(r)oll again, (b)ank your points or (q)uit ' def start_game(self) -> None: """Print welcome message and ask user if they want to start the game """ print(self.welcome_msg) answer = self.validate_answer(input(self.wanna_play_msg), ('y', 'n')) if answer == 'y': return self.game() elif answer == 'n': return print('OK. Maybe another time') def game(self) -> None: """Handle game workflow""" print( f'Starting round {self.current_round}/{self.NUMBER_OF_ROUNDS}') while self.current_round <= self.NUMBER_OF_ROUNDS: print(f'Rolling {self.number_of_dice_to_roll} dice...') current_roll = self.roll_dice(self.number_of_dice_to_roll) print(','.join(str(i) for i in current_roll)) # If current roll is worth 0 - go to the next round if GameLogic.calculate_score(current_roll)[0] == 0: print(self.zilch_msg) print( f'You banked {self.bank.bank_points} points in round {self.current_round}') print(f'Total score is {self.bank.bank_points} points') self.bank.clear_shelf() self.number_of_dice_to_roll = 6 self.current_round += 1 print( f'Starting round {self.current_round}/{self.NUMBER_OF_ROUNDS}') continue # Handle user dice selection selected_dice, all_dice_scored = self.handle_selection( current_roll) self.number_of_dice_to_roll -= len(selected_dice) print( f'You have {self.bank.shelf_points} unbanked points and {self.number_of_dice_to_roll} dice remaining') answer = self.validate_answer( input(self.options_msg), ('r', 'b', 'q')) if answer == 'r': if self.number_of_dice_to_roll == 0 and all_dice_scored: self.number_of_dice_to_roll = 6 continue elif answer == 'b': points = self.bank.bank() print( f'You banked {points} points in round {self.current_round}') print(f'Total score is {self.bank.bank_points} points') self.number_of_dice_to_roll = 6 self.current_round += 1 print( f'Starting round {self.current_round}/{self.NUMBER_OF_ROUNDS}') self.quit() def handle_selection(self, current_roll): while True: # Check if user entry is acceptable (number of dice or quit) acceptable_entries = ('1', '2', '3', '4', '5', '6', 'q') answer = self.validate_answer( input(self.select_dice_msg), acceptable_entries) # Check if user entry is a valid selection (dice are present in the current roll) while True: is_valid = all(str(current_roll).count(dice) >= answer.count(dice) for dice in answer) if is_valid: break print(self.invalid_selection_msg) print(','.join(str(i) for i in current_roll)) answer = self.validate_answer( input(self.select_dice_msg), acceptable_entries) # Calculate score for a valid selection valid_selection = tuple([int(i) for i in answer]) current_score, all_dice_scored, _ = GameLogic.calculate_score( valid_selection) # Shelf points self.bank.shelf(current_score) # If current selection is scored more than 0 - return, else ask to select again if current_score != 0: break selection = ', '.join(str(dice) for dice in answer) print( f'Selection of {selection} gives you 0 points, please try again') return (answer, all_dice_scored) def validate_answer(self, answer: str, acceptable_options: tuple) -> str: """Process user answer and brings it to the consistent format Args: answer (str): Original user answer acceptable_options (tuple): Tuple of acceptable answers Returns: str: Processed user answer """ while True: if answer.lower() == 'yes' or answer.lower() == 'y': answer = 'y' elif answer.lower() == 'no' or answer.lower() == 'n': answer = 'n' elif answer.lower() == 'roll' or answer.lower() == 'r': answer = 'r' elif answer.lower() == 'bank' or answer.lower() == 'b': answer = 'b' elif answer.lower() == 'quit' or answer.lower() == 'q': self.quit() if answer in acceptable_options or any(i in acceptable_options for i in answer): break answer = input(self.invalid_selection_msg) return answer def quit(self): """Shows final message and exits the program """ print(f'Total score is {self.bank.bank_points} points') print(f'Thanks for playing. You earned {self.bank.bank_points} points') sys.exit()
class Game: """Class for Game of Greed application """ def __init__(self, num_rounds=20): self.dice_remaining = None self.banker = Banker() self.num_rounds = num_rounds self.round_ = 0 self._roller = None def play(self, roller=None): """Entry point for playing (or declining) a game Args: roller (function, optional): Allows passing in a custom dice roller function. Defaults to None. """ self.round_num = 0 self._roller = roller or GameLogic.roll_dice print("Welcome to Game of Greed") print("(y)es to play or (n)o to decline") response = input("> ") if response == "y" or response == "yes": self.start_new_round() else: self.decline_game() def start_new_round(self): if self.round_ > self.num_rounds: self.user_quit() return self.round_ += 1 print(f"Starting round {self.round_}") self.dice_remaining = 6 self.game_round_rolling_phase() def game_round_rolling_phase(self): if not self.dice_remaining: self.dice_remaining = 6 print(f"Rolling {self.dice_remaining} dice...") roll = self._roller(self.dice_remaining) self.game_round_keep_phase(roll) def game_round_keep_phase(self, roll): self.print_dice(roll) if not GameLogic.calculate_score(roll): print('****************************************\n' '** Zilch!!! Round over **\n' '****************************************') print(f"You banked 0 points in round {self.round_}") print(f"Total score is {self.banker.balance} points") self.banker.clear_shelf() self.start_new_round() return kept_dice = None user_input = None while not user_input: print("Enter dice to keep, or (q)uit:") user_input = input("> ") if user_input == "q": self.user_quit() return parsed_input = [ int(number) for number in user_input if number.isnumeric() ] if not GameLogic.validate_keepers(roll, parsed_input): print('Cheater!!! Or possibly made a typo...') self.game_round_keep_phase(roll) return kept_dice = GameLogic.get_scorers(roll) # TODO, we should not pass the roll, but instead pass the kept dice # once that function is built self.dice_remaining -= len(kept_dice) self.game_round_gambling_phase(roll) def game_round_gambling_phase(self, kept_dice): score = GameLogic.calculate_score(kept_dice) self.banker.shelf(score) print( f"You have {self.banker.shelved} unbanked points and {self.dice_remaining} dice remaining" ) print("(r)oll again, (b)ank your points or (q)uit:") user_input = input("> ") if user_input == "r": self.game_round_rolling_phase() return if user_input == "q": self.user_quit() return if user_input == "b": print( f"You banked {self.banker.shelved} points in round {self.round_}" ) print(f"Total score is {self.banker.bank()} points") self.start_new_round() return # TODO: this function should return a list or tuple of dice that the user is keeping # it should not allow the user to keep dice that dont exist, or dice that that cannot score def validate_dice(self, roll, user_input): wants_to_keep = [] for char in user_input: wants_to_keep += char return wants_to_keep def user_quit(self): print(f"Thanks for playing. You earned {self.banker.balance} points") def print_dice(self, dice_rolled): output = "*** " for die in dice_rolled: output += f"{die} " output += "***" print(output) def decline_game(self): print("OK. Maybe another time") def start_game(self): self.round_ = 0 self.start_new_round()
class Game: """Class for Game of Greed application """ def __init__(self, roller=None, num_rounds=20): self._roller = roller or GameLogic.roll_dice self.banker = Banker() self.num_rounds = num_rounds self.round_num = 0 def play(self): """ Entry point for playing (or/not) a game """ print("Welcome to Game of Greed") prompt = "Wanna play?" self.choice(prompt.strip(), self.start_game, self.decline_game) def choice(self, prompt, accept, decline): response = input(prompt) if response == "y" or response == "yes": accept() else: decline() def decline_game(self): print("OK. Maybe another time") def start_game(self): self.round_num = 1 while self.round_num <= self.num_rounds: self.start_round(self.round_num) self.round_num += 1 print(f"Total score is {self.banker.balance} points") self.quit_game() def quit_game(self): print(f"Thanks for playing. You earned {self.banker.balance} points") sys.exit() def start_round(self, round, num_dice=6): print(f"Starting round {round}") round_score = 0 while True: roll = self.roll_dice(num_dice) if self.got_zilch(roll): break keepers = self.handle_keepers(roll) roll_again_response = input( "(r)oll again, (b)ank your points or (q)uit ") if roll_again_response == "q": self.quit_game() return elif roll_again_response == "b": round_score = self.banker.bank() break else: num_dice -= len(keepers) if num_dice == 0: num_dice = 6 print(f"You banked {str(round_score)} points in round {round}") def handle_keepers(self, roll): while True: keeper_string = input( "Enter dice to keep (no spaces), or (q)uit: ") if keeper_string.startswith("q"): self.quit_game() keepers = self.gather_keepers(roll, keeper_string) roll_score = self.calculate_score(keepers) if roll_score == 0: print("Must keep at least one scoring dice") else: break self.banker.shelf(roll_score) print( f"You have {self.banker.shelved} unbanked points and {len(roll) - len(keepers)} dice remaining" ) return keepers def roll_dice(self, num): print(f"Rolling {num} dice...") roll = self._roller(num) print(",".join([str(i) for i in roll])) return roll def got_zilch(self, roll): initial_score = self.calculate_score(roll) if initial_score == 0: print("Zilch!!! Round over") self.banker.clear_shelf() return True return False def calculate_score(self, roll): return GameLogic.calculate_score(roll) def keep_scorers(self, roll): return GameLogic.get_scorers(roll) def gather_keepers(self, roll, keeper_string): keepers = [int(ch) for ch in keeper_string] while not GameLogic.validate_keepers(roll, keepers): print("Cheater!!! Or possibly made a typo...") print(",".join([str(i) for i in roll])) keeper_string = input( "Enter dice to keep (no spaces), or (q)uit: ") if keeper_string.startswith("q"): self.quit_game() keepers = [int(ch) for ch in keeper_string] return keepers
class Game: """Class for Game of Greed application """ def __init__(self, num_rounds=20): self.banker = Banker() self.num_rounds = num_rounds self.round_num = 0 def play(self, roller=None): """Entry point for playing (or declining) a game Args: roller (function, optional): Allows passing in a custom dice roller function. Defaults to None. """ self._roller = roller or GameLogic.roll_dice print("Welcome to Game of Greed") print("(y)es to play or (n)o to decline") response = input("> ") if response == "y" or response == "yes": self.start_game() else: self.decline_game() def decline_game(self): print("OK. Maybe another time") def start_game(self): self.round_num = 1 while self.round_num <= self.num_rounds: self.start_round(self.round_num) self.round_num += 1 print(f"Total score is {self.banker.balance} points") self.quit_game() def quit_game(self): print(f"Thanks for playing. You earned {self.banker.balance} points") sys.exit() def start_round(self, round, num_dice=6): print(f"Starting round {round}") round_score = 0 while True: roll = self.roll_dice(num_dice) if self.got_zilch(roll): break keepers = self.handle_keepers(roll) print("(r)oll again, (b)ank your points or (q)uit:") roll_again_response = input("> ") if roll_again_response == "q": self.quit_game() return elif roll_again_response == "b": round_score = self.banker.bank() break else: num_dice -= len(keepers) if num_dice == 0: num_dice = 6 print(f"You banked {str(round_score)} points in round {round}") def handle_keepers(self, roll): while True: print("Enter dice to keep, or (q)uit:") keeper_string = input("> ") if keeper_string.startswith("q"): self.quit_game() keepers = self.gather_keepers(roll, keeper_string) roll_score = self.calculate_score(keepers) if roll_score == 0: print("Must keep at least one scoring dice") else: break self.banker.shelf(roll_score) num_dice_remaining = len(roll) - len(keepers) print( f"You have {self.banker.shelved} unbanked points and {num_dice_remaining} dice remaining" ) return keepers def roll_dice(self, num): print(f"Rolling {num} dice...") roll = self._roller(num) print("*** " + " ".join([str(i) for i in roll]) + " ***") return roll def got_zilch(self, roll): initial_score = self.calculate_score(roll) if initial_score == 0: width = 40 print("*" * width) print("**" + "Zilch!!! Round over".center(width - 4) + "**") print("*" * width) self.banker.clear_shelf() return True return False def calculate_score(self, roll): return GameLogic.calculate_score(roll) def _convert_keepers(self, keeper_string): return [int(ch) for ch in keeper_string if ch.isdigit()] def gather_keepers(self, roll, keeper_string): keepers = self._convert_keepers(keeper_string) while not GameLogic.validate_keepers(roll, keepers): print("Cheater!!! Or possibly made a typo...") print("*** " + " ".join([str(i) for i in roll]) + " ***") print("Enter dice to keep, or (q)uit:") keeper_string = input("> ") if keeper_string.startswith("q"): self.quit_game() keepers = self._convert_keepers(keeper_string) return keepers