耶耶耶耶耶 发表于 2024-12-27 03:28:51

用Python写炸金花游戏

以卑鄙戏规则:
https://i-blog.csdnimg.cn/direct/38089b6e1d9e42c09ddef4cc76cd2f39.png
那么我们要实现的功能,就是以下几个:

[*]生成扑克牌。
[*]随机洗牌并分发给五名玩家,每人三张牌。
[*]判定每位玩家的牌型(比方:豹子、同花顺等)。
[*]比较五名玩家的牌型,得出赢家。
代码分解与讲授

1. 扑克牌的生成与洗牌

suit_cards = ['黑桃', '红桃', '方块', '梅花']# 花色
check_number = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']# 点数

# 嵌套循环生成扑克牌
# poker_list =
poker_list = []
for suit in suit_cards:
    for check in check_number:
      poker_list.append(f"{suit}{check}")

random.shuffle(poker_list)# 洗牌
功能:


[*]通过嵌套循环,生成一副完整的扑克牌(共 52 张)。

[*]比方,“黑桃2”、“红桃A” 等。

[*]使用 random.shuffle() 对扑克牌列表进行随机洗牌,确保发牌的随机性。
[*]这内里把存储牌的容器设置为列表poker_list,实在聚集set也可以,不外聚集有随机性,还是喜好都在掌握中的感觉,而且列表方便管理。
2. 给玩家发牌

player = ['player1', 'player2', 'player3', 'player4', 'player5']# 玩家列表
# player_poker = {p: [] for p in player}# 初始化每个玩家的手牌为空列表(字典推导式)
player_poker = {}# 初始化一个空字典
for p in player:# 遍历每个玩家
    player_poker = []# 为每个玩家赋值一个空列表,表示其手牌,player_poker是个字典,键是用户,列表是值(也就是玩家手牌)

# 确保牌的数量足够分发
if len(poker_list) < len(player) * 3:
    raise ValueError("牌堆中牌的数量不足以分发给所有玩家!")

# 每人发三张牌
for i in range(3):# 每人发3轮
    for p in player:       # 嵌套循环,player中有5个,一共循环15次
      poker = poker_list.pop()# 从牌堆顶部发一张牌
      player_poker.append(poker)
功能:

[*]初始化 5 名玩家,每名玩家分配一个空手牌列表。
[*]检查如果牌堆中牌的数量不敷,则抛出错误。
[*]每名玩家每轮发一张牌,共发 3 轮,每人得到 3 张牌。
[*]发牌后,每名玩家的牌存储在 player_poker 中,结构如下:{
    'player1': ['黑桃K', '方块Q', '红桃A'],
    'player2': ['梅花7', '黑桃8', '红桃10'],
    ...
}

3. 打印玩家的手牌

for player, pokers in player_poker.items():# items是字典的方法,返回一个可迭代对象,每个元素是一个键值对
    print(f"{player}的牌是:{', '.join(pokers)}")
功能:


[*]将每名玩家的手牌以字符串形式打印出来,方便观察。
[*].join() 是一个字符串方法,用于将列表中的元素用指定的字符串毗连起来。
[*]', '.join(pokers) 会将列表中的元素用逗号加空格(, )毗连成一个字符串:
', '.join(['黑桃A', '红桃K', '方块Q'])# 结果: '黑桃A, 红桃K, 方块Q'

输出示例:
player1的牌是:黑桃K, 方块Q, 红桃A
player2的牌是:梅花7, 黑桃8, 红桃10
...
4. 定义牌的优先级

point_rank = {point: i for i, point in enumerate(check_number, start=2)}# 字典推导式(i,point)对
这里解释一下:point是键,i是值, 可以去看一下字典推导式的结构构成
功能:


[*]point_rank:定义点数的巨细,数值越大点数越高。比方,“A” 的优先级最大,值为 14。{'2': 2, '3': 3, ..., 'K': 13, 'A': 14}

5. 判定牌型

def poker_type(cards):#这个cards是列表,也就是前面键值对中的值
    points = sorted( for card in cards], key=lambda x: point_rank)# 提取点数并按大小排序
    suits = for card in cards]# 提取花色(列表推导式),索引前两个字符

    # 判断是否为豹子
    if points == points == points:
      return '豹子', points

    # 判断是否为同花顺
    is_straight = (point_rank] - point_rank] == 1 and \
                   point_rank] - point_rank] == 1) or points == ['2', '3', 'A']
    if len(set(suits)) == 1 and is_straight:   # len(set(suit))==1判断一个列表或字符串中的所有元素是否相同
      return '同花顺', points

    # 判断是否为顺子
    if is_straight:
      return '顺子', points

    # 判断是否为同花
    if len(set(suits)) == 1:
      return '同花', points

    # 判断是否为对子
    if points == points or points == points or points == points:
      return '对子', points

    # 如果都不是,返回单张
    return '单张', points
功能:
根据玩家的三张牌,判定牌型并返回 牌型名称 和 点数列表。

[*]豹子:三张点数雷同。
[*]同花顺:花色雷同,点数连续。
[*]顺子:点数连续(但花色不肯定雷同)。
[*]同花:花色雷同(但点数不肯定连续)。
[*]对子:两张牌点数雷同。
[*]单张:既不连续,也不同花或对子。
6. 确定牌型优先级

hand_rankings = ['单张', '对子', '顺子', '同花', '同花顺', '豹子']
功能:


[*]定义牌型的优先级,牌型从低到高依次为:

[*]单张 < 对子 < 顺子 < 同花 < 同花顺 < 豹子。

7. 比较两手牌的巨细

def compare_hands(player1, player2):
    type1, points1 = player1
    type2, points2 = player2

    # 比较牌型优先级
    if hand_rankings.index(type1) > hand_rankings.index(type2):
      return 1
    elif hand_rankings.index(type1) < hand_rankings.index(type2):
      return -1

    # 如果牌型相同,逐个比较点数
    for p1, p2 in zip(reversed(points1), reversed(points2)):
      if point_rank > point_rank:
            return 1
      elif point_rank < point_rank:
            return -1

    # 如果点数相同
    return 0
功能:


[*]先比较两手牌的牌型优先级,优先级高者胜。
[*]如果牌型雷同,逐一比较点数,由高到低比较。
8. 计算每个玩家的牌型并找出赢家

player_hands = {player: poker_type(cards) for player, cards in player_poker.items()}

winner = max(player_hands.items(), key=lambda item: (hand_rankings.index(item), item))
功能:

[*]遍历每名玩家的手牌,计算牌型。
[*]使用 max 函数,根据牌型优先级和点数巨细,找出赢家。
9. 打印结果

print("\n牌局结果:")
for player, (hand_type, points) in player_hands.items():
    print(f"{player} 的牌型: {hand_type} ({', '.join(points)})")

print(f"赢家是: {winner},牌型: {winner} ({', '.join(winner)})")
功能:


[*]输出每名玩家的牌型和点数。
[*]输出赢家及其牌型。
输出示例:
player1 的牌型: 顺子 (10, J, Q)
player2 的牌型: 对子 (8, 8, K)
player3 的牌型: 单张 (7, 9, A)
player4 的牌型: 同花 (4, 6, J)
player5 的牌型: 豹子 (K, K, K)

赢家是: player5,牌型: 豹子 (K, K, K)
完整代码

import random# 定义扑克牌花色和点数suit_cards = ['黑桃', '红桃', '方块', '梅花']check_number = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']# 生成扑克牌poker_list = random.shuffle(poker_list)# 洗牌# 玩家和玩家手牌player = ['player1', 'player2', 'player3', 'player4', 'player5']player_poker = {p: [] for p in player}# 发牌,每人发三张if len(poker_list) < len(player) * 3:    raise ValueError("牌堆中牌的数量不敷以分发给所有玩家!")for i in range(3):    for p in player:      poker = poker_list.pop()      player_poker.append(poker)# 打印每个玩家的牌for player, pokers in player_poker.items():    print(f"{player}的牌是:{', '.join(pokers)}")# 定义点数优先级point_rank = {point: i for i, point in enumerate(check_number, start=2)}# 判定牌型def poker_type(cards):    points = sorted( for card in cards], key=lambda x: point_rank)    suits = for card in cards]    # 判定是否为豹子    if points == points == points:      return '豹子', points    # 判定是否为同花顺    is_straight = (point_rank] - point_rank] == 1 and \                   point_rank] - point_rank] == 1) or points == ['2', '3', 'A']    if len(set(suits)) == 1 and is_straight:      return '同花顺', points    # 判定是否为顺子    if is_straight:      return '顺子', points    # 判定是否为同花    if len(set(suits)) == 1:      return '同花', points    # 判定是否为对子    if points == points or points == points or points == points:      return '对子', points    # 否则为单张    return '单张', points# 定义牌型优先级hand_rankings = ['单张', '对子', '顺子', '同花', '同花顺', '豹子']
# 比较两手牌的巨细def compare_hands(player1, player2):    type1, points1 = player1    type2, points2 = player2    # 比较牌型优先级    if hand_rankings.index(type1) > hand_rankings.index(type2):      return 1    elif hand_rankings.index(type1) < hand_rankings.index(type2):      return -1    # 如果牌型雷同,逐个比较点数    for p1, p2 in zip(reversed(points1), reversed(points2)):      if point_rank > point_rank:            return 1      elif point_rank < point_rank:            return -1    # 如果点数雷同,结果为平局    return 0# 计算每个玩家的牌型player_hands = {player: poker_type(cards) for player, cards in player_poker.items()}# 找出最大牌winner = max(player_hands.items(), key=lambda item: (hand_rankings.index(item),                                                    for point in item]))# 打印结果print("\n牌局结果:")
for player, (hand_type, points) in player_hands.items():
    print(f"{player} 的牌型: {hand_type} ({', '.join(points)})")

print(f"赢家是: {winner},牌型: {winner} ({', '.join(winner)})")

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 用Python写炸金花游戏