自己写一个程序,实现发牌、比大小判断输赢。

#### 游戏规则

一付扑克牌,去掉大小王,每个玩家发3张牌,最后比大小,看谁赢。

有以下几种牌:

豹子:三张一样的牌,如3张6.

顺金:又称同花顺,即3张同样花色的顺子, 如红桃 5、6、7

顺子:又称拖拉机,花色不同,但是顺子,如红桃5、方片6、黑桃7,组成的顺子

对子:2张牌一样

单张:单张最大的是A

这几种牌的大小顺序为, **豹子>顺金>顺子>对子>单张**

#### 需程序实现的点

1. 先生成一付完整的扑克牌

2. 给5个玩家随机发牌

3. 统一开牌,比大小,输出赢家是谁

目录

讲解思路:

步骤一:初始化牌组列表及玩家列表

步骤二:模拟发牌

效果展示(运行过程中会有停顿感以模拟真实发牌):

步骤三:判断输赢

类Player补充的函数:

完整代码:

效果展示:


讲解思路:

首先,需要实现两个类:扑克牌Card和玩家Player,然后确定它们的基本属性。

# 定义一个Card类,由牌面和花色初始化
class Card:def __init__(self, face="", color=""):self.face = face                # 牌面,字符串类型self.color = color              # 花色,字符串类型self.name = color + face        # 牌的完整名称self.prior1 = PRIORITY[face]     # 牌面对应的优先级self.prior2 = PRIORITY[color]     # 牌花色对应的优先级

对于扑克牌Card类:牌面、花色、完整名称属性应该很好理解, prior1和prior2主要是对应牌面和花色的优先级,这2个属性是方便比较牌Card对象的大小。所有优先级对应如下:

# PRIORITY数组用于比较牌面值,花色,牌型的优先级
# A>K>Q>...>2
# 黑桃>红心>方块>梅花
# 豹子>顺金>顺子>对子>单张
PRIORITY = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8,'9': 9, '10': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14,'梅花♣': 1, '方块♦': 2, '红心♥': 3, '黑桃♠': 4,'单张': 1, '对子': 2, '顺子': 3, '顺金': 4, '豹子': 5}
# 定义一个Player类,由玩家姓名初始化
class Player:def __init__(self, name=""):self.card = list()      # 玩家拥有的牌存储在card里面,元素类型为Cardself.name = name        # 玩家姓名self.type = ''          # 牌型self.winner = False     # 标志,记录该玩家是否是最后的赢家self.pair = 0           # 记录第一张对子牌的索引,默认为0

对于玩家Player类:玩家姓名name、牌组card属性应该很好理解, 牌型type指定玩家牌属于顺子,豹子等等,winner属性记录玩家是否是赢家,pair记录对子牌的索引。

这个游戏过程我们分为三个步骤,第一步是初始化;第二步是模拟发牌;第三步是判断输赢。

步骤一:初始化牌组列表及玩家列表

此处定义多个全局变量:(牌面有13种情况,花色有4种情况,牌型有5种情况,玩家有5位)

# 分别定义全局变量:牌面值,花色,牌型,玩家姓名
FACES = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
COLORS = ['黑桃♠', '红心♥', '方块♦', '梅花♣']
TYPE = ['豹子', '顺金', '顺子', '对子', '单张']
NAMES = ['#Player1', '#Player2', '#Player3', '#Player4', '#Player5']

我们需要两个列表来存储52张牌以及5位玩家,列表元素分别是Card对象和Player对象

# 牌组列表初始化为空,玩家组列表初始化为空
CARD_GROUP = list()
PLAYERS = list()

准备工作做好了,接下来填充列表:

# 输入:无
# 输出:无
# 功能:初始化52张的扑克牌列表,即生成一副完整的牌,然后初始化玩家列表
def init():CARD_GROUP.clear()  # 清空牌组列表for f in FACES:  # 遍历牌面值for c in COLORS:  # 遍历花色CARD_GROUP.append(Card(f, c))  # 添加扑克牌for name in NAMES:  # 初始化玩家列表PLAYERS.append(Player(name))  # 添加玩家

步骤二:模拟发牌

直接说思路:每次从列表CARD_GROUP随机抽取一张牌发给玩家,此牌再从牌组中移除。

# 输入:无
# 输出:无
# 功能:实现发牌
def deal():# 因为每人需要发三张牌,所以用三次循环实现# 模拟随机发牌过程:每次随机抽取一张牌,然后从列表移除circle = 3for i in range(circle):print('第{0}轮发牌:'.format((i + 1)), end='\t')for p in PLAYERS:temp = random.choice(CARD_GROUP)        # 随机抽牌CARD_GROUP.remove(temp)                 # 从牌组移除这张牌p.card.append(temp)                     # 将牌加入玩家的card列表里面time.sleep(0.7)                         # 体现发牌停顿感,暂停0.7sprint(temp.name, end='\t\t')            # 打印牌名称print()print()

效果展示(运行过程中会有停顿感以模拟真实发牌):

步骤三:判断输赢

这个过程中,我们要分两个小过程,首先是判断玩家手中的牌型,把他们分类;然后比较同种牌型下的牌组大小。

1. 判断牌型,这个函数作为Player类的成员函数实现:

    def judge_type(self):                   # 判断牌型,这个过程中,若出现对子类型的牌,则更新属性self.pairself.card.sort(reverse=True)        # 对玩家的牌按照优先级从大到小排序cards = self.cardif cards[0].prior1 == cards[1].prior1 and cards[0].prior1 == cards[2].prior1:self.type = '豹子'elif cards[0].prior1-cards[1].prior1 == 1 and cards[1].prior1-cards[2].prior1 == 1:if cards[0].prior2 == cards[1].prior2 and cards[0].prior2 == cards[2].prior2:self.type = '顺金'else:self.type = '顺子'elif cards[0].prior1 == cards[1].prior1:self.type = '对子'elif cards[1].prior1 == cards[2].prior1:        # 排序过后,若出现对子牌,那么它们必定连在一起,所以其实索引0和2不用比较self.type = '对子'self.pair = 1else:self.type = '单张'

2. 接下来是“重头戏”:怎么比较玩家手中牌的大小呢?

首先,我们知道有个库函数sort(),用于对原列表进行排序,如果指定参数,则使用比较函数指定的比较函数。语法如下:

list.sort( key=None, reverse=False)

仔细分析炸金花游戏的比较过程:首先对于玩家比如说张三手中的牌,需要对这三张牌进行比较,这是第一个排序;然后对于同种牌型的玩家,比如两个人都是对子牌,需要对玩家进行比较,这是第二个排序。像这种对《类对象数组的排序》,有基础的童鞋应该有思路了:实现一个内置函数cmp,然后调用库函数sort就可以了。一开始我以为是重写类的__cmp__()函数,查了半天发现是重写__lt__()函数,其实就是重写<号。这个游戏需要重写两个类的__lt__函数,如下:

    def __lt__(self, other):            # 此处重写Card类的'<'符号,先比较牌面,再比较花色,当调用sort函数时,其会自动采用该内置函数比较if self.prior1 == other.prior1:return self.prior2 <= other.prior2else:return self.prior1 < other.prior1def __lt__(self, other):    # 此处重写Player类的'<'符号,先比较牌型,再比较每张牌,当调用sort函数时,其会自动采用该内置函数比较n = len(self.card)if PRIORITY[self.type] == PRIORITY[other.type]:     # 若牌型相同,则比较牌大小。注意:对子牌型需要先比对,再比单。for i in range(n):index = (self.pair + i) % n                     # 0,1,2或者是1,2,0比较if self.card[index] != other.card[index]:return self.card[index] < other.card[index]# 循环外这种情况是,玩家所有牌全部一样,也返回True。# 当然,看花色的情况下,第一张牌就可以比较出玩家输赢return Trueelse:return PRIORITY[self.type] < PRIORITY[other.type]

类Player补充的函数:

info函数:用于输出玩家的姓名,牌信息,是否是赢家

    def info(self):print(self.name, end='\t')          # 输出玩家姓名for c in self.card:                 # 输出牌面print(c.name, end='\t')if not self.winner:                 # 若不是赢家,则只用输出牌型print(self.type)else:                               # 若是赢家,则还要加上庆祝语print(self.type, '\tWinner! 												

Python3编写炸金花游戏--超详细的讲解!!相关推荐

  1. 详细的Python炸金花游戏代码

    ** 详细的Python炸金花游戏代码 ** 觉得有用请点个赞吧 #!/usr/bin/env python # -*- coding: utf-8 -*- ''' # @Time: 2022/07/ ...

  2. 飞机大战小游戏(超详细)

    偷学Python之最后的项目二:飞机大战小游戏(超详细) 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志.--苏轼 甜甜先说 这次用Python中的pygame模块来完成一个飞机大战的小游戏:基本思 ...

  3. 炸金花游戏(4)--炸金花AI基准测试评估

    前言: 本文将谈谈如何评估测试炸金花的AI, 其实这个也代表一类的问题, 德州扑克也是类似的解法. 本文将谈谈两种思路, 一种是基于基准AI对抗评估, 另一种是基于测试集(人工选定牌谱). 由于炸金花 ...

  4. 炸金花游戏(1)--炸金花游戏的模型设计和牌力评估

    前言: 好久没写博客了, 今天来补上一篇, 是关于炸金花游戏模型的设计和牌力评估. 其核心思想和之前谈到过的德州模型很像, 本文也想为炸金花游戏这个系列开个头, 希望后面能写写AI相关的文章. 相关文 ...

  5. Python实现炸金花游戏的示例代码

    本文主要介绍了Python实现炸金花游戏的示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下.编程学习资料点击领取. 今天的第二个作品,哈哈哈哈,搞起来感觉还挺 ...

  6. 炸金花游戏(2)--炸金花游戏的胜率预估

    前言: 我也是突然心血来潮, 想写写炸金花这类游戏的AI实现. 本文算是这一系列的第二篇, 主要写炸金花的胜率预估, 主要基于蒙特卡罗的思想, 胜率是炸金花AI的核心决策数据, ^_^. 相关文章: ...

  7. 使用anaconda配置python3.6环境安装pyltp超详细教程,使用pycharm调用

    使用anaconda配置python3.6环境安装pyltp超详细教程,使用pycharm调用 看了一堆网上的安装教程,有的写得太简单,有的太复杂,本菜鸡根本看不懂在说什么,看了好几篇才整明白是怎么回 ...

  8. 炸金花游戏(3)--基于EV(期望收益)的简单AI模型

    前言: 炸金花这款游戏, 从技术的角度来说, 比德州差了很多. 所以他的AI模型也相对简单一些. 本文从EV(期望收益)的角度, 来尝试构建一个简单的炸金花AI. 相关文章: 德州扑克AI--Prog ...

  9. php金花游戏,PHP实现炸金花游戏比赛

    这篇文章主要介绍了PHP实现炸金花游戏比赛的方法,实例分析了炸金花游戏的实现原理与相关算法技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了PHP实现炸金花游戏比赛的方法.具体分析如下: ...

  10. 炸金花游戏(5)--动态收敛预期胜率的一种思路

    前言: 前面几篇炸金花的文章, 里面涉及到了一个核心问题, 就是如何实现对手的牌力提升, 以及胜率的动态调整. 这个问题是EV模型, 以及基准AI里最重要的核心概念之一. 本文将尝试实现一个版本, 望 ...

最新文章

  1. Hadoop详解(八):MapReduce深度分析
  2. selenium2与python自动化1-selenium简介与降级
  3. boost::multiprecision模块实现打印出所有的阶乘 这将适合一个 128 位整数相关的测试程序
  4. Node.js 初识 fs 模块
  5. matlab2012生成dll,64位win7下vc2010如何調用matlab2012a中生成的dll文件
  6. 使用pp架构形成计算机集群请求的地址无效_干货!史上最详细脑图《大型网站技术架构》...
  7. 六个超大规模Hadoop(前景)
  8. 11个优秀PHP开发框架-专门为开发人员准备
  9. 【转】mysql数据库中实现内连接、左连接、右连接
  10. 电力系统分析—潮流计算代码Python编程练习(基于极坐标形式的常规牛拉法)
  11. java jco_JAVA通过JCo连接SAP
  12. Python 使用openpyxl处理Excel文件
  13. VC++程序设计与应用--菜单、工具栏与状态栏
  14. JavaScript制作日历
  15. (一)C++游戏开发-本地存储-介绍
  16. 快手适合在美妆行业做广告投放吗?快手广告如何计费?
  17. 基于Openwrt 拨号上网(SDX55) (PCIe)移植文档
  18. Niagara N4 与物联网的学习经验分享(一 New Station)
  19. 截图与贴图神器:Snipaste
  20. 微信云服务器发长视频朋友圈,今天才知道,微信朋友圈还能发5分钟长视频,超简单,一看就会...

热门文章

  1. Linux vim 编辑文件底部显示[converted]解决办法
  2. 12 个组织良好的网络监控工具
  3. 闪存驱动器_什么是闪存驱动器?
  4. java怎么重新开始游戏_添加开始,停止,重置按钮到简单的Java游戏
  5. 高斯启发式Gaussian Heuristic 格理论相关知识
  6. js获取粘贴的html,JS读取粘贴板内容
  7. 华为笔记本电脑home键和end键快捷方式
  8. 加州大学戴维斯计算机博士生,关于加州大学戴维斯分校博士研究生CSC奖学金信息分享会的通知...
  9. Day 12 - 标签图片的方法与实作
  10. RMAN-06004 RMAN-20003