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

发布于:2025-03-16 ⋅ 阅读:(16) ⋅ 点赞:(0)

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

更新后的完整代码


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