Tons-o-Dice

As a text-based application software, Tons-o-Dice will use a command line interface where users
type in a command or input and the relevant output is printed onto the screen in text. When the
software is executed, it will show a greeting message and a list of commands, followed by a
command prompt ‘>’ indicating the system is ready to take user’s input. At the prompt, users can
give one of the following commands:
n: new player, register an account for a new player
c: show the number of coins this player has
s: show the leader board, which will print the list of the players and their scores
p: play a game, which will start a new game
q: quit, which will quit the application
For registering a new player, the system will ask for the name of the new player. The name is not
allowed to be changed after being registered, and also the name must be unique (i.e. not allowed to have the same name as an existing player). A new player is given 100 coins for playing games.
Below is an example of the output on the screen (user’s input in bold italic ).
Welcome to Tons-o-Dice!
Developed by Alan Turing
COMP 1048 Object-Oriented Programming
What would you like to do?
(n) register a new player
(c) show your coins
(s) show the leader board
(p) play a game
(q) quit
> n
What is the name of the new player?
> Alan
Welcome, Alan!
What would you like to do?
(n) register a new player
(c) show your coins
(s) show the leader board
(p) play a game
(q) quit
> n
What is the name of the new player?
> Alan
Sorry, the name is already taken.
What would you like to do?
(n) register a new player
(c) show your coins
(s) show the leader board
(p) play a game
(q) quit
> n
What is the name of the new player?
> Steve
Welcome, Steve!
Users can play dice games. Only one game will be played at a time, i.e., the game must be finished before playing another game. There are three dice games users can choose from: Even-or-Odd, Minz, and Bunco. Different dice games have different number of players required. Even-or-Odd is played by one player, Minz can be played by 3 to 5 players, and Bunco can be played by 2 to 4 players. For playing Minz or Bunco, users will be asked how many players will play the game at the beginning. If the number of players registered is not enough to play the selected game, an error message will be displayed and return to the main menu. Once the number of players to play the game has been decided, each player needs to input the name and how much coins to bid. If the name does not match to a valid registered player or if the player with the name is already in the game, an error message will be shown and asked again. Each player can only bid up to the number of coins they have. Depending on the game results, the winner will receive the amount s/he bid, while others will lose their bid. If the player has no coins left, then that player cannot play anymore.
What would you like to do?
(n) register a new player
(c) show your coins
(s) show the leader board
(p) play a game
(q) quit
> p
Which game would you like to play?
(e) Even-or-Odd
(m) Minz
(b) Bunco
> m
Not enough players to play Minz.
What would you like to do?
(n) register a new player
(c) show your coins
(s) show the leader board
(p) play a game
(q) quit
> p
Which game would you like to play?
(e) Even-or-Odd
(m) Minz
(b) Bunco
> b
Let’s play the game of Bunco!
How many players (2-4)?
> 2
What is the name of player #1?
> Bill
There is no player named Bill.
What is the name of player #1?
> Alan
How many coins would you bid Alan (1-70)?
> 100
Invalid number of coins.
How many coins would you bid Alan (1-70)?
> 20
What is the name of player #2?
> Alan
Alan is already in the game. What is the name of player #2?
> Steve
How many coins would you bid Steve (1-100)?
> 25
After the players and their bids are all set, the game will start. Games that involve multiple players are played in a round-robin manner where each player takes a turn. When needing to throw dice, the player is asked for how strong s/he would throw, choosing a number between 0 to 5 (inclusive), which will affect the outcome by shifting the face up value. For example, if the random number generated by the system was 5, and the player’s input was 2, the face up value of the die will be 1.
The outcome of throwing dice should be printed using the following symbols:
⚀ ⚁ ⚂ ⚃ ⚄ ⚅
The game of Even-or-Odd has only one player playing with a die. To win, the player has to guess if the die will turn up with an even or odd number. Below are some examples of how it will be played:
Hey Steve, Even (e) or Odd (o)?
> a
Invalid choice.
Even (e) or Odd (o)?
> o
How strong will you throw (0-5)?
> 7
Invalid choice.
How strong will you throw (0-5)?
> 3
Congratulations, Steve! You win!
Hey Alan, Even (e) or Odd (o)?
> e
How strong will you throw (0-5)?
> 1
Sorry, Alan! You lose!
The game of Minz is played with a pair of dice. Each player in the game takes turn to throw a pair of dice and the player who gets the lowest sum of the face up values. If more than one player throws the same lowest sum, then those players keep playing with others being left out. For example, below is an example of three players playing:
Let the game begin!
It’s Steve’s turn.
How strong will you throw (0-5)?
> 3
⚀⚁
It’s Alan’s turn.
How strong will you throw (0-5)?
> 0
⚂⚂
It’s Bill’s turn.
How strong will you throw (0-5)?
> 5
⚀⚁
Players remaining: Steve, Bill
It’s Steve’s turn.
How strong will you throw (0-5)?
> 1
⚂⚃
It’s Bill’s turn.
How strong will you throw (0-5)?
> 5
⚅⚄
Congratulations, Steve! You win!
The game of Bunco is played with a set of three dice. There are six rounds in each game, and in each round the players take turns to roll dice in round robin (in the order of the players added to the game). The first round starts from the first player added to the game, then the rest of the rounds starts from the next player after the last player played in the previous round. Once a player in turn rolls dice, one point is awarded for each die that matches the current round number. For example, if two dice has a face up value of 3 after rolled in round 3 that player is awarded 2 points. If all three dice match the current round number (named a "Bunco"), 21 points are awarded. If all three dice match each other but do not match the current round number, 5 points are awarded. If any points are scored in his/her turn, the player gets to roll again, continuing to add to their score in round. If no points are awarded after rolling dice, that player's turn ends and the next player plays. Each round ends when a player has scored 21 points, which makes rolling a bunco an instant win. At the end of each round, the winner of that round is announced. The game ends when all six rounds are complete. At the end of the game a summary of the scores of each player in each round and the number of buncos played is reported, along with the winner of the game. The player with the most rounds won is the overall game winner, with ties broken by comparing total points scored. If the total points scored are the same, the player who had more Buncos win. Below is an example of three players playing the game of Bunco.
<Round 1>
It’s Steve’s turn.
How strong will you throw (0-5)?
> 5
⚄⚀⚃
You earned 1 point, 1 point in total.
Keep playing Steve.
How strong will you throw (0-5)?
> 3
⚀⚀⚂
You earned 2 points, 3 points in total.
Keep playing Steve.
How strong will you throw (0-5)?
> 1
⚅⚄⚁
You earned no points, 3 points in total.
It’s Bill’s turn.
How strong will you throw (0-5)?
> 2
⚀⚀⚀
Bunco!
You earned 21 points, 21 points in total.
Bill is the winner in round 1!
<Round 2>
It’s Alan’s turn.
How strong will you throw (0-5)?
> 5
⚁⚃⚁
You earned 2 points, 2 points in total.
Keep playing Alan.
How strong will you throw (0-5)?
> 3
⚃⚃⚃
You earned 5 points, 7 points in total.
Keep playing Alan.
How strong will you throw (0-5)?
3
⚃⚃⚀
You earned no points, 7 points in total.
It’s Steve’s turn.
How strong will you throw (0-5)?
> 0
⚁⚁⚁
Bunco!
You earned 21 points, 21 points in total.
Steve is the winner in round 2!
<Round 3>
It’s Bill’s turn.
How strong will you throw (0-5)?
2
⚂⚂⚂
Bunco!
You earned 21 points, 21 points in total.
Bill is the winner in round 3!
<Round 4>
It’s Alan’s turn.
How strong will you throw (0-5)?
> 1
⚂⚂⚂
You earned 5 points, 5 points in total.
Keep playing Alan.
How strong will you throw (0-5)?
2
⚁⚁⚁
You earned 5 points, 10 points in total.
Keep playing Alan.
How strong will you throw (0-5)?
> 0
⚃⚀⚃
You earned 2 points, 12 points in total.
Keep playing Alan.
How strong will you throw (0-5)?
> 3
⚀⚀⚀
You earned 5 points, 17 points in total.
Keep playing Alan.
How strong will you throw (0-5)?
> 2
⚅⚅⚅
You earned 5 points, 22 points in total.
Alan is the winner in round 4!
<Round 5>
It’s Steve’s turn.
How strong will you throw (0-5)?
> 4
⚂⚁⚂
You earned 0 points, 0 points in total.
It’s Bill’s turn.
How strong will you throw (0-5)?
> 2
⚁⚄⚄
You earned 2 points, 2 points in total.
Keep playing Bill.
How strong will you throw (0-5)?
> 5
⚀⚁⚂
You earned 0 points, 2 points in total.
It’s Alan’s turn.
How strong will you throw (0-5)?
5
⚄⚄⚄
Bunco!
You earned 21 points, 21 points in total.
Alan is the winner in round 5!
<Round 6>
It’s Steve’s turn.
How strong will you throw (0-5)?
> 4
⚁⚂⚁
You earned 0 points, 0 points in total.
It’s Bill’s turn.
How strong will you throw (0-5)?
3
⚅⚅⚅
You earned 21 points, 21 points in total.
Bill is the winner in round 6!
===============================
Round     Steve      Bill        Alan
===============================
1                 3           21          0
2                21            0          7
3                 0           21          0
4                 0            0         22
5                 0            2         21
6                 0           21          0
===============================
Total         24            65         50
===============================
Bunco        1              3           1
===============================
Bill won 3 rounds, scoring 65 points, with 3 Buncos.
Congratulations, Bill! You win!
Users can check how many coins they have by entering ‘c’ as shown in the example below.
Additionally, users can also view the leader board to keep track of their performance. The leader
board will show the list of all registered players with their details, including their name, the number
of games played, the number of games won, and the number of coins remaining. The list must be
sorted in the order of the number of coins, and if having the same number of coins, then in the order
of winning rate (i.e., the number of games won divided by the number of games played).
What would you like to do?
(n) register a new player
(c) show your coins
(s) show the leader board
(p) play a game
(q) quit
> c
You have 170 coins!
What would you like to do?
(n) register a new player
(c) show your coins
(s) show the leader board
(p) play a game
(q) quit
> s
=================================
Name Played        Won        Coins
=================================
Alan     11              8              325
Steve    5               4             170
Bill        7              3             170
Elon     15              8              95
=================================
What would you like to do?
(n) register a new user
(s) show the score board
(p) play a game
(q) quit
> q

Thank you for playing Tons-o-Dice!


额外要求:

code will run the application software you developed:
tod = TonsoDice()
tod.run()

1.Class TonsODice:This is your main class which controls all games

2.Class Game:An abstract class that combines attributes and methods which are common to all games

3.Class Player:Represents the human player

4.Class EvenOrOdd

5.Class Minz

6.Class Bunco

7.Class Die(or Dice):Necessary to explicitly show cardinalities between Player and the different types of game classes

8.Class Round:Necessary to explicitly show cardinalities and keep score for each round

话不多说,直接上源码,大家觉得有用,不妨收藏一下,多谢:
 

import random
from abc import ABC, abstractmethod

class Player:
    def __init__(self, name):
        """Initialize a Player object with a name, starting coins, games played, and games won."""
        self.name = name
        self.coins = 100
        self.games_played = 0
        self.games_won = 0

class Die:
    faces = ['⚀', '⚁', '⚂', '⚃', '⚄', '⚅']

    @staticmethod
    def roll(strength):
        """
        Simulates rolling a die with additional strength.

        Args:
        - strength (int): Additional strength added to the die roll.

        Returns:
        - str: A face of the die based on the result of the roll.
        """
        result = random.randint(1, 6) + strength
        return Die.faces[(result - 1) % 6]

class Game(ABC):
    def __init__(self, players):
        self.players = players
        """
        Abstract base class for defining a game.

        Args:
        - players (list of Player): List of players participating in the game.
        """
    @abstractmethod
    def play(self):
        """Abstract method to be implemented in subclasses to start playing the game."""
        pass

class EvenOrOdd(Game):
    def play(self):
        """Implementation of the Even-or-Odd game."""
        player = self.players[0]
        print(f"Hey {player.name}, Even (e) or Odd (o)?")
        while True:  
            try:  
                choice = input("> ").strip().lower()  
                if choice in ['e', 'o']:  
                    break  
                else:  
                    print("Invalid choice.")  
            except (TypeError, ValueError):  
                print("Invalid input. Please enter 'e' or 'o'.") 

        print("How strong will you throw (0-5)?")
        while True:  
            try:  
                strength = int(input("> ").strip())  
                if 0 <= strength <= 5:  
                    break  
                else:  
                    print("Invalid choice.")  
            except (TypeError, ValueError):  
                print("Invalid input. Please enter a number between 0 and 5.")  
  
        result = Die.roll(strength)  
        print(result)
        
        die_value = Die.faces.index(result) + 1
        if (choice == 'e' and die_value % 2 == 0) or (choice == 'o' and die_value % 2 != 0):
            print(f"Congratulations, {player.name}! You win!")
            player.games_played += 1
            player.games_won += 1
        else:
            print(f"Sorry, {player.name}! You lose!")
            player.games_played += 1

class Minz(Game):
    def play(self):
        """Implementation of the Minz game."""
        players = self.players[:]
        min_sum = float('inf')
        remaining_players = []

        while len(players) > 1:
            min_sum = float('inf')
            remaining_players.clear()

            for player in players:
                print(f"It’s {player.name}’s turn.")
                print("How strong will you throw (0-5)?")
                while True:  
                    try:  
                        strength = int(input("> ").strip())  
                        if 0 <= strength <= 5:  
                            break  
                        else:  
                            print("Invalid choice.")  
                    except (TypeError, ValueError):  
                        print("Invalid input. Please enter a number between 0 and 5.")  
  
                result1 = Die.roll(strength)
                result2 = Die.roll(strength)
                print(result1, result2)
                sum_of_dice = Die.faces.index(result1) + 1 + Die.faces.index(result2) + 1

                if sum_of_dice < min_sum:
                    min_sum = sum_of_dice
                    remaining_players = [player]
                elif sum_of_dice == min_sum:
                    remaining_players.append(player)

            players = remaining_players[:]

            if len(players) > 1:
                print(f"Players remaining: {', '.join(p.name for p in players)}")

        winner = players[0]
        print(f"Congratulations, {winner.name}! You win!")
        total_lost_bets = 0
        for player in self.players:
            player.games_played += 1
            if player!= winner:
                total_lost_bets += player.bid
        winner.coins += total_lost_bets
        winner.games_won += 1
        for player in self.players:
            if player!= winner:
                player.coins -= player.bid

class Bunco(Game):
    def __init__(self, players):
        """
        Initializes a Bunco game with players and sets up round scores and statistics.

        Args:
        - players (list of Player): List of players participating in the game.
        """
        super().__init__(players)
        self.rounds = 6
        self.scores = {player.name: [0] * self.rounds for player in players}
        self.buncos = {player.name: 0 for player in players}
        self.round_winners = {player.name: 0 for player in players}

    def play(self):
        """Implementation of the Bunco game."""
        for round_number in range(1, self.rounds + 1):
            print(f"<Round {round_number}>")
            round = Round(self.players, round_number)
            round.play()
            for player in self.players:
                self.scores[player.name][round_number - 1] += round.scores[player.name]
                self.buncos[player.name] += round.buncos[player.name]
            self.round_winners[round.winner] += 1
        self.show_summary()

    def show_summary(self):
        # Define the column width
        """Displays a summary of the Bunco game results."""
        column_width = 12
        # Create a format string for alignment
        header_format = f"{{:<{column_width}}}"
        data_format = f"{{:>{column_width + 1}}}"

        print("=" * (column_width * (len(self.players) + 1)))
        print(header_format.format("Round") + "".join(header_format.format(player.name) for player in self.players))
        print("=" * (column_width * (len(self.players) + 1)))
        
        for round_number in range(self.rounds):
            print(header_format.format(str(round_number + 1)) +
                "".join(header_format.format(self.scores[player.name][round_number]) for player in self.players))
        
        print("=" * (column_width * (len(self.players) + 1)))
        print(header_format.format("Total") + "".join(header_format.format(sum(self.scores[player.name])) for player in self.players))
        print("=" * (column_width * (len(self.players) + 1)))
        print(header_format.format("Bunco") + "".join(header_format.format(self.buncos[player.name]) for player in self.players))
        print("=" * (column_width * (len(self.players) + 1)))


        overall_winner = self.determine_winner()
        print(f"{overall_winner} won the game, scoring {sum(self.scores[overall_winner])} points, with {self.buncos[overall_winner]} Buncos.")
        print(f"Congratulations, {overall_winner}! You win!")

        # Update games_played for all players and games_won for the winner
        for player in self.players:
            player.games_played += 1
            if player.name == overall_winner:
                player.games_won += 1
                total_lost_bets = 0
                for other_player in self.players:
                    if other_player.name!= overall_winner:
                        total_lost_bets += other_player.bid
                player.coins += total_lost_bets
            else:
                player.coins -= player.bid

    def determine_winner(self):
        """
        Determines the overall winner of the Bunco game based on rounds won, points, and buncos.

        Returns:
        - str: Name of the overall winner.
        """
        max_rounds_won = max(self.round_winners.values())
        potential_winners = [name for name, rounds_won in self.round_winners.items() if rounds_won == max_rounds_won]

        if len(potential_winners) == 1:
            return potential_winners[0]
        
        max_points = max(sum(self.scores[name]) for name in potential_winners)
        potential_winners = [name for name in potential_winners if sum(self.scores[name]) == max_points]

        if len(potential_winners) == 1:
            return potential_winners[0]

        max_buncos = max(self.buncos[name] for name in potential_winners)
        potential_winners = [name for name in potential_winners if self.buncos[name] == max_buncos]

        return potential_winners[0]


class Round:
    def __init__(self, players, round_number):
        """
        Initializes a Round of Bunco with players and round number.

        Args:
        - players (list of Player): List of players participating in the round.
        - round_number (int): Number of the round.
        """
        self.players = players
        self.round_number = round_number
        self.scores = {player.name: 0 for player in players}
        self.buncos = {player.name: 0 for player in players}
        self.winner = None

    def play(self):
        """Plays through a round of Bunco."""
        starting_player_index = (self.round_number - 1) % len(self.players)
        round_over = False

        while not round_over:
            for i in range(len(self.players)):
                current_player = self.players[(starting_player_index + i) % len(self.players)]
                print(f"It’s {current_player.name}’s turn.")

                continue_turn = True

                while continue_turn:
                    print("How strong will you throw (0-5)?")
                    user_input = input("> ").strip()
                    if user_input == "":
                        print("Please enter a number.")
                    elif not user_input.isdigit():
                        print("Invalid input. Please enter a number.")
                    elif int(user_input) < 0 or int(user_input) > 5:
                        print("Invalid choice. Please enter a number between 0 and 5.")
                    else:
                        strength = int(user_input)
                        dice_results = [Die.roll(strength) for _ in range(3)]
                        dice_faces = [Die.faces.index(die) + 1 for die in dice_results]
                        print(''.join(dice_results))
                        points = self.calculate_points(dice_faces, self.round_number)
                        self.scores[current_player.name] += points

                        if points == 0:
                            print(f"You earned no points, {self.scores[current_player.name]} points in total.")
                            continue_turn = False
                        elif points == 21:
                            print("Bunco!")
                            print(f"You earned {points} points, {self.scores[current_player.name]} points in total.")
                            round_over = True
                            continue_turn = False
                        else:
                            print(f"You earned {points} points, {self.scores[current_player.name]} points in total.")
                            if self.scores[current_player.name] >= 21:
                                round_over = True
                                continue_turn = False

                if round_over:
                    break

        self.winner = max(self.scores, key=self.scores.get)
        print(f"{self.winner} is the winner in round {self.round_number}!")

    def calculate_points(self, dice_faces, round_number):
        """
        Calculates points based on dice faces for the round.

        Args:
        - dice_faces (list of int): Dice faces rolled in the round.
        - round_number (int): Number of the current round.

        Returns:
        - int: Points earned in the round.
        """
        if dice_faces.count(round_number) == 3:
            self.buncos[self.players[0].name] += 1
            return 21
        elif len(set(dice_faces)) == 1:
            return 5
        else:
            return dice_faces.count(round_number)


class TonsODice:
    def __init__(self):
        """Initializes the Tons-o-Dice game management system."""
        self.players = {}
        self.games = []

    def register_player(self):
        """Registers a new player for Tons-o-Dice."""
        print("What is the name of the new player?")
        name = input("> ").strip()
        if name in self.players:
            print(f"Sorry, {name} is already taken.")
        else:
            self.players[name] = Player(name)
            print(f"Welcome, {name}!\n")

    def show_coins(self, player_name):
        """
        Displays the number of coins for a specific player.

        Args:
        - player_name (str): Name of the player.
        """
        if player_name in self.players:
            print(f"You have {self.players[player_name].coins} coins!")
        else:
            print(f"No player named {player_name}.")

    def show_leaderboard(self):
        """Displays the leaderboard of players based on coins and win ratio."""
        leaderboard = sorted(self.players.values(), key=lambda p: (-p.coins, -p.games_won / max(1, p.games_played)))
        print("=============================")
        print("Name   Played   Won   Coins")
        print("=============================")
        for player in leaderboard:
            print(f"{player.name}" + "      "+ f"{player.games_played}" + "       " + f"{player.games_won}" + "     " + f"{player.coins}")
        print("=============================")

    def play_game(self):
        """Allows a player to choose and play a game."""
        print("Which game would you like to play?")
        print("(e) Even-or-Odd")
        print("(m) Minz")
        print("(b) Bunco")
        game_choice = input("> ").strip().lower()
        
        if game_choice == 'e':
            player_name = input("Enter your name: ").strip()
            if player_name in self.players:
                player = self.players[player_name]
                game = EvenOrOdd([player])
                game.play()
            else:
                print(f"No player named {player_name}.")
        elif game_choice in ['m', 'b']:
            num_players = int(input(f"How many players ({3 if game_choice == 'm' else 2}-{5 if game_choice == 'm' else 4})? ").strip())
            if num_players < (3 if game_choice == 'm' else 2) or num_players > (5 if game_choice == 'm' else 4):
                print("Invalid number of players.")
                return
            players = []
            for i in range(num_players):
                player_name = input(f"What is the name of player #{i + 1}?\n> ").strip()
                if player_name not in self.players:
                    print(f"There is no player named {player_name}.")
                    return
                player = self.players[player_name]
                if player in players:
                    print(f"{player_name} is already in the game.")
                    return
                bid = int(input(f"How many coins would you bid {player.name} (1-{player.coins})?\n> ").strip())
                while bid < 1 or bid > player.coins:
                    print("Invalid number of coins.")
                    bid = int(input(f"How many coins would you bid {player.name} (1-{player.coins})?\n> ").strip())
                player.bid = bid
                players.append(player)
            if game_choice == 'm':
                game = Minz(players)
            else:
                game = Bunco(players)
            game.play()
        else:
            print("Invalid game choice.")

    def run(self):
        """Runs the Tons-o-Dice game management interface."""
        print("Welcome to Tons-o-Dice!")
        print("Developed by Alan Turing")
        print("COMP 1048 Object-Oriented Programming\n")
        while True:
            print("What would you like to do?")
            print("(n) register a new player")
            print("(c) show your coins")
            print("(s) show the leader board")
            print("(p) play a game")
            print("(q) quit")
            command = input("> ").strip().lower()
            if command == 'n':
                self.register_player()
            elif command == 'c':
                player_name = input("Enter your name: ").strip()
                self.show_coins(player_name)
            elif command == 's':
                self.show_leaderboard()
            elif command == 'p':
                self.play_game()
            elif command == 'q':
                print("Thank you for playing Tons-o-Dice!")
                break
            else:
                print("Invalid command.")

if __name__ == "__main__":
    game = TonsODice()
    game.run()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值