面向对象编程---掷骰子游戏

面向对象编程—掷骰子游戏

最近编了一个面向编程的经典游戏案例,根据游戏的规则,设计编程的流程和类,方法,属性。这是一个比较经典和流行的面向对象编程的玩骰子的小游戏。

整个游戏分为四个模块:

​ ◆ 主菜单模块(main_menu.py)

​ ◊ 功能:导入主程序模块,定义一个AllThatDice类, 定义一个run函数

​ ◆ 主程序模块(main.py)

​ ◊ 功能:程序运行主界面,游戏玩家名单注册、显示游戏的总成绩、进入游戏、退出游戏。

​ playGame函数,参数为游戏名, getTable函数

​ ◆ 游戏玩家模块(Person.py)

​ ◊ 功能:定义人员类,属性包括玩家游戏初始币值、获胜场数、玩的总场数

​ won函数、res函数、play函数

​ ◆ 游戏模块(Games.py)

​ ◊ 功能:定义游戏类Game:

​ § 属性–骰子点数元组、参与游戏的最少玩家人数、最多玩家人数

​ § find函数,参数为玩家姓名,playIt函数,makeBid函数、sifter函数

​ 定义奇偶游戏子类Odd_or_Even(Game):

​ § 属性–游戏玩家账号account,参数为默认最少玩家数1,最多玩家数1,游戏名称“Odd-or-Even”

​ § play函数

​ 定义Maxi(Game)游戏子类:

​ § 属性–游戏玩家账号,参数为默认最少玩家数3,最多玩家数5,游戏名称“Maxi”

​ § play函数

​ 定义Bunco(Game)游戏子类:

​ § 属性–游戏玩家账号,参数为默认最少玩家数2,最多玩家数4,游戏名称“Bunco”

​ § play函数

游 戏 简 介

这款游戏的玩法分三种,第一种Odd-or_Even(猜奇偶数),只有一个玩家玩骰子。就是猜测骰子出现的数字是奇数还是偶数。如果猜对了,就算赢了。第二种游戏是Maxi,需要最少3个玩家,最多5个玩家掷一对骰子。每个玩家按顺序投掷一对骰子,正面朝上的数值总和最高的玩家获胜,如果一个玩家抛出香哦太难的最高金额,那么这些玩家将继续与其他玩家一起玩游戏。第三种游戏Bunco,需要最少2个玩家,最多4个玩家玩3个骰子。一共六轮游戏,每轮游戏,按顺序玩家投掷骰子,如果骰子的正面的数值与当前的游戏的轮数都不相等,那么不得分,轮到下一个游戏玩家,如果下一个游戏玩家投掷3个骰子,有一个正面朝上的骰子的数值与当前的轮数相等,那么加1point,该玩家继续投掷骰子,如果出现2个正面朝上的骰子的数值与当前轮数相等,那么该玩家加2points,那么如果出现3个骰子的正面朝上的数值与当前轮数不相等,但是三个骰子的数值相等,该玩家加5个points,继续投掷骰子,直到3个骰子中没有出现与该轮游戏轮数相等的数值,换下一个游戏玩家,每个游戏玩家的points累计相加,如果超过21,那么本轮游戏结束,达到或者超过21points的玩家就是本轮游戏的获胜者,如果出现3个骰子的正面数值都与该轮游戏轮数相等,那么就是“Bunco!”,并且加21points,该轮游戏结束,进入下一轮,而且下一轮首先出现的游戏玩家是当前结束的游戏玩家的下一个。

游 戏 运 行 环境

开发环境: PyCharm 2020

开发语言:Python3.9

游 戏 界 面

1. 主界面

包括四个选项,① 注册新游戏玩家 ② 显示游戏排行榜 ③ 玩游戏。④ 退 出,如下图红框所示:

2. 玩游戏之前,必须先注册游戏玩家

根据上图所示,选择输入r,进入游戏玩家注册界面,如下图所示:

3. 开始玩游戏

输入p,进入游戏界面,如下图所示:

4. 游戏界面出现三款游戏,进行选择

4.1 选择o, 进行奇偶游戏

如下图所示:

4.2 选择m, 进入Maxi游戏

如下图所示:

4.3 选择b, 进入Bunco游戏

如下图所示:

附上源码:

Games.py

import random
import Person


# 游戏类
class Game:
    s = ("x", "⚀", "⚁", "⚂", "⚃", "⚄", "⚅")
    g_name = ""
    g_max = 0
    g_min = 0
    # 参与游戏的玩家人数
    num_people = 0
    bid = {
    
    }  # 筹码字典
    n = 0  # 玩家数
    Pond = 0  # 奖池
    account = []  # 账户

    def __init__(self, a, b, s):
        self.g_min = a
        self.g_max = b
        self.g_name = s

    def find(self, name):
        for i in range(len(self.account)):
            if self.account[i].name == name:
                return i
        return -1

    # 进行游戏
    def playIt(self):
        if len(self.account) >= self.g_min:
            print("Let’s play the game of " + self.g_name + "!")
            print("How many players (" + str(self.g_min) + "-" + str(self.g_max) + ")?")
            return 1
        else:
            print("Not enough players to play " + self.g_name + ".")

    # 下注
    def makeBid(self):

        # 玩家数检查
        while True:
            self.num_people = input(">")
            self.num_people = int(self.num_people)
            if self.g_min <= self.num_people <= self.g_max:
                break
            else:
                print("Invalid choice.\n")
        try:
            # 参与玩家
            for i in range(1, self.num_people + 1):
                id1 = 0
                # 姓名录入
                while True:
                    print("What is the name of player #" + str(i) + "?")
                    name = input(">")
                    if self.find(name) != -1:
                        if not (name in self.bid):
                            id1 = self.find(name)
                            self.account[id1].play()
                            break
                        else:
                            print(name + " is already in the game.\n")

                    else:
                        print("There is no player named " + name + ".")

                # 赌注录入
                while True:
                    print("How many chips would you bid " + name + " (1-" + str(self.account[id1].coin) + ")?")
                    bid_i = input(">")
                    bid_i = int(bid_i)
                    if 1 <= bid_i <= self.account[id1].coin:
                        self.bid[name] = bid_i
                        self.account[id1].coin -= bid_i
                        self.Pond += bid_i
                        break
                    else:
                        print("Invalid number of chips.")
        except:
            print('请核实输入的信息!!')

    # 获取筛子
    def sifter(self, i):
        n = i + random.randint(1, 6)
        n %= 6
        if n == 0: return 6
        return n


# 赔率设置,输则扣掉bid,赢则获得bid
class Odd_or_Even(Game):

    def __init__(self, account):
        Game.__init__(self, 1, 1, "Odd-or-Even")
        self.account = account

    def play(self):
        if not self.playIt():
            return
        self.makeBid()

        arr = []
        i = 0
        for key in self.bid.keys():
            per = self.account[self.find(key)]
            o = 'e'
            odd = 0
            while True:
                print("Hey " + key + ", Odd (o) or Even (e)?")
                o = input(">")
                if o == 'o' or o == 'e':
                    if o == 'o':
                        odd = 1
                    else:
                        odd = 0
                    break
                else:
                    print("Invalid choice.\n")

            s = 0
            while True:
                print("How strong will you throw (0-5)?")
                s = int(input(">"))
                if 0 <= s <= 5:
                    break
                else:
                    print("Invalid choice.")

            s = self.sifter(s)
            print(self.s[s])
            if s % 2 == odd:
                per.coin += self.Pond * 2
                per.won()
                print("Congratulations, " + key + "! You win!")
            else:
                print("Sorry, " + key + "! You lose!")


# 赔率设置,赢家获得全部pond
class Maxi(Game):
    def __init__(self, account):
        Game.__init__(self, 3, 5, "Maxi")
        self.account = account

    def play(self):
        if not self.playIt():
            return
        self.makeBid()
        print("Let the game begin!")
        while True:
            num = {
    
    }
            nums = []
            for name in self.bid.keys():
                print("It’s " + name + "’s turn.")
                a = 0
                b = 0
                c = 0
                while True:
                    print("How strong will you throw (0-5)?")
                    c = int(input(">"))
                    if 0 <= c <= 5:
                        break
                    else:
                        print("Invalid choice.\n")

                a = self.sifter(c)
                b = self.sifter(c)
                print(self.s[a] + " " + self.s[b])
                # print(str(a) + "个点" + " " + str(b) + "个点")  # 防止看不清骰子
                nums.append(a + b)
                num[name] = a + b
            n = 0
            maxn = max(nums)
            for i in nums:
                if maxn == i:
                    n += 1

            if n == 1:
                for name in num.keys():
                    if num[name] == maxn:
                        e = self.account[self.find(name)]
                        e.coin += self.Pond
                        e.won()
                        print("Congratulations, " + name + "! You win!")
                        return
            else:
                print("Players remaining:")
                for name in num.keys():
                    if num[name] == maxn:
                        print(name + ',')
                    else:
                        del self.bid[name]


class Bunco(Game):
    def __init__(self, account):
        Game.__init__(self, 2, 4, "Bunco")
        self.account = account
        self.rnd_stop_flag = False


    def play(self):
        if not self.playIt():
            return
        self.makeBid()
        # 轮数
        rnd = 1
        # 总成绩列表
        total_score = []
        # 定义一个Bunco字典,键为玩家姓名,值为Bunco
        bunco = {
    
    }
        # 定义赢家赢的轮数字典, 键为玩家姓名,值为赢的轮数
        win_round = {
    
    }
        # 参与游戏的玩家列表
        player_lst = list(self.bid.keys())
        # 为每个玩家的bunco初始化为0
        for name in self.bid.keys():
            bunco[name] = 0
            win_round[name] = 0

        turn_i = 0
        while rnd <= 6:
            self.rnd_stop_flag = False

            # 把筹码字典键转成列表
            name_lst = list(self.bid.keys())
            # 遍历玩家名字列表,首轮玩家名字列表索引默认为0

            for i in range(turn_i, len(name_lst)):
                # 判断本轮游戏是否结束,如果结束退出本轮循环
                if self.rnd_stop_flag:
                    break
                # 这样才能做到每轮的结果不变,否则都是最后一轮的游戏结果
                score = str(rnd)
                score = {
    
    }
                print("<Round " + str(rnd) + ">")

                for name in self.bid.keys():
                    # 每一轮开始之前,得分字典清零
                    score['Round'] = rnd
                    score[name] = 0

                while True:
                    print("It’s " + name_lst[i] + "’s turn.")

                    a = 0
                    b = 0
                    c = 0
                    d = 0


                    while True:
                        print("How strong will you throw (0-5)?")
                        # 异常处理,否则输入非数字程序会崩溃退出
                        try:
                            d = int(input(">"))
                            if 0 <= d <= 5:
                                break
                            else:
                                print("Invalid choice.\n")
                        except:
                            print('Please input the number(0-5)!!')
                            pass

                    a = self.sifter(d)
                    b = self.sifter(d)
                    c = self.sifter(d)
                    print(self.s[a] + "     " + self.s[b] + "     " + self.s[c])
                    print(str(a) + "个点" + " " + str(b) + "个点" + " " + str(c) + "个点")

                    # 如果一个骰子的点数与游戏的轮数相等
                    if (a == rnd and a != b and a != c) or (b == rnd and a != b and b != c) or (
                            c == rnd and c != a and c != b):
                        score[name_lst[i]] += 1
                        print("You earned 1 point," + str(score[name_lst[i]]) + " points in total.")
                        if score[name_lst[i]] >= 21:
                            # 输出本轮游戏赢家名字
                            print(f"{
      
      name_lst[i]} is the winner in round {
      
      rnd}!")
                            # 把本轮的分值添加到列表
                            total_score.append(score)
                            win_round[name_lst[i]] += 1
                            #print(total_score)
                            #print(bunco)
                            # 跳到下一个人
                            turn_i = i + 1
                            # 判断是否超过玩家名字列表的索引范围
                            if turn_i == len(name_lst):
                                turn_i = 0
                            rnd += 1
                            self.rnd_stop_flag = True
                            print(f'===== 第{
      
      rnd-1}轮游戏结束!=====')
                            if rnd<=6:
                                print(f'===== 开启第{
      
      rnd}轮游戏!=====')
                            break
                        else:
                            print(f"Keep playing {
      
      name_lst[i]}")


                    # 如果 两个骰子的点数相同,而且两个点子数等于游戏的轮数,加2points
                    elif (a == b == rnd and a != c) or (a == c == rnd and a != b) or (b == c == rnd and b != a):
                        score[name_lst[i]] += 2
                        print("You earned 2 point," + str(score[name_lst[i]]) + " points in total.")
                        # 判断该游戏玩家总points是否超过21points
                        if score[name_lst[i]] >= 21:
                            # 输出本轮游戏赢家名字
                            print(f"{
      
      name_lst[i]} is the winner in round {
      
      rnd}!")
                            # 把本轮的分值添加到列表
                            total_score.append(score)
                            win_round[name_lst[i]] += 1
                            #print(total_score)
                            #print(bunco)
                            # 跳到下一个人
                            turn_i = i + 1
                            # 判断是否超过玩家名字列表的索引范围
                            if turn_i == len(name_lst):
                                turn_i = 0
                            rnd += 1
                            self.rnd_stop_flag = True
                            print(f'===== 第{
      
      rnd-1}轮游戏结束!=====')
                            if rnd<=6:
                                print(f'===== 开启第{
      
      rnd}轮游戏!=====')
                            break
                        else:

                            print(f"Keep playing {
      
      name_lst[i]}")


                    # 如果三个骰子的点数一样,但是不等于游戏的轮数,加5points
                    elif a == b == c and a != rnd:
                        score[name_lst[i]] += 5
                        print("You earned 5 point," + str(score[name_lst[i]]) + " points in total.")
                        # print(score)

                        # 判断该游戏玩家的总points是否超过21points
                        if score[name_lst[i]] >= 21:
                            # 输出本轮游戏赢家名字
                            print(f"{
      
      name_lst[i]} is the winner in round {
      
      rnd}!")
                            # 把本轮的分值添加到列表
                            total_score.append(score)
                            win_round[name_lst[i]] += 1
                            #print(total_score)
                            #print(bunco)
                            # 跳到下一个人
                            turn_i = i + 1
                            # 判断是否超过玩家名字列表的索引范围
                            if turn_i == len(name_lst):
                                turn_i = 0
                            rnd += 1
                            self.rnd_stop_flag = True
                            print(f'===== 第{
      
      rnd-1}轮游戏结束!=====')
                            if rnd <= 6:
                                print(f'===== 开启第{
      
      rnd}轮游戏!=====')
                            break
                        else:
                            print(f"Keep playing {
      
      name_lst[i]}")

                    # 如果没有一个骰子的点数跟游戏轮数一样,没有point,换人
                    elif a != rnd and b != rnd and c != rnd:
                        print("You earned no points, " + str(score[name_lst[i]]) + " points  in total.")
                        # print(score)

                        i += 1
                        # 判断是否超过玩家名字列表的索引范围
                        if i == len(name_lst):
                            i = 0

                    # 如果骰子点数都等于轮数,结束本轮游戏,进入下一轮
                    elif a == b == c == rnd:
                        print("Bunco!")
                        print("You earned 21 points, " + str(score[name_lst[i]] + 21) + " points in total.")
                        print(f"{
      
      name_lst[i]} is  the winner in round {
      
      rnd}!\n\n")
                        score[name_lst[i]] += 21
                        # 为每个人玩家赢得的bunco记录
                        bunco[name_lst[i]] += 1
                        # 把本轮的分值添加到列表
                        total_score.append(score)
                        win_round[name_lst[i]] += 1
                        # print(total_score)
                        # print(bunco)
                        # 跳到下一个人
                        turn_i = i + 1
                        # 判断是否超过玩家名字列表的索引范围
                        if turn_i == len(name_lst):
                            turn_i = 0
                        rnd += 1
                        self.rnd_stop_flag = True
                        print(f'===== 第{
      
      rnd-1}轮游戏结束!=====')
                        if rnd <=6:
                            print(f'===== 开启第{
      
      rnd}轮游戏!=====')
                        break

        # 把Bunco值转成列表
        bunco_lst = list(bunco.values())

        # 输出六轮游戏的总数据
        print('=' * 40)
        for key in total_score[0].keys():
            print(key, end='\t\t')
        print('\n' + '=' * 40)
        # 把总列表中第一个字典的所有键转成列表
        name_lst = list(total_score[0].keys())
        # 玩家人数等于列表中去掉第一个元素(round),其余就是游戏玩家的数
        num_people1 = len(name_lst) - 1
        # 玩家的六轮总points汇总作为sum列表的元素
        sum = []
        # 玩家的人数最少2位最多4位
        if num_people1 == 2:
            sum = [0, 0]
            # 0-5 代表 游戏1-6轮
            for new_i in range(6):
                # 遍历六轮的游戏的points值
                for value in total_score[new_i].values():
                    print(value, end='\t\t\t')
                sum[0] += list(total_score[new_i].values())[1]
                sum[1] += list(total_score[new_i].values())[2]
                print()
            print('=' * 40)
            print('Total' + '\t\t' + str(sum[0]) + '\t\t\t' + str(sum[1]))
            print('=' * 40)

            print('Bunco' + '\t\t' + str(bunco_lst[0]) + '\t\t\t' + str(bunco_lst[1]))
            print('=' * 40)
            # 取bunco最大值
            result = max(list(bunco.values()))
            #print(result)
            # 取sum最大值
            max_sum = max(sum)
            # 取赢的轮数最大值
            max_round = max(list(win_round.values()))

            for player in player_lst:
                # 玩家赢的轮数和bunco都是最高的,输出
                if  win_round[player] == max_round:
                    print(player + ' won ' + str(win_round[player]) + ' rounds,' + ' scoring  ' + str(
                        max_sum) + ' points,' + ' with ' + str(result) + ' Buncos.')
                    print(f'Congratulations, {
      
      player}!, You win! ')
                else:
                    pass


        # 游戏玩家3个人
        elif num_people1 == 3:
            sum = [0, 0, 0]

            for new_i in range(6):
                for value in total_score[new_i].values():
                    print(value, end='\t\t\t')
                sum[0] += list(total_score[new_i].values())[1]
                sum[1] += list(total_score[new_i].values())[2]
                sum[2] += list(total_score[new_i].values())[3]
                print()
            print('=' * 40)
            print('Total' + '\t\t' + str(sum[0]) + '\t\t\t' + str(sum[1]) + '\t\t\t' + str(sum[2]))
            print('=' * 40)
            print('Bunco' + '\t\t' + str(bunco_lst[0]) + '\t\t\t' + str(bunco_lst[1]) + '\t\t\t' + str(bunco_lst[2]))
            print('=' * 40)
            # 取bunco最大值
            result = max(list(bunco.values()))
            # 取sum最大值
            max_sum = max(sum)
            # 取赢的轮数最大值
            max_round = max(list(win_round.values()))
            for player in player_lst:
                # 玩家赢的轮数和bunco都是最高的,输出
                if  win_round[player] == max_round:
                    print(player + ' won ' + str(win_round[player]) + ' rounds,' + ' scoring  ' + str(
                        max_sum) + ' points,' + ' with ' + str(result) + ' Buncos.')
                    print(f'Congratulations, {
      
      player}!, You win! ')
                else:
                    pass
        elif num_people1 == 4:
            sum = [0, 0, 0, 0]

            for new_i in range(6):
                for value in total_score[new_i].values():
                    print(value, end='\t\t\t')
                sum[0] += list(total_score[new_i].values())[1]
                sum[1] += list(total_score[new_i].values())[2]
                sum[2] += list(total_score[new_i].values())[3]
                sum[3] += list(total_score[new_i].values())[4]
                print()
            print('=' * 40)
            print('Total' + '\t\t' + str(sum[0]) + '\t\t\t' + str(sum[1]) + '\t\t\t' + str(sum[2]) + '\t\t\t' + str(sum[3]))
            print('=' * 40)
            print('Bunco' + '\t\t' + str(bunco_lst[0]) + '\t\t\t' + str(bunco_lst[1]) + '\t\t\t' + str(bunco_lst[2]) +'\t\t\t' +str(bunco_lst[3]))
            print('=' * 40)
            # 取bunco最大值
            result = max(list(bunco.values()))
            # 取sum最大值
            max_sum = max(sum)
            # 取赢的轮数最大值
            max_round = max(list(win_round.values()))
            for player in player_lst:
                # 玩家赢的轮数和bunco都是最高的,输出
                if  win_round[player] == max_round:
                    print(player + ' won ' + str(win_round[player]) + ' rounds,' + ' scoring  ' + str(
                        max_sum) + ' points,' + ' with ' + str(result) + ' Buncos.')
                    print(f'Congratulations, {
      
      player}!, You win! ')
                else:
                    pass

Person.py

class Per:
    coin = 100
    name = ""
    # 胜场
    won_num = 0
    # 总场
    play_num = 0

    def __init__(self, name):
        self.name = name

    def res(self, n):
        self.coin = n

    def won(self):
        self.won_num += 1

    def play(self):
        self.play_num += 1

Main.py

import Games
import Person


account = []

def find(name):
    for i in range(len(account)):
        if account[i].name == name:
            return True
        else:
            return False


# 增加玩家
def add(name):
    if find(name):
        print("Sorry, the name is already taken.")
    else:
        # 账户初始额度100
        account.append(Person.Per(name))
        print("Welcome, " + name + "!")


# 进行游戏
def playGame(game):
    if game == 'o':
        e = Games.Odd_or_Even(account)
        e.play()
    elif game == 'm':
        e = Games.Maxi(account)
        e.play()
    elif game == 'b':
        e = Games.Bunco(account)
        e.play()
    else:
        print("Invalid choice.")


def getTable():
    print("=============================\n")
    print("Name       Played  Won  Chips\n")
    print("=============================\n")
    account.sort(key=lambda x: x.coin, reverse=True)
    for a in account:
        print(a.name, str(a.play_num).rjust(16-len(a.name)), str(a.won_num).rjust(4), str(a.coin).rjust(6), "\n")
    print("=============================")

# 主函数
print("\n> Welcome to All-That-Dice!" +
      "\n> Developed by Bruce_Liuxiaowei" +
      "\n> Object-Oriented Programming\n> Date:2022-06-02")

while True:
    print("\nWhat would you like to do?" +
          "\n(r) register a new player" +
          "\n(s) show the leader board" +
          "\n(p) play a game" +
          "\n(q) quit")
    flag = input(">")
    if flag == 'r':
        print("What is the name of the new player?")
        add(input(">"))
    elif flag == 's':
        getTable()
    elif flag == 'p':
        print("Which game would you like to play?\n" +
              "(o) Odd-or-Even\n" + "(m) Maxi\n" + "(b) Bunco")
        playGame(input(">"))
    elif flag == 'q':
        print("\nThank you for playing All-That-Dice!")
        break
    else:
        print("Invalid choice.")
    input()

Main_menu.py

import main

# 定义一个所有骰子游戏的类
class AllThatDice:
    def run(self):
        main.py


if __name__ == "__main__":
    my_all_that_dice = AllThatDice()
    my_all_that_dice.run()

猜你喜欢

转载自blog.csdn.net/weixin_41905135/article/details/125110883
今日推荐