写了那么久的博客,始于Python爬虫,目前专于Java学习,终于有了属于自己的小窝,欢迎各位访问我的个人网站,未来我们一起交流进步。

在学习《流畅的Python》一书中,第一节 Python 数据类型讲解的过程中,实现了一副扑克牌,代码实现非常简洁。当看完之后,联想到生活中我们玩过的炸金花,便着手设计了程序,用来实现双人炸金花这种游戏模型。

本程序中主要分为三个对象类,Poker 类(扑克牌),Player 类(玩家),Winner 类(游戏取胜机制)。

一、Poker 类(扑克牌)

Card = collections.namedtuple('Card', ['rank', 'suit'])class Poker(MutableSequence):# 扑克牌的相关定义ranks = [str(n) for n in range(2, 11)] + list('JQKA')suits = 'spades hearts diamonds clubs'.split()  # 黑桃,红桃,方块,梅花suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)#黑桃最大,红桃次之,方块再次之,梅花最小def __init__(self):self._cards = [Card(rank, suit) for rank in self.ranksfor suit in self.suits]def __len__(self):return len(self._cards)def __getitem__(self, position):  # 仅仅实现了__getitem__方法,该对象就变成可迭代的return self._cards[position]def __setitem__(self, position, value):self._cards[position] = valuedef __delitem__(self, position):del self._cards[position]def insert(self, position, value):self._cards[position] = value

一副扑克牌有 54 张牌,其中 52 张是正牌,另2张是副牌(大王和小王)。本程序中未涉及到大小王。52 张正牌又均分为 13 张一组,并以黑桃、红桃、梅花、方块四种花色表示各组,每组花色的牌包括从 2-10 以及 J、Q、K、A 标示的 13 张牌。

二、Player 类(玩家)

Own_Poker = collections.namedtuple('Own_Poker', ['id', 'rank', 'suit', 'score'])class Player():'''牌型  豹子:三张同样大小的牌。  顺金:花色相同的三张连牌。  金花:三张花色相同的牌。 顺子:三张花色不全相同的连牌。  对子:三张牌中有两张同样大小的牌。  单张:除以上牌型的牌。'''def __init__(self, id, poker):self.id = idself.poker = poker  #一副扑克牌self.pokers = [] #玩家手中的牌self.type = 0  # 每个人初始都假定为三张毫无关系的牌,也就是扑克牌赢法中的“单张”def set_card_score(self, card):'''按照点数判定扑克牌的大小:param card:扑克牌卡片:return:扑克牌点数大小'''rank_value = Poker.ranks.index(card.rank)suit_values = Poker.suit_valuesreturn rank_value * len(suit_values) + suit_values[card.suit]def sort_card_index(self, rank_index_list):'''通过值减下标的方式分组,如果三个值连续则被分配到同一个g中比如说ll=[3,4,5,7,8],分组时,enumerate(ll)=[(0,3),(1,4),(2,5),(3,7),(4,8)],fun函数值减下标,结果一样的,就归为一组在本程序中,如果是三张连续的扑克牌,则应该是同一个g中,此时返回为Ture,否则为False:param rank_index_list::return:'''fun = lambda x: x[1] - x[0]for k, g in groupby(enumerate(rank_index_list), fun):  # 返回一个产生按照fun进行分组后的值集合的迭代器.if len([v for i, v in g]) == 3:return Truereturn Falsedef judge_type(self):'''玩家随机发完三张牌后,根据扑克牌玩法进行区分,对手中的牌进行判别属于哪种类型:return:'''suit_list = []rank_list = []score_list = []for poker in self.pokers:suit_list.append(poker.suit)rank_list.append(poker.rank)score_list.append(poker.score)rank_index_list = []  # 扑克牌卡片在Poker中rank中的indexfor rank in rank_list:index = self.poker.ranks.index(rank)rank_index_list.append(index)if len(set(rank_list)) == 1:self.type = 5  # 豹子elif len(set(suit_list)) == 1:if self.sort_card_index(rank_index_list):self.type = 4  # 顺金else:self.type = 3  # 金花elif self.sort_card_index(rank_index_list):self.type = 2  # 顺子elif len(set(rank_list)) == 2:self.type = 1  # 对子def play(self):self.judge_type()

每位玩家都有一个名称,用同一副扑克牌,炸金花游戏要求每人手中有三张牌,根据手中的牌,程序初步判断属于哪种牌型,用于后续游戏取胜机制做判断。

三、Winner 类(游戏取胜机制)

class Winner():def __init__(self, player1, player2):self.player1 = player1self.player2 = player2def get_max_card(self, player):'''筛选出三张牌中最大的牌,这里返回的是在ranks中的index:param player::return:'''ranks = Poker.ranksrank_index_list = []  # 扑克牌卡片在Poker中rank中的indexfor poker in player.pokers:index = ranks.index(poker.rank)rank_index_list.append(index)return max(rank_index_list)def get_card_suit(self, player):'''返回扑克牌花色大小:param player::return:'''suit_values = Poker.suit_valuessuit = player.pokers[0].suitreturn suit_values[suit]def get_card_value(self, player):'''当牌型是对子的时候,经过匹配找出是对子的牌和单个的牌,这里返回的是牌的index,便于比较大小:param player::return:'''ranks = Poker.ranksrank_index_dict = {}  # 扑克牌卡片在Poker中rank中的indexrepeat_rank_value = 0  # 成对的两张扑克牌的大小single_rank_value = 0  # 单个的扑克牌的大小for poker in player.pokers:index = ranks.index(poker.rank)if index in rank_index_dict:rank_index_dict[index] += 1else:rank_index_dict[index] = 1rank_index_dict = sorted(rank_index_dict.items(), key=lambda d: d[1], reverse=True)n = 0for key in rank_index_dict:if n == 0:repeat_rank_value = keyelse:single_rank_value = keyn += 1return repeat_rank_value, single_rank_valuedef get_player_score(self, player):'''当牌型为单牌时,计算手中的牌相加后的值大小:param player::return:'''ranks = Poker.ranksscore = 0for poker in player.pokers:index = ranks.index(poker.rank)  # 扑克牌卡片在Poker中rank中的indexscore += indexreturn scoredef get_winner(self):player1, player2 = self.player1, self.player2# 先比较玩家手中的牌型,大的胜出,玩牌的规则暂时不涉及到牌色,如有修改可以在此基础上调整# 豹子> 顺金 > 金花 > 顺子 > 对子 > 单张if player1.type > player2.type:return player1elif player1.type < player2.type:return player2else:  # 当玩家双方手中的牌型一致时,根据赢法一一判断if player1.type == 5 or player1.type == 4 or player1.type == 2:  # 豹子、顺金、顺子 规则说明:按照比点if self.get_max_card(player1) > self.get_max_card(player2):return player1else:return player2elif player1.type == 1:  # 对子 规则说明:先比较相同两张的值的大小,谁大谁胜出;如果对子相同,再比较单个repeat_rank_value1, single_rank_value1 = self.get_card_value(player1)repeat_rank_value2, single_rank_value2 = self.get_card_value(player1)if repeat_rank_value1 > repeat_rank_value2:return player1elif repeat_rank_value1 < repeat_rank_value2:return player2else:if single_rank_value1 > single_rank_value2:return player1elif single_rank_value1 < single_rank_value2:return player2else:return None  # 平局,大家手上的牌一样大else:  # 单牌,金花   规则:比较所有牌的点数大小,不区分牌色if self.get_player_score(player1) > self.get_player_score(player2):return player1elif self.get_player_score(player1) < self.get_player_score(player2):return player2else:return None

由于不是很清楚炸金花的游戏规则,这里我们采用的是最简单的游戏规则。

牌型 豹子:三张同样大小的牌。顺金:花色相同的三张连牌。金花:三张花色相同的牌。 顺子:三张花色不全相同的连牌。 对子:三张牌中有两张同样大小的牌。单张:除以上牌型的牌。

玩法比较简单,豹子> 顺金 > 金花 > 顺子 > 对子 > 单张,当牌型不一致的话,谁牌型大谁胜出;当牌型一致的时候,又分为三种情况,一是豹子、顺金、顺子,比较玩家手中牌的最大值,谁拥有最大牌面值谁胜出;二是对子,比较玩家手中对子的牌面大小,如果相同再另行比较;三是金花、单张,比较玩家手中所有牌面大小之和。

除了上述三个对象类外,还需要一个发牌者(荷官)来主持洗牌和发牌。

def compare_card(card1, card2):'''比较两种扑克牌是否相同:param card1::param card2::return: 相同返回为True,否则为False'''if card1.rank == card2.rank and card1.suit == card2.suit:return Truereturn Falsedef dutch_official_work(poker, player1, player2):'''发牌人(荷官)给两位玩家轮替发牌,发出去的牌都需要从这副扑克牌中剔除出去:param poker: 那一副扑克牌:param player1:玩家1:param player2:玩家2:return:整理后的扑克牌'''def distribute_card(player):card = choice(poker)  # 发牌player.pokers.append(Own_Poker(player.id, card.rank, card.suit, player.set_card_score(card)))for i in range(len(poker)):if compare_card(card, poker[i]):poker.__delitem__(i)breakshuffle(poker)  # 洗牌for k in range(3):distribute_card(player1)distribute_card(player2)return poker

总结:多看,多想,多动手。纸上得来终觉浅,绝知此事要躬行。
对了,详细代码可以访问 https://github.com/Acorn2/fluentPyStudy/blob/master/chapter01/Poker_Demo.py

用 Python 打扑克牌——炸金花相关推荐

  1. 用python开发一个炸金花小游戏,注意别玩上瘾了

    扑克牌可谓是居家旅行.桌面交友的必备道具,今天我们用 Python 来实现一个类似炸金花的扑克牌小游戏,先来看一下基本的游戏规则. 炸(诈)金花又叫三张牌,是在全国广泛流传的一种民间多人纸牌游戏.游戏 ...

  2. 熬了三个大夜利用Python开发一个炸金花小游戏,注意别玩上瘾了~~(附完整源码)

    大家好,我是你们的好朋友王老师~ 众所周知扑克牌可谓是居家旅行.桌面交友的必备道具,今天我们用 Python 来实现一个类似炸金花的扑克牌小游戏,先来看一下基本的游戏规则. 炸(诈)金花又叫三张牌, ...

  3. Python开发一个炸金花小游戏,注意别玩上瘾了

    众所周知扑克牌可谓是居家旅行.桌面交友的必备道具,今天我们用 Python 来实现一个类似炸金花的扑克牌小游戏,先来看一下基本的游戏规则. 炸(诈)金花又叫三张牌,是在全国广泛流传的一种民间多人纸牌 ...

  4. python开发的炸金花小游戏来啦,从此不再无聊~

    哈喽~大家好,我是恰恰!大家今天应该都已经开工了,很多同学过年的时候都是在牌桌上度过的吧哈哈,所以今天给大家带来一个用Python开发的扎金花的小游戏,又可以学习又可以玩,趣味性学习没错了!快来看看吧 ...

  5. 用python开发一个炸金花小游戏,注意别玩上瘾了~~

    众所周知扑克牌可谓是居家旅行.桌面交友的必备道具,今天我们用 Python 来实现一个类似炸金花的扑克牌小游戏,先来看一下基本的游戏规则. 炸(诈)金花又叫三张牌,是在全国广泛流传的一种民间多人纸牌 ...

  6. 用python开发一个炸金花小游戏,注意别玩上瘾了~~(附完整源码)

    大家好,我是辰哥~ 众所周知扑克牌可谓是居家旅行.桌面交友的必备道具,今天我们用 Python 来实现一个类似炸金花的扑克牌小游戏,先来看一下基本的游戏规则. 炸(诈)金花又叫三张牌,是在全国广泛流 ...

  7. Python写的炸金花程序(含有特殊牌,可供2-17人重复玩耍)

    下面附上运行示例  输入1可再来一局 输入2可退出程序 下面附上源码,游戏规则在源码最后 import random#生成一副扑克牌,除去大小王 poker1=[2,3,4,5,6,7,8,9,10, ...

  8. Python解炸金花问题

    Python解炸金花问题 炸金花小游戏 游戏规则: 整体代码 炸金花小游戏 -要求: 编写炸金花游戏程序 自己写一个程序,实现发牌.比大小判断输赢. 游戏规则: 一付扑克牌,去掉大小王,每个玩家发3张 ...

  9. 用Python写炸金花代码,学习python语言精品案例

    以下代码对于练习python相关的条件循环语句.自定义函数及函数调用.列表.字典.变量运算.基本逻辑等的练习很有帮助,特别是如何使用python语言解决实际问题的思路,且具有一定趣味性,对于Pytho ...

最新文章

  1. 2021年大数据Spark(三十九):SparkStreaming实战案例四 窗口函数
  2. android原生跳转到外网
  3. 清理恶意插件提高上网速度
  4. 纪中2018暑假培训day3提高a组改题记录(混有部分b组)
  5. js文章QQ空间分享
  6. 在linux中which命令,Linux 中 which 命令怎么用?
  7. 因为apple无法检查其是否包含恶意软件_新Linux恶意脚本——清理其他恶意软件后再感染...
  8. H5页面适配iOS、Android和微信
  9. 兼容IE和FF:获取Referer的JS和PHP方法 及 PHP利用curl伪造IP和来路
  10. 3.8 RIPv2的认证机制
  11. Android蓝牙电话(SCO)和蓝牙音乐(A2DP)总结(四)
  12. 编译出错:self-encoder.context-me_method = ME_UMH;
  13. 【优化算法】孪生支持向量机(TWSVM)【含Matlab源码 1257期】
  14. 算法的时间复杂度与空间复杂度
  15. resnet34\resnet101网络结构图
  16. WPS 表格中单元格文字后插入公式
  17. 模拟停车场管理系统(栈和队列的应用)
  18. 我们都是穷人甲乙丙丁
  19. 2023款16英寸苹果MacBook Pro续航实测
  20. 图片 bmp 格式详解

热门文章

  1. XSS漏洞的原理与测试解决方案笔记
  2. linux如何查看系统停机日志,linux系统中如何查看日志
  3. 网易嵌入式面试 2015年8月19日晚网易电话面试
  4. 第八章 win10+gsoap+onvif+ffmpeg
  5. 网络常见面试题总结(四)
  6. 世界杯:用Python分析热门夺冠球队
  7. (Java高级程序设计-案例)-通过JDBC连接MySQL并对表进行增、删、改、查
  8. Phillip and Trains(dfs专题)
  9. 腾讯云服务器java搭建教程_腾讯云服务器搭建
  10. 360buy android 首页打开网络监控数据分析