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

devtools/2025/3/19 9:40:08/

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

更新后的完整代码


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/devtools/168304.html

相关文章

pytorch小记(九):pytorch中创建指定形状的张量: torch.empty

pytorch小记&#xff08;九&#xff09;&#xff1a;pytorch中创建指定形状的张量: torch.empty 详细解释1. 基本功能2. 语法3. 示例代码示例 1&#xff1a;创建一个 5 的未初始化张量示例 2&#xff1a;创建一个 23 的未初始化张量示例 3&#xff1a;指定数据类型和设备 4. 注…

启幕数据结构算法雅航新章,穿梭C++梦幻领域的探索之旅——二叉树序列构造探秘——堆的奥义与实现诗篇

人无完人&#xff0c;持之以恒&#xff0c;方能见真我&#xff01;&#xff01;&#xff01; 共同进步&#xff01;&#xff01; 文章目录 一、堆的定义与结构二、堆的实现1.堆的初始化和销毁堆的初始化堆的销毁 2.向上调整算法和入堆向上调整算法入堆 3.向下调整算法和出堆顶数…

深度学习之防止过拟合

过拟合是机器学习中常见的问题,特别是当模型复杂度较高或训练数据量较少时。为了避免模型过度依赖训练数据中的噪声,采取一些有效的防止过拟合的方法非常重要。以下是几种常见的防止过拟合的技术,包括 Dropout、数据增强、正则化 等,并对它们进行详细的介绍与对比。 1. Dr…

IP 协议

文章目录 IP 协议概述数据包格式首部校验和实例分析实例一 分片抓包分析参考 本文为笔者学习以太网对网上资料归纳整理所做的笔记&#xff0c;文末均附有参考链接&#xff0c;如侵权&#xff0c;请联系删除。 IP 协议 概述 IP 协议是 TCP/IP 协议簇中的核心协议&#xff0c;也…

MySQL--DDL

1、DDL-数据库操作 查询&#xff1a; 查询所有数据库&#xff1a; SHOW DATABASES; 查询当前数据库&#xff1a; SELECT DATABASE(); 创建: CREATE DATABASE[IF NOT EXISTS] 数据库名 [DEFAULT CHARSET 字符集] [COLLATE 排序规则]&#xff1b; 删…

JVM部分八股

什么是JVM&#xff1f; 有哪些好处&#xff1f; 索引越界可能导致程序覆盖其他程序内存中的代码 JVM是一套规范&#xff0c;有多种实现 JVM运行流程&#xff1f; 1.类加载器将java程序翻译为java字节码文件 2.运行数据区将字节码文件加载到内存&#xff0c;字节码文件是J…

【计算机视觉】工业表计读数(2)--表计检测

1. 简介 工业表计&#xff08;如压力表、电表、气表等&#xff09;在工控系统、能源管理等领域具有重要应用。然而&#xff0c;传统人工抄表不仅工作量大、效率低&#xff0c;而且容易产生数据误差。近年来&#xff0c;基于深度学习的目标检测方法在工业检测中展现出极大优势&…

【第13节】windows sdk编程:GDI编程

目录 一、GDI 概述 二、设备环境概念 三、使用 GDI 绘图对象 四、使用 GDI 坐标系统 五、使用GDI绘图 5.1 输出文字 5.2 画点和线 5.3 画矩形框、圆和多边形 5.4 画位图和图标 5.5 双缓冲技术 六、综合代码示例 一、GDI 概述 Windows 应用程序不支持标准输出函数&am…