Python 扑克牌小游戏 十点半 (学堂在线-Python程序设计基础) 任务1-10

前言

代码文件分为 TenPoinHalf_class.py 和 Game.py 两个文件
为了方便 默认放在同一个目录下
运行的时候运行 Game.py 文件

十点半游戏规则介绍

项目名称:设计一个简易的十点半纸牌游戏。

玩家:由2到4个人玩,一个庄家,其余的都是闲家。
目标:使手中的牌的点数之和在不超过十点半的情况下尽量大。
牌数:一副牌剔除大小王的52张牌
点牌:A、2、3、4、5、6、7、9、10,其中A为1点其他牌为本身的点数。
人牌: J、Q、K被称为“人牌”,都算为半点。

发牌:从庄家自己开始发牌,按顺时针轮流发给闲家张第一张牌。

要牌:玩家可以根据自己底牌的点数选择是否要牌,如果觉得有胜算,就不必补牌。反之,则由庄家的下家开始,依序向庄家提出补牌申请。最多可以要4张。庄家接收了闲家的补牌信息后,必须自牌顶依序抽牌给需要的人,每次一张。每一轮补牌完毕后,若有人还要再补,依然可向庄家提出要求,注意补牌的先后次序不可搞乱。当各闲家不再提出补牌要求后,庄家必须翻出自己的持牌,然后斟酌实际情况自牌堆中补牌。

爆牌:持牌总点数超过十点半,则视为爆牌。闲家爆牌后不能再要牌了,并将自己所押注的筹码奉送给庄家。

胜负:等到庄家也不想补牌了(这中间也没发生爆掉的情况),便将所有人的持牌公开,一决胜负。若庄家闲家都爆牌,那么庄家大。庄家的点数最大(最接近或等于十点半),就可以取走各家所押注的筹码。反之,如果有比庄家点数多的人,庄家就得向他支付自己所押注的筹码。彼此点数相同则视为平手。 若有人补了4张牌,竟未发生爆掉情况,则称为五龙(该基本持牌共5张),其点数所代表的意义要比十点半还大。

任务8-扑克牌类

(1)创建一个表示扑克牌的Card类,该类包含包含花色、数值、init()构造函数、__str()__函数、计算单张牌大小的函数等成员。

TenPoinHalf_class.py

class Card:  # 创建一个表示扑克牌的Card类
    def __init__(self, suit, rank):  # 该类包含包含花色、数值、点数
        self.suit = suit
        self.rank = rank
        self.value = 0.0
        Card.calculate(self)

    def __str__(self):
        return "此牌的花色为%s,数值为%s,积分为%.1f" % (self.suit, self.rank, self.value)

    def calculate(self):  # 计算单张牌大小的函数
        if self.rank == 'A':
            value = 1
        elif self.rank == 'J' or self.rank == 'Q' or self.rank == 'K':
            value = 0.5
        else:
            value = float(self.rank)
        self.value = value

任务8-手牌类

(2)创建一手牌类 Hand,包括清空牌的方法、增加一张牌的方法、给出去一张牌的方法、计算一手牌点数的方法。

TenPoinHalf_class.py

class Hand:  # 手牌类 Hand
    def __init__(self, name):
        self.name = name
        self.handcard = []
        self.handvalue = 0.0

    def __str__(self):
        return "此为{}玩家的手牌,点数为{:.1f}".format(self.name, self.handvalue)

    def clearhand(self):  # 清空牌的方法
        self.handcard.clear()
        self.handvalue = 0.0

    def addcard(self, card):  # 增加牌的方法
        self.handcard.append(card.pop(0))
        Hand.handcalculate(self)

    def givecard(self, card):  # 给出去一张牌的方法
        self.handcard.remove(card)
        Hand.handcalculate(self)

    def handcalculate(self):  # 计算一手牌点数的方法
        value = 0
        for i in range(len(self.handcard)):
            value += self.handcard[i].value
        self.handvalue = value

任务9-一副牌类

(3)创建一个包含4个一手牌对象的列表
(4)创建一个包括52张牌的一副牌对象,实现轮流给4个一手牌对象发牌。最后打印4个一手牌的牌以及它们的总点数。

创建一副牌类,它继承了一手牌类,但是新增了生成牌、洗牌、发牌的方法。

TenPoinHalf_class.py

class Deck(Hand):  # 创建一副牌类,它继承了一手牌类
    def __init__(self):
        self.card = []
        Deck.producecard(self)
        Deck.refresh(self)

    def producecard(self):  # 生成牌

        for suit in ['♥', '♠', '♦', '♣']:
            for rank in [
                    'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J',
                    'Q', 'K'
            ]:
                self.card.append(Card(suit, rank))

    def refresh(self):  # 洗牌
        from random import shuffle
        shuffle(self.card)

    def deal(self, hand):  # 发牌
        hand.append(self.card.pop(0))

任务9-玩家类

创建一个玩家类,包括是否叫牌、爆牌、输牌、赢牌、平局等方法

TenPoinHalf_class.py

class Player:  # 玩家类
    def __init__(self, name, chip):
        self.name = name
        self.chip = chip
        self.hand = Hand(name)

    def __str__(self):
        return "玩家 {} 剩余筹码为 {:.1f} \n".format(self.name, self.chip)

    def bid(self):  # 是否叫牌

        if input("请问 {} 是否叫牌?叫牌请输入Y>>".format(self.name)) in ['Y', 'y']:
            print("给阿姨倒一杯卡布奇诺!我的回合,抽牌!\n")
            return True
        else:
            print("玩家 {} 选择不叫牌\n".format(self.name))
            return False

    def overflow(self):  # 是否爆牌
        if self.hand.handvalue > 10.5:
            print("爆牌了!\n")
            return True
        else:
            print("再接再厉!\n")
            return False

    def winlose(self, value):  # 判断玩家输赢
        if self.hand.handvalue > value.hand.handvalue or len(
                self.hand.handcard) == 5 > len(value.hand.handcard):
            print("win")
            return True
        else:
            print("lose")
            return False

任务9-庄家类

创建一个庄家类,它继承了玩家类,重写了是否叫牌的方法。

TenPoinHalf_class.py

class Banker(Player):  # 创建一个庄家类,它继承了玩家类
    def bid(self):  # 重写了是否叫牌的方法
        if input("请问庄家 {} 是否叫牌?叫牌请输入Y>>".format(self.name)) in ['Y', 'y']:
            print("给阿姨倒一杯卡布奇诺!我的回合,抽牌!\n")
            return True
        else:
            print("庄家 {} 选择不叫牌\n".format(self.name))
            return False

任务10-Game.py 完整代码

(1)在任务九的基础上完成本任务的代码编写。
(2)将任务八和任务九中编写的类单独放在一个名为TenPoinHalf_class代码文件中。
(3)创建一个名为Game的代码文件,并在其中创建一个Game类。
(4)在Game代码文件中创建一个游戏的主函数main()。
(5)调试代码,实现十点半游戏的所有功能。

Game.py

import TenPoinHalf_class as a


class Game:
    def __init__(self, id):
        self.id = id
        self.players = []  # 创建一个包含4个一手牌对象的列表
        self.chips = [0.0, 0.0, 0.0, 0.0, 0.0]
        while True:
            try:
                p = int(input("请输入玩家人数(1-5)>>"))
                if 1 <= p <= 5:
                    self.nums = p
                    break
                else:
                    pass
            except Exception:
                print("\nError:输入不正确\n")

        for i in range(self.nums - 1):
            self.players.append(
                a.Player(input("请输入{}号玩家姓名>>".format(i + 1)), 100))
        self.players.append(a.Banker(input("请输入庄家姓名>>"), 100))

    def main(self):  # 游戏的主函数
        self.deckcard = a.Deck()  # 创建一个包括52张牌的一副牌对象

        for i in range(self.nums - 1):
            while True:
                try:
                    p = float(
                        input(" {} 请下不大于20的筹码>>".format(self.players[i].name)))
                    if 0.0 < p <= 20.0:
                        self.chips[i] = p
                        break
                except Exception:
                    print("\nError:输入不正确\n")

        for i in range(self.nums):  # 实现轮流给4个一手牌对象发牌
            self.deckcard.deal(self.players[i].hand.handcard)  # 发牌
            self.players[i].hand.handcalculate()  # 计分
            # 打印4个一手牌的牌以及它们的总点数
            print(self.players[i].hand, '\n', *self.players[i].hand.handcard,
                  '\n')

        for i in range(self.nums):
            while self.players[i].bid():  # 调用是否叫牌
                self.players[i].hand.addcard(self.deckcard.card)  # 加牌
                print(self.players[i].hand, '\n',
                      *self.players[i].hand.handcard, '\n')
                if self.players[i].overflow():  # 调用是否爆牌
                    self.players[i].hand.clearhand()  # 手牌清空
                    break  # 爆牌后跳出循环
                elif len(self.players[i].hand.handcard) == 5:
                    print("全体起立!凑齐五小\n")
                    break

        for i in range(self.nums - 1):
            if self.players[i].winlose(self.players[self.nums - 1]):  # 调用输or赢
                print("玩家{}号赢了庄家!".format(i + 1))
                self.players[i].chip += self.chips[i]
                self.players[self.nums - 1].chip -= self.chips[i]
                print("{} 的余额为{}\n".format(self.players[i].name,
                                           self.players[i].chip))
            else:
                print("庄家赢了玩家{}号".format(i + 1))
                self.players[i].chip -= self.chips[i]
                self.players[self.nums - 1].chip += self.chips[i]
                print("{} 的余额为{}\n".format(self.players[i].name,
                                           self.players[i].chip))
        print("庄家 {} 的余额为{}\n".format(self.players[self.nums - 1].name,
                                      self.players[self.nums - 1].chip))
        print("第{}局游戏结束\n".format(self.id))


def play():
    n = 1
    x = Game(n)
    twice = 1
    while True:
        print("\n第{}局游戏开始".format(twice))
        x.main()

        if input("是否继续游戏?继续请输入Y>>") in ['Y', 'y']:
            twice += 1
        else:
            break
    print("\n游戏结束\n")
    print(*x.players)


if __name__ == '__main__':
    play()

TenPoinHalf_class.py 完整代码

TenPoinHalf_class.py

class Card:  # 创建一个表示扑克牌的Card类
    def __init__(self, suit, rank):  # 该类包含包含花色、数值、点数
        self.suit = suit
        self.rank = rank
        self.value = 0.0
        Card.calculate(self)

    def __str__(self):
        return "此牌的花色为%s,数值为%s,积分为%.1f" % (self.suit, self.rank, self.value)

    def calculate(self):  # 计算单张牌大小的函数
        if self.rank == 'A':
            value = 1
        elif self.rank == 'J' or self.rank == 'Q' or self.rank == 'K':
            value = 0.5
        else:
            value = float(self.rank)
        self.value = value


class Hand:  # 手牌类 Hand
    def __init__(self, name):
        self.name = name
        self.handcard = []
        self.handvalue = 0.0

    def __str__(self):
        return "此为{}玩家的手牌,点数为{:.1f}".format(self.name, self.handvalue)

    def clearhand(self):  # 清空牌的方法
        self.handcard.clear()
        self.handvalue = 0.0

    def addcard(self, card):  # 增加牌的方法
        self.handcard.append(card.pop(0))
        Hand.handcalculate(self)

    def givecard(self, card):  # 给出去一张牌的方法
        self.handcard.remove(card)
        Hand.handcalculate(self)

    def handcalculate(self):  # 计算一手牌点数的方法
        value = 0
        for i in range(len(self.handcard)):
            value += self.handcard[i].value
        self.handvalue = value


class Deck(Hand):  # 创建一副牌类,它继承了一手牌类
    def __init__(self):
        self.card = []
        Deck.producecard(self)
        Deck.refresh(self)

    def producecard(self):  # 生成牌

        for suit in ['♥', '♠', '♦', '♣']:
            for rank in [
                    'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J',
                    'Q', 'K'
            ]:
                self.card.append(Card(suit, rank))

    def refresh(self):  # 洗牌
        from random import shuffle
        shuffle(self.card)

    def deal(self, hand):  # 发牌
        hand.append(self.card.pop(0))


class Player:  # 玩家类
    def __init__(self, name, chip):
        self.name = name
        self.chip = chip
        self.hand = Hand(name)

    def __str__(self):
        return "玩家 {} 剩余筹码为 {:.1f} \n".format(self.name, self.chip)

    def bid(self):  # 是否叫牌

        if input("请问 {} 是否叫牌?叫牌请输入Y>>".format(self.name)) in ['Y', 'y']:
            print("给阿姨倒一杯卡布奇诺!我的回合,抽牌!\n")
            return True
        else:
            print("玩家 {} 选择不叫牌\n".format(self.name))
            return False

    def overflow(self):  # 是否爆牌
        if self.hand.handvalue > 10.5:
            print("爆牌了!\n")
            return True
        else:
            print("再接再厉!\n")
            return False

    def winlose(self, value):  # 判断玩家输赢
        if self.hand.handvalue > value.hand.handvalue or len(
                self.hand.handcard) == 5 > len(value.hand.handcard):
            print("win")
            return True
        else:
            print("lose")
            return False


class Banker(Player):  # 创建一个庄家类,它继承了玩家类
    def bid(self):  # 重写了是否叫牌的方法
        if input("请问庄家 {} 是否叫牌?叫牌请输入Y>>".format(self.name)) in ['Y', 'y']:
            print("给阿姨倒一杯卡布奇诺!我的回合,抽牌!\n")
            return True
        else:
            print("庄家 {} 选择不叫牌\n".format(self.name))
            return False

学堂在线课程链接

https://next.xuetangx.com/course/SZIIT61021001122/1515546

发布了1 篇原创文章 · 获赞 1 · 访问量 50

猜你喜欢

转载自blog.csdn.net/weixin_46059499/article/details/104592668