用Python写炸金花游戏

打印 上一主题 下一主题

主题 802|帖子 802|积分 2406

以卑鄙戏规则:


那么我们要实现的功能,就是以下几个:

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

代码分解与讲授

1. 扑克牌的生成与洗牌

  1. suit_cards = ['黑桃', '红桃', '方块', '梅花']  # 花色
  2. check_number = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']  # 点数
  3. # 嵌套循环生成扑克牌
  4. # poker_list = [f"{suit}{check}" for suit in suit_cards for check in check_number]
  5. poker_list = []
  6. for suit in suit_cards:
  7.     for check in check_number:
  8.         poker_list.append(f"{suit}{check}")
  9. random.shuffle(poker_list)  # 洗牌
复制代码
功能


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

    • 比方,“黑桃2”、“红桃A” 等。

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

2. 给玩家发牌

  1. player = ['player1', 'player2', 'player3', 'player4', 'player5']  # 玩家列表
  2. # player_poker = {p: [] for p in player}  # 初始化每个玩家的手牌为空列表(字典推导式)
  3. player_poker = {}  # 初始化一个空字典
  4. for p in player:  # 遍历每个玩家
  5.     player_poker[p] = []  # 为每个玩家赋值一个空列表,表示其手牌,player_poker是个字典,键是用户,列表是值(也就是玩家手牌)
  6. # 确保牌的数量足够分发
  7. if len(poker_list) < len(player) * 3:
  8.     raise ValueError("牌堆中牌的数量不足以分发给所有玩家!")
  9. # 每人发三张牌
  10. for i in range(3):  # 每人发3轮
  11.     for p in player:       # 嵌套循环,player中有5个,一共循环15次
  12.         poker = poker_list.pop()  # 从牌堆顶部发一张牌
  13.         player_poker[p].append(poker)
复制代码
功能

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

3. 打印玩家的手牌

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


  • 将每名玩家的手牌以字符串形式打印出来,方便观察。
  • .join() 是一个字符串方法,用于将列表中的元素用指定的字符串毗连起来。
  • ', '.join(pokers) 会将列表中的元素用逗号加空格(, )毗连成一个字符串:
  1. ', '.join(['黑桃A', '红桃K', '方块Q'])  # 结果: '黑桃A, 红桃K, 方块Q'
复制代码
输出示例:
  1. player1的牌是:黑桃K, 方块Q, 红桃A
  2. player2的牌是:梅花7, 黑桃8, 红桃10
  3. ...
复制代码

4. 定义牌的优先级

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


  • point_rank:定义点数的巨细,数值越大点数越高。比方,“A” 的优先级最大,值为 14。
    1. {'2': 2, '3': 3, ..., 'K': 13, 'A': 14}
    复制代码

5. 判定牌型

  1. def poker_type(cards):  #这个cards是列表,也就是前面键值对中的值
  2.     points = sorted([card[2:] for card in cards], key=lambda x: point_rank[x])  # 提取点数并按大小排序
  3.     suits = [card[:2] for card in cards]  # 提取花色(列表推导式),索引前两个字符
  4.     # 判断是否为豹子
  5.     if points[0] == points[1] == points[2]:
  6.         return '豹子', points
  7.     # 判断是否为同花顺
  8.     is_straight = (point_rank[points[2]] - point_rank[points[1]] == 1 and \
  9.                    point_rank[points[1]] - point_rank[points[0]] == 1) or points == ['2', '3', 'A']
  10.     if len(set(suits)) == 1 and is_straight:   # len(set(suit))==1判断一个列表或字符串中的所有元素是否相同
  11.         return '同花顺', points
  12.     # 判断是否为顺子
  13.     if is_straight:
  14.         return '顺子', points
  15.     # 判断是否为同花
  16.     if len(set(suits)) == 1:
  17.         return '同花', points
  18.     # 判断是否为对子
  19.     if points[0] == points[1] or points[1] == points[2] or points[0] == points[2]:
  20.         return '对子', points
  21.     # 如果都不是,返回单张
  22.     return '单张', points
复制代码
功能
根据玩家的三张牌,判定牌型并返回 牌型名称点数列表

  • 豹子:三张点数雷同。
  • 同花顺:花色雷同,点数连续。
  • 顺子:点数连续(但花色不肯定雷同)。
  • 同花:花色雷同(但点数不肯定连续)。
  • 对子:两张牌点数雷同。
  • 单张:既不连续,也不同花或对子。

6. 确定牌型优先级

  1. hand_rankings = ['单张', '对子', '顺子', '同花', '同花顺', '豹子']
复制代码
功能


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

    • 单张 < 对子 < 顺子 < 同花 < 同花顺 < 豹子。


7. 比较两手牌的巨细

  1. def compare_hands(player1, player2):
  2.     type1, points1 = player1
  3.     type2, points2 = player2
  4.     # 比较牌型优先级
  5.     if hand_rankings.index(type1) > hand_rankings.index(type2):
  6.         return 1
  7.     elif hand_rankings.index(type1) < hand_rankings.index(type2):
  8.         return -1
  9.     # 如果牌型相同,逐个比较点数
  10.     for p1, p2 in zip(reversed(points1), reversed(points2)):
  11.         if point_rank[p1] > point_rank[p2]:
  12.             return 1
  13.         elif point_rank[p1] < point_rank[p2]:
  14.             return -1
  15.     # 如果点数相同
  16.     return 0
复制代码
功能


  • 先比较两手牌的牌型优先级,优先级高者胜。
  • 如果牌型雷同,逐一比较点数,由高到低比较。

8. 计算每个玩家的牌型并找出赢家

  1. player_hands = {player: poker_type(cards) for player, cards in player_poker.items()}
  2. winner = max(player_hands.items(), key=lambda item: (hand_rankings.index(item[1][0]), item[1][1]))
复制代码
功能

  • 遍历每名玩家的手牌,计算牌型。
  • 使用 max 函数,根据牌型优先级和点数巨细,找出赢家。

9. 打印结果

  1. print("\n牌局结果:")
  2. for player, (hand_type, points) in player_hands.items():
  3.     print(f"{player} 的牌型: {hand_type} ({', '.join(points)})")
  4. print(f"赢家是: {winner[0]},牌型: {winner[1][0]} ({', '.join(winner[1][1])})")
复制代码
功能


  • 输出每名玩家的牌型和点数。
  • 输出赢家及其牌型。
输出示例:
  1. player1 的牌型: 顺子 (10, J, Q)
  2. player2 的牌型: 对子 (8, 8, K)
  3. player3 的牌型: 单张 (7, 9, A)
  4. player4 的牌型: 同花 (4, 6, J)
  5. player5 的牌型: 豹子 (K, K, K)
  6. 赢家是: player5,牌型: 豹子 (K, K, K)
复制代码

完整代码

  1. import random# 定义扑克牌花色和点数suit_cards = ['黑桃', '红桃', '方块', '梅花']check_number = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']# 生成扑克牌poker_list = [f"{suit}{check}" for suit in suit_cards for check in check_number]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[p].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([card[2:] for card in cards], key=lambda x: point_rank[x])    suits = [card[:2] for card in cards]    # 判定是否为豹子    if points[0] == points[1] == points[2]:        return '豹子', points    # 判定是否为同花顺    is_straight = (point_rank[points[2]] - point_rank[points[1]] == 1 and \                   point_rank[points[1]] - point_rank[points[0]] == 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[0] == points[1] or points[1] == points[2] or points[0] == points[2]:        return '对子', points    # 否则为单张    return '单张', points# 定义牌型优先级hand_rankings = ['单张', '对子', '顺子', '同花', '同花顺', '豹子']
  2. # 比较两手牌的巨细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[p1] > point_rank[p2]:            return 1        elif point_rank[p1] < point_rank[p2]:            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[1][0]),                                                     [point_rank[point] for point in item[1][1]]))# 打印结果print("\n牌局结果:")
  3. for player, (hand_type, points) in player_hands.items():
  4.     print(f"{player} 的牌型: {hand_type} ({', '.join(points)})")
  5. print(f"赢家是: {winner[0]},牌型: {winner[1][0]} ({', '.join(winner[1][1])})")
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

耶耶耶耶耶

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表