用Python写炸金花游戏

ops/2024/12/27 23:14:21/

文章目录

      • **代码分解与讲解**
        • 1. **扑克牌的生成与洗牌**
        • 2. **给玩家发牌**
        • 3. **打印玩家的手牌**
        • 4. **定义牌的优先级**
        • 5. **判断牌型**
        • 6. **确定牌型优先级**
        • 7. **比较两手牌的大小**
        • 8. **计算每个玩家的牌型并找出赢家**
        • 9. **打印结果**
      • 完整代码

以下游戏规则:


在这里插入图片描述
那么我们要实现的功能,就是以下几个:

  1. 生成扑克牌。
  2. 随机洗牌并分发给五名玩家,每人三张牌。
  3. 判断每位玩家的牌型(例如:豹子、同花顺等)。
  4. 比较五名玩家的牌型,得出赢家。

代码分解与讲解

1. 扑克牌的生成与洗牌
python">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]
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. 给玩家发牌
python">player = ['player1', 'player2', 'player3', 'player4', 'player5']  # 玩家列表
# player_poker = {p: [] for p in player}  # 初始化每个玩家的手牌为空列表(字典推导式)
player_poker = {}  # 初始化一个空字典
for p in player:  # 遍历每个玩家player_poker[p] = []  # 为每个玩家赋值一个空列表,表示其手牌,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[p].append(poker)

功能

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

3. 打印玩家的手牌
python">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. 定义牌的优先级
python">point_rank = {point: i for i, point in enumerate(check_number, start=2)}  # 字典推导式(i,point)对

这里解释一下:point是键,i是值, 可以去看一下字典推导式的结构组成
功能

  • point_rank:定义点数的大小,数值越大点数越高。例如,“A” 的优先级最大,值为 14。
    python">{'2': 2, '3': 3, ..., 'K': 13, 'A': 14}
    

5. 判断牌型
python">def poker_type(cards):  #这个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:   # len(set(suit))==1判断一个列表或字符串中的所有元素是否相同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

功能
根据玩家的三张牌,判断牌型并返回 牌型名称点数列表

  1. 豹子:三张点数相同。
  2. 同花顺:花色相同,点数连续。
  3. 顺子:点数连续(但花色不一定相同)。
  4. 同花:花色相同(但点数不一定连续)。
  5. 对子:两张牌点数相同。
  6. 单张:既不连续,也不同花或对子。

6. 确定牌型优先级
python">hand_rankings = ['单张', '对子', '顺子', '同花', '同花顺', '豹子']

功能

  • 定义牌型的优先级,牌型从低到高依次为:
    • 单张 < 对子 < 顺子 < 同花 < 同花顺 < 豹子。

7. 比较两手牌的大小
python">def compare_hands(player1, player2):type1, points1 = player1type2, points2 = player2# 比较牌型优先级if hand_rankings.index(type1) > hand_rankings.index(type2):return 1elif 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 1elif point_rank[p1] < point_rank[p2]:return -1# 如果点数相同return 0

功能

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

8. 计算每个玩家的牌型并找出赢家
python">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]), item[1][1]))

功能

  1. 遍历每名玩家的手牌,计算牌型。
  2. 使用 max 函数,根据牌型优先级和点数大小,找出赢家。

9. 打印结果
python">print("\n牌局结果:")
for player, (hand_type, points) in player_hands.items():print(f"{player} 的牌型: {hand_type} ({', '.join(points)})")print(f"赢家是: {winner[0]},牌型: {winner[1][0]} ({', '.join(winner[1][1])})")

功能

  • 输出每名玩家的牌型和点数。
  • 输出赢家及其牌型。

输出示例:

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 = [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 = ['单张', '对子', '顺子', '同花', '同花顺', '豹子']# 比较两手牌的大小
def compare_hands(player1, player2):type1, points1 = player1type2, points2 = player2# 比较牌型优先级if hand_rankings.index(type1) > hand_rankings.index(type2):return 1elif 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 1elif 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牌局结果:")
for player, (hand_type, points) in player_hands.items():print(f"{player} 的牌型: {hand_type} ({', '.join(points)})")print(f"赢家是: {winner[0]},牌型: {winner[1][0]} ({', '.join(winner[1][1])})")

http://www.ppmy.cn/ops/144771.html

相关文章

一文了解多云原生的现代化实时数仓 SelectDB Cloud

随着数字化转型的加速&#xff0c;云计算已成为现代企业运营中的关键组成部分。云的重要性体现在多个方面&#xff1a;首先&#xff0c;它提供更好的灵活性与可扩展性&#xff0c;可根据实际需求动态调整计算和存储资源&#xff0c;以快速适应市场变化并支持业务增长。其次&…

【网络云计算】2024第51周-每日【2024/12/20】小测-理论-周测

文章目录 1、软件RAID的常用级别和硬件RAID的区别&#xff0c;制作RAID生产环境有哪些注意事项2、交换机常用的技术有哪些3、NFS服务器如何结合LVM4、写两个if语句&#xff0c;判断文件和目录是否存在5、链路聚合和VRRP有哪些区别&#xff1f; 【网络云计算】2024第51周-每日【…

Axure RP 8安装(内带安装包)

通过网盘分享的文件&#xff1a;Axure8.0.zip 链接: https://pan.baidu.com/s/195_qy2iiDIcYG4puAudScA 提取码: 6xt8 --来自百度网盘超级会员v1的分享 勾选I Agree 安装完成

《向量数据库指南》——Milvus Cloud 2.5:Sparse-BM25引领全文检索新时代

Milvus Cloud BM25:重塑全文检索的未来 在最新的Milvus Cloud 2.5版本中,我们自豪地引入了“全新”的全文检索能力,这一创新不仅巩固了Milvus Cloud在向量数据库领域的领先地位,更为用户提供了前所未有的灵活性和效率。作为大禹智库的向量数据库高级研究员,以及《向量数据…

可视化大屏编辑器, 开源!

hi, 大家好, 我是徐小夕. 5年前就开始着手设计和研发可视化大屏编辑器, 当时低代码在国内还没有现在那么火, 有人欢喜有人哀, 那个时候我就比较坚定的认为无码化搭建未来一定是个趋势, 能极大的帮助企业提高研发效率和降低研发成本, 所以 all in 做了2年, 上线了一个相对闭环的…

汽车IVI中控开发入门及进阶(41):视频播放器MPlayer

版本: MPlayer 1.5 2022年已发布。 MPlayer 1.5与最新FFmpeg版本(5.0)和当前FFmpeg开发版本(FFmpeg master)兼容。tarball已经包含一个FFmpeg快照,因此不需要单独获取它。如果想遵循MPlayer和FFmpeg的最新改进,强烈建议你使用开发版本。 MPlayer - The Movie Playerht…

DevEco Studio支持鸿蒙应用的全生命周期开发

DevEco Studio支持鸿蒙应用的全生命周期开发 一、引言 随着科技的发展&#xff0c;软件开发流程日益复杂&#xff0c;从最初的概念到最终的产品发布和后续维护&#xff0c;涉及多个阶段。对于移动操作系统而言&#xff0c;其应用开发工具链的支持尤为关键。HarmonyOS&#xf…

贪心算法求解加油站问题

代码随想录链接:代码随想录 思路: 首先构造一个差距数组diff&#xff0c;其中每个位置的值都是gas数组和cost数组对应位置的值的差 初始化一个变量start记录从哪个加油站出发&#xff0c;一个变量cursum记录从start出发时车内油量的总和&#xff0c;一个变量totsum表示整个差…