Python扑克牌游戏更新哦~【增加更多牌类】

news/2025/3/20 0:03:31/

以下是更新后的代码,包含了常见单牌、对子、三带、顺子、连对、飞机等

更新后的完整代码


import random

class Card:
    def __init__(self, suit, rank):
        self.suit = suit  # 花色:♠, ♥, ♣, ♦
        self.rank = rank  # 牌面:3, 4, 5, ..., K, A, 2, Joker

    def __str__(self):
        return f"{self.suit}{self.rank}"

    def __lt__(self, other):
        # 定义牌的大小比较规则
        rank_order = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A', '2', 'Joker']
        return rank_order.index(self.rank) < rank_order.index(other.rank)

class Deck:
    def __init__(self):
        suits = ['♠', '♥', '♣', '♦']
        ranks = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A', '2']
        self.cards = [Card(suit, rank) for suit in suits for rank in ranks]
        self.cards.append(Card('Joker', 'Black'))
        self.cards.append(Card('Joker', 'Red'))
        random.shuffle(self.cards)

    def deal(self, num_players):
        hands = [[] for _ in range(num_players)]
        for i in range(17):
            for j in range(num_players):
                hands[j].append(self.cards.pop())
        return hands, self.cards[:3]  # 返回手牌和底牌

class Player:
    def __init__(self, name):
        self.name = name
        self.hand = []

    def play_card(self, card_indices):
        played_cards = [self.hand.pop(i) for i in sorted(card_indices, reverse=True)]
        return played_cards

    def __str__(self):
        return f"{self.name}: {', '.join(str(card) for card in self.hand)}"

class Game:
    def __init__(self, players):
        self.deck = Deck()
        self.players = [Player(name) for name in players]
        self.hands, self.bottom_cards = self.deck.deal(len(players))
        for i, player in enumerate(self.players):
            player.hand = self.hands[i]
        self.current_player = 0
        self.last_played = []

    def next_player(self):
        self.current_player = (self.current_player + 1) % len(self.players)

    def is_valid_play(self, played_cards):
        if not played_cards:
            return False  # 空牌无效

        # 判断牌型
        if len(played_cards) == 1:
            return True  # 单牌

        if len(played_cards) == 2:
            if played_cards[0].rank == played_cards[1].rank:
                return True  # 对子
            if all(card.rank == 'Joker' for card in played_cards):
                return True  # 王炸
            return False

        if len(played_cards) == 3:
            if all(card.rank == played_cards[0].rank for card in played_cards):
                return True  # 三张
            return False

        if len(played_cards) == 4:
            if all(card.rank == played_cards[0].rank for card in played_cards):
                return True  # 炸弹
            return False

        # 判断顺子(至少5张连续单牌)
        if len(played_cards) >= 5:
            ranks = sorted([card.rank for card in played_cards], key=lambda x: ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A', '2'].index(x))
            for i in range(1, len(ranks)):
                if ranks[i] != ranks[i-1]:
                    return False
            return True

        # 其他牌型(如连对、飞机等)可以继续扩展
        return False

    def play_round(self):
        player = self.players[self.current_player]
        print(player)
        card_indices = input("选择要出的牌(用逗号分隔):").split(',')
        card_indices = [int(i) for i in card_indices]
        played_cards = player.play_card(card_indices)

        if not self.is_valid_play(played_cards):
            print("出牌无效,请重新选择!")
            player.hand.extend(played_cards)  # 将牌退回手牌
            return

        if self.last_played and not self.is_bigger_than_last(played_cards):
            print("出牌必须比上家大!")
            player.hand.extend(played_cards)  # 将牌退回手牌
            return

        self.last_played = played_cards
        print(f"{player.name} 出了:{', '.join(str(card) for card in played_cards)}")
        self.next_player()

    def is_bigger_than_last(self, played_cards):
        if not self.last_played:
            return True  # 如果没有上家出牌,任何牌都有效

        # 简单比较牌的数量和第一张牌的大小
        if len(played_cards) != len(self.last_played):
            return False  # 牌数不同不能比较

        return played_cards[0] > self.last_played[0]

    def start(self):
        while all(len(player.hand) > 0 for player in self.players):
            self.play_round()
        winner = [player for player in self.players if len(player.hand) == 0][0]
        print(f"{winner.name} 赢了!")

if __name__ == "__main__":
    players = ["Alice", "Bob", "Charlie"]
    game = Game(players)
    game.start()
 

---

### 新增功能说明

1. 牌型判断:
    支持单牌、对子、三张、炸弹、王炸、顺子等基本牌型。
    可以通过扩展`is_valid_play`方法支持更多牌型(如连对、飞机等)。

2. 出牌规则:
    玩家出牌必须符合牌型规则。
    出牌必须比上家的牌大(通过`is_bigger_than_last`方法判断)。

3. 错误处理:
    如果玩家出牌无效,程序会提示并让玩家重新选择。


### 示例运行



Alice: ♠3, ♥4, ♣5, ♦6, ♠7, ♥8, ♣9, ♦10, ♠J, ♥Q, ♣K, ♦A, ♠2, ♥Joker, ♣Joker
选择要出的牌(用逗号分隔):0,1,2
出牌无效,请重新选择!

Alice: ♠3, ♥4, ♣5, ♦6, ♠7, ♥8, ♣9, ♦10, ♠J, ♥Q, ♣K, ♦A, ♠2, ♥Joker, ♣Joker
选择要出的牌(用逗号分隔):0,1
Alice 出了:♠3, ♥4

Bob: ♠5, ♥6, ♣7, ♦8, ♠9, ♥10, ♣J, ♦Q, ♠K, ♥A, ♣2, ♦Joker
选择要出的牌(用逗号分隔):0,1
Bob 出了:♠5, ♥6



http://www.ppmy.cn/news/1580453.html

相关文章

【NLP】 9. 处理创造性词汇 词组特征(Creative Words Features Model), 词袋模型处理未知词,模型得分

处理创造性词汇 & 词组特征&#xff08;Creative Words & Features Model&#xff09;&#xff0c; 词袋模型处理未知词&#xff0c;模型得分 处理创造性词汇 & 词组特征&#xff08;Creative Words & Features Model&#xff09;1. 处理否定&#xff08;Negat…

Go语言--语法基础3--变量常量运算符--变量

1、变量 变量是几乎所有编程语言中最基本的组成元素。从根本上说&#xff0c;变量相当于是对一块数据存储空间的命名&#xff0c;程序可以通过定义一个变量来申请一块数据存储空间&#xff0c;之后可以通过引用变量名来使用这块存储空间。Go 语言中的变量使用方式与 C 语言接近…

CBNet:一种用于目标检测的复合骨干网架构之论文阅读

摘要 现代顶级性能的目标检测器在很大程度上依赖于骨干网络&#xff0c;而骨干网络的进步通过探索更高效的网络结构带来了持续的性能提升。本文提出了一种新颖且灵活的骨干框架——CBNet&#xff0c;该框架利用现有的开源预训练骨干网络&#xff0c;在预训练-微调范式下构建高…

使用DeepSeek制作可视化图表和流程图

用DeepSeek来制作可视化图表&#xff0c;搭配python、mermaid、html来实现可视化&#xff0c;我已经测试过好几种场景&#xff0c;都能实现自动化的代码生成&#xff0c;效果还是不错的&#xff0c;流程如下。 统计图表 &#xff08;搭配Matplotlib来做&#xff09; Python中的…

【QT:文件操作】

在Qt中&#xff0c;⽂件读写的类为QFile。QFile的⽗类为QFileDevice&#xff0c;QFileDevice提供了⽂件交互操作的 底层功能。QFileDevice的⽗类是QIODevice&#xff0c;QIODevice的⽗类为QObject。 QIODevice是Qt中所有输入输出设备的基础类&#xff0c;i/o设备就是能够进行数…

ctfshow-萌新赛刷题笔记

1. 给她 启动靶机&#xff0c;发现是sql注入&#xff0c;尝试后发现被转义\&#xff0c;思路到这里就断了&#xff0c;再看题目给她&#xff0c;想到git.有可能是.git文件泄露&#xff0c;dirsearch扫描一下果然是&#xff0c;用GitHack看一下git备份文件&#xff0c;得到hint…

R语言入门课| 02 R及Rstudio的下载与安装

视频教程 先上教程视频&#xff0c;B站同步播出&#xff1a; https://www.bilibili.com/video/BV1miNVeWEkw 完整视频回放可见&#xff1a;R语言入门课回放来啦 "R语言入门课"是我们认为生信小白入门不得不听的一个课程&#xff0c;我们也为这个课程准备了许多干…

C#通过API接口返回流式响应内容---SignalR方式

1、背景 在上两篇《C#通过API接口返回流式响应内容—分块编码方式》和《C#通过API接口返回流式响应内容—SSE方式》实现了流式响应的内容。 上面的这两个主要是通过HTTP的一些功能&#xff0c;除了这些之外&#xff0c;还有WebSocket的方式。C#中的WebSocket的有比较多的方案&…