以卑鄙戏规则:
那么我们要实现的功能,就是以下几个:
- 生成扑克牌。
- 随机洗牌并分发给五名玩家,每人三张牌。
- 判定每位玩家的牌型(比方:豹子、同花顺等)。
- 比较五名玩家的牌型,得出赢家。
代码分解与讲授
1. 扑克牌的生成与洗牌
- 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 张)。
- 使用 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[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)
复制代码 功能:
- 初始化 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([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
复制代码 功能:
根据玩家的三张牌,判定牌型并返回 牌型名称 和 点数列表。
- 豹子:三张点数雷同。
- 同花顺:花色雷同,点数连续。
- 顺子:点数连续(但花色不肯定雷同)。
- 同花:花色雷同(但点数不肯定连续)。
- 对子:两张牌点数雷同。
- 单张:既不连续,也不同花或对子。
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[p1] > point_rank[p2]:
- return 1
- elif point_rank[p1] < point_rank[p2]:
- 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[1][0]), item[1][1]))
复制代码 功能:
- 遍历每名玩家的手牌,计算牌型。
- 使用 max 函数,根据牌型优先级和点数巨细,找出赢家。
9. 打印结果
- 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 = 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牌局结果:")
- 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])})")
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |