예제 #1
0
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
예제 #2
0
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
예제 #3
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()
예제 #4
0
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()
예제 #5
0
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()
예제 #6
0
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
예제 #7
0
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