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 _enter_dice(self): """simulate user entering which dice to keep. Defaults to all scoring dice""" roll = GameLogic.get_scorers(self.last_roll) roll_string = "" for value in roll: roll_string += str(value) if GameLogic.calculate_score(roll) < 200: self.report("> " + roll_string[0]) return roll_string[0] five_count = 0 two_count = 0 three_count = 0 for value in roll_string: if value == "5": five_count += 1 elif value == "2": two_count += 1 elif value == "3": three_count += 1 if two_count <= 4 and two_count != len(roll): roll_string.replace("2", "", two_count) if three_count <= 3 and three_count != len(roll): roll_string.replace("3", "", three_count) if five_count <= 2: if five_count == len(roll_string): roll_string.replace("5", "", 1) else: roll_string.replace("5", "", five_count) if roll_string == "": roll_string += str(roll[0]) self.report("> " + roll_string) return roll_string
def _enter_dice(self): """simulate user entering which dice to keep. Defaults to all scoring dice""" roll = GameLogic.get_scorers(self.last_roll) roll_string = "" # if we all dice score, please keep them all # if we are intending on banking, lets keep all scoring dice if len(roll) == len( self.last_roll) or self._roll_bank_or_quit() == "b": # self.real_print("\nINTENDING TO BANK:",self.dice_remaining) for value in roll: roll_string += str(value) self.report("> " + roll_string) return roll_string # lets go for highest average of points per die highest_score_per_die = 0 highest_scoring_dice = 0 highest_scoring_len = 0 # check each combination of dice, to determine the 'best' value per die, and keep that set roll = list(roll) roll.sort() for i in range(len(roll)): for j in range(len(roll)): if len(roll[i:j + 1]): test_dice = roll[i:j + 1] test_score = GameLogic.calculate_score( roll[i:j + 1]) / len(test_dice) if test_score > highest_score_per_die: highest_score_per_die = test_score highest_scoring_dice = test_dice highest_scoring_len = len(test_dice) elif test_score == highest_score_per_die: if (highest_score_per_die >= 100): if len(test_dice) > highest_scoring_len: highest_score_per_die = test_score highest_scoring_dice = test_dice highest_scoring_len = len(test_dice) for value in highest_scoring_dice: roll_string += str(value) self.report("> " + roll_string) return roll_string
def test_gl_calculate_score(self, roll, result): """Test if the method calculates correct number of scores Args: roll (tuple): roll combination result (int): points result """ assert GameLogic.calculate_score(roll)[0] == result
def zilch(round, roll, bank=0): if GameLogic.calculate_score(roll) == 0: print('Zilch!!! Round over') print(f'You banked 0 points in round {round}') print(f'Total score is {bank} points') return True return False
def farkle(self, roll): score = GameLogic.calculate_score(roll) if score == 0: print(f"""**************************************** ** Zilch!!! Round over ** ****************************************""") self.banker.clear_shelf()
def test_two_triplets(): assert GameLogic.calculate_score((3,1,3,1,3,1)) == 1300 assert GameLogic.calculate_score((5,5,5,1,1,1)) == 1500 assert GameLogic.calculate_score((2,2,2,4,4,4)) == 600 assert GameLogic.calculate_score((6,6,6,5,5,5)) == 1100 assert GameLogic.calculate_score((3,2,2,3,2,3)) == 500 assert GameLogic.calculate_score((3,2,2,2,3)) == 200 assert GameLogic.calculate_score((1,2,2,2,3)) == 300 assert GameLogic.calculate_score((2,2,2,3)) == 200
def test_roll_dice_2(): x = GameLogic.roll_dice(5) j = False for i in x: if 1 <= i <= 6 and type(i) is int: j = True expected = True actual = j assert actual == expected
def test_gl_roll_dice_pass_2(self): """Test if the method returns all values in specified range (1 - 6) """ results = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0} for _ in range(10000): roll = Counter(GameLogic.roll_dice((6))) for pips, times in roll.items(): results[pips] += times for times in results.values(): assert times > 0
def _mock_input(self, *args): prompt = args[0] if prompt.startswith("Wanna play?"): return "y" elif prompt.startswith("Enter dice to keep (no spaces), or (q)uit:"): scorers = GameLogic.get_scorers(self.roll) keepers = "".join([str(ch) for ch in scorers]) return keepers elif prompt.startswith("(r)oll again, (b)ank your points or (q)uit "): return "b" else: raise ValueError(f"Unrecognized prompt {prompt}")
def _enter_dice(self): """simulate user entering which dice to keep. Defaults to all scoring dice""" roll = GameLogic.get_scorers(self.last_roll) roll_string = "" for value in roll: roll_string += str(value) self.report("> " + roll_string) return roll_string
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 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
def handle_selection(self, roll): while True: print("Enter dice to keep, or (q)uit:") response = input("> ") if response == 'q': self.quit_game() saved_dice = self.saved_dice(roll, response) tup = tuple([int(i) for i in response]) score = GameLogic.calculate_score(tup) break self.banker.shelf(score) print( f'You have {self.banker.shelved} unbanked points and {len(roll) - len(saved_dice)} dice remaining' ) return saved_dice
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
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
def play_round(self, rounds_total): num_dice = 6 while True: # Rolling dice print(f"Rolling {num_dice} dice...") # roll = self.roller(num_dice) roll = self.roller(num_dice) print(','.join([str(i) for i in roll])) # For next version, check if ziltch here, if yes then break the round # Day 3 # Check what user wants to do more =input("Enter dice to keep (no spaces), or (q)uit: ") # Check if player wants to quit if more == 'q': self.quit_game() # Split "dice to keep" into list of integers splitted_dice=[int(i) for i in more] unbanked_score = GameLogic.calculate_score(self,(splitted_dice)) rounds_total += unbanked_score # Subtract from num_dice num_dice -= len(splitted_dice) print(f"You have {unbanked_score} unbanked points and {num_dice} dice remaining") what_next= input("(r)oll again, (b)ank your points or (q)uit ") if more == 'q': self.quit_game() if what_next=='b' or what_next=='bank': self.total += rounds_total print(f"You banked {rounds_total} points in round {self.round}") self.round += 1 num_dice = 6 print(f"Total score is {self.total} points") break
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 play(self): is_it_zilch = False is_it_cheater = False is_it_roll_again = 0 #to see if roll again more than 4 round = 0 score = 0 new_banker = Banker() print("Welcome to Game of Greed") response = input("Wanna play?") if response == 'n': print("OK. Maybe another time") elif response == 'y': while True: num_dice = 6 round += 1 print(f"Starting round {round}") print(f"Rolling {num_dice} dice...") roll = self.roller(num_dice) Game.print_roll(roll) if GameLogic.calculate_score(roll) == 0: is_it_zilch = True print('Zilch!!! Round over') print( f"You banked {new_banker.shelved} points in round {round}" ) print(f"Total score is {new_banker.balance} points") continue what_next = input( "Enter dice to keep (no spaces), or (q)uit: ") if what_next == 'q': if is_it_roll_again >= 4: print(f"Total score is {new_banker.balance} points") print( f"Thanks for playing. You earned {new_banker.balance} points" ) break elif is_it_cheater or is_it_zilch: print( f"Thanks for playing. You earned {new_banker.balance} points" ) break else: print(f"Total score is {new_banker.balance} points") print( f"Thanks for playing. You earned {new_banker.balance} points" ) break else: while GameLogic.if_cheater(roll, Game.totuple(what_next)) == 0: is_it_cheater = True print('Cheater!!! Or possibly made a typo...') Game.print_roll(roll) what_next = input( "Enter dice to keep (no spaces), or (q)uit: ") if what_next == 'q' or what_next == 'quit': if is_it_cheater: print( f"Thanks for playing. You earned {new_banker.balance} points" ) break else: print(f"Total score is {new_banker.balance} points") print( f"Thanks for playing. You earned {new_banker.balance} points" ) break else: num_dice = num_dice - len(what_next) what_next = int(what_next) to_topule = Game.totuple(what_next) new_banker.shelved = GameLogic.calculate_score(to_topule) print( f"You have {new_banker.shelved} unbanked points and {num_dice} dice remaining" ) new_responce = input( "(r)oll again, (b)ank your points or (q)uit ") if new_responce == 'b': new_banker.balance = new_banker.balance + new_banker.shelved print( f"You banked {new_banker.shelved} points in round {round}" ) new_banker.shelved = 0 print(f"Total score is {new_banker.balance} points") elif new_responce == 'q': if is_it_cheater: print( f"Thanks for playing. You earned {new_banker.balance} points" ) break else: print( f"Total score is {new_banker.balance} points") print( f"Thanks for playing. You earned {new_banker.balance} points" ) break while new_responce == 'r': is_it_roll_again += 1 print(f"Rolling {num_dice} dice...") roll = self.roller(num_dice) Game.print_roll(roll) if GameLogic.calculate_score(roll) == 0: is_it_zilch = True new_banker.shelved = 0 print('Zilch!!! Round over') print( f"You banked {new_banker.shelved} points in round {round}" ) print( f"Total score is {new_banker.balance} points") break what_next = input( "Enter dice to keep (no spaces), or (q)uit: ") if what_next == 'q': print( f"Thanks for playing. You earned {new_banker.balance} points" ) break else: num_dice = num_dice - len(what_next) what_next = int(what_next) to_topule = Game.totuple(what_next) add_value = GameLogic.calculate_score(to_topule) new_banker.shelved += add_value add_value = 0 print( f"You have {new_banker.shelved} unbanked points and {num_dice} dice remaining" ) new_responce = input( "(r)oll again, (b)ank your points or (q)uit ") if new_responce == 'r': continue elif new_responce == 'b': new_banker.balance = new_banker.balance + new_banker.shelved print( f"You banked {new_banker.shelved} points in round {round}" ) new_banker.shelved = 0 print( f"Total score is {new_banker.balance} points" ) break
def test_two_fives(): actual = GameLogic.calculate_score((5, 5)) expected = 100 assert actual == expected
def test_two_ones(): actual = GameLogic.calculate_score((1, 1)) expected = 200 assert actual == expected
def test_all(test_input, expected): actual = GameLogic.calculate_score(test_input) assert actual == expected
def test_single_five(): actual = GameLogic.calculate_score((5, )) expected = 50 assert actual == expected
def test_six_ones(): actual = GameLogic.calculate_score((1, 1, 1, 1, 1, 1)) expected = 4000 assert actual == expected
def test_six_of_a_kind(): actual = GameLogic.calculate_score((2, 2, 2, 2, 2, 2)) expected = 800 assert actual == expected
def test_straight(): actual = GameLogic.calculate_score((1, 6, 3, 2, 5, 4)) expected = 1500 assert actual == expected
def test_three_ones_and_a_five(): actual = GameLogic.calculate_score((1, 1, 1, 5)) expected = 1050 assert actual == expected
def test_validate_illegal_overflow(): roll = (1, ) keepers = (1, 1, 1, 1, 1, 1) actual = GameLogic.validate_keepers(roll, keepers) expected = False assert actual == expected
def test_validate_legal_keepers(): roll = (1, 2, 3, 4, 5) keepers = (5, 1) actual = GameLogic.validate_keepers(roll, keepers) expected = True assert actual == expected
def test_three_ones(): actual = GameLogic.calculate_score((1, 1, 1, 2, 3, 4)) expected = 1000 assert actual == expected