今年过年的时候,在玩微信小程序之欢乐斗地主。发现里面还含有一个小游戏叫做“残局闯关”,如下图。

这里面的题,如果不熟悉其中的套路,有个别几道还真的不好做(下文有例子)。于是,我便萌发了设计并实现一个残局解答器的想法。从过年期间就开始利用业余时间进行coding,到今天晚上,用了大约3周左右的业余时间,终于实现出了一个基本的残局解答器。目前UI也已经全部完成。可以轻松解题了!
那么,如何做一个残局解答器呢?它是由哪几个部分构成的呢?算法又是怎样的呢?下面一个一个来介绍。

一、 残局解答器的组成部分
本残局解答器由以下这几部分组成:
1. 局面表示法
2. 招法生成器
3. 招法分类器
4. 招法过滤器
5. 招法应对器
6. 计算引擎
7. UI界面(未全部完成)
8. 测试程序

以下一一介绍:

1. 局面表示法
   局面表示分为2种,一种是用户输入输出局面表示法,第二种是引擎计算时使用的局面表示法。
   对于用户输入输出,那就和自然表示一样,J就是'J', Q就是'Q',小王是'Y',大王是'Z', 2是2或'2'都可以。
   对于引擎计算时的局面表示,那就全部是数据了,如J、Q、K、A、2分别是11,12,13,14,18. 小王是20,大王是30. 
   
2. 招法生成器(MoveGener)
   给定一个list,即一手牌,能够计算出这手牌所有的可出的招法,包括pass。
   本程序中,除pass外,共分为14种招法,分别为:单牌、对子、三个、炸弹、王炸、3+1、3+2、连续单牌(至少5连张)、连对(至少3连对)、飞机(连续2个或多个相同的3张牌)、连续3+1、连续3+2、4+2、4+双对。
   
3. 招法分类器(MoveClassifier)
   给定一个招法(即一个list),能够返回该招法的类型。若是连续型招法(如连对),还能指出是几连。
   
4. 招法过滤器(MoveFilter)
   给定一系列招法,再给定一个对手招法,在这一系列招法中,找出能够克制对手招法的招法。
   比如,[[3,3], [4,4], [5,5]], 对手招法是[4,4],那么经过MoveFilter的计算,得到的返回应该是 [[5,5]]
   
5. 招法应对器(get_resp_moves)
   给定一手牌,以及一个对手招法,给出这手牌中所有能够应对该对手招法的招法。
   可见,招法应对器就是对MoveGener、MoveClassifier、和MoveFilter的一个综合使用。
   第一步,利用MoveClassifier,判断对手招法是14种招法类型的哪一种;
   第二步,利用MoveGener,生成这种类型的这手牌的所有招法;
   第三步,利用MoveFilter,过滤第二步中产生的招法,得到可以应对对手招法的招法。
   
6. 计算引擎
   这是本程序的核心部分。
   本程序一共实现了2个引擎 - 蒙特卡洛搜索引擎(分为单进程版和多进程版) 和 Min-Max搜索引擎。
   详情见下一章。
   
7. UI界面
   因为未完全实现,所以这里从略。不过即使没有UI界面,本程序也是可以用来解答残局的。
   
8. 测试程序
   上述各个组成部分都有自己对应的测试程序。保证无bug.

二、计算引擎

Min-Max纯暴力搜索加剪枝
Min-Max算法是国际象棋和中国象棋的人工智能程序的基石算法。虽然象棋AI种类繁多,优化方法也是千变万化,但是所有象棋AI归根结底,都是建立于Min-Max这个基石之上的。
那么,Min-Max算法是什么意思呢?
其实,意思很直观。先这么看,假设地主先出,地主一手牌就出完了,那么这种情况就是地主必胜。给地主先出之前的局面打分,就是满分100分。假设地主先出,但牌没有出完,农民接着出。不论地主出什么牌,农民手上只有2张牌,王炸,好了,那么农民必胜。这个时候,给地主出完牌而农民待出牌的局面打分,就是0分,这是农民必胜局面。再往上一层,给地主待出牌的局面打分,发现无论地主出什么牌,比如10种出法,10种返回都是0分,那么地主待出牌的这个局面自然也就是0分。
换句话说,在地主待出牌的局面下,一旦找到一种出法的返回值是100分,那么选这种打法就地主必胜啦;反之,若所有招法的局面都返回0分,那这就是地主必败局面,如果要往上一层返回,就是返回0分。
总结一下:
地主待出牌局面,一旦找到一个100分的招法,剩下招法都不用试了,直接返回100分,这就是剪枝;
同理,农民待出牌局面,一旦找到一个0分的招法,剩下的招法都不用试了,直接返回0分,这就是剪枝。

利用Min-Max算法,以及上面介绍的剪枝算法,我发现程序运行的速度有了极大的提升。其实原因就是剪枝了。

三、运行效果

最后,来看一下运行效果吧。
聪明的读者,请看一下2018年3月残局闯关的第12关吧,您能过去吗?

首先,编辑solve_python.py文件,只需修改其中2行表示地主牌和农民牌的,如下:

然后,运行程序:

没错,唯一的一招必杀是先出 10 !所有其他招法都是必败招。这就是Min-Max的威力了!

其实,一般的题用不了这么长的时间,几秒到几十秒就做出来了,但这一道题确实有点难度,所以时间也耗得久一些。地主出牌后,用户可以根据手机上农民的出牌,再把农民出的牌手动输入到以上人机交互界面里,然后电脑会继续计算地主的应招,这一次计算就很快了,基本是秒级的。

最后,公布一下源代码地址:

https://github.com/FinixLei/WeChat_LandLords

(完)

关于本残局解答器最新的故事(2019-05),请参见《C++大战Python - 以C++11重写欢乐斗地主残局解答器》

做一个微信欢乐斗地主之残局解答器!相关推荐

  1. C++大战Python - 以C++11重写欢乐斗地主残局解答器

    业界传说Python平均一行代码能够顶的上几十行C/C++代码.业界还传说,C++效率能够达到Python的几十倍. 对于以上二者,笔者本来感觉也许差不多只是略夸张.笔者曾经用C++和Python分别 ...

  2. 经典残局html,微信欢乐斗地主3月残局1-100关全攻略 3月残局图文攻略大全

    微信欢乐斗地主3月残局1-100关全攻略 微信欢乐斗地主3月残局通关攻略.微信欢乐斗地主3月残局已经上线了,小编整理好了100关的攻略给大家,微信欢乐斗地主3月残局攻略,很多玩家都在问三月的残局怎么过 ...

  3. 做一个微信小程序多少钱?

    很多朋友在问做一个微信小程序多少钱?他们知道微信小程序是下一个风口,也想从小程序上分得一杯羹.微信小程序是一个不需要下载安装就可使用的应用,它实现了应用触手可及的梦想,用户扫一扫或者搜一下即可打开应用 ...

  4. 如何建立自己的微信小程序,做一个微信小程序大概多少钱?

    如今,小程序的功能越来越强大,也越来越受欢迎,它不仅能帮助企业和商家做推广,还能给他们带来很多好处.所以,很多企业都开始建立自己的小程序.但是对于如何建立自己的微信小程序,以及做一个微信小程序大概多少 ...

  5. 做一个微信小程序商城需要多少钱?

    这几年,微信小程序特别火,因为易用易传播的特性,很多企业也都都在搭建小程序商城进行宣传拓客.这也催生了网络上提供小程序服务的公司也是铺天盖地,有免费的,几十元的,卖模板的,开店的,倒卖源码的,盗版的, ...

  6. 做一个微信小程序需要多少钱?两种示例

    在需求明确之前,做一个微信小程序需要多少钱还不清楚.我们选择了两种目前需求量很大的小程序,并推出了价格.你可以看看有没有你想要的: [服务微信小程序] 一般是订购小程序,预订小程序,常用于服装.餐厅. ...

  7. 零基础做一个微信答题小程序(四)

    嗨!大家好,我是小蚂蚁.这一节里,我们继续分享如何在答完题后进行答案的比对,以及如何实现一个回顾功能. 在上一节里我们提到过,为了记录玩家的答题数据,我们创建了一个新的表格--玩家答题选项表,里面记录 ...

  8. 三步教你用Node做一个微信哄女友(基友)神器,小白可上手

    前言 不知道大家最近有没有被python版的<微信每日说>刷屏呢,他可是霸占了github的python热门快两周了.我们前端的小伙伴是不是也看着有点眼馋呢,因为毕竟是不那么熟悉的pyth ...

  9. 【微信小程序控制硬件⑦ 进阶篇】动起来做一个微信小程序Mqtt协议控制智能硬件的框架,为心里全栈工程师梦想浇水。

    文章目录 一.前言: 二.涉及的技术点: 三.框架的运行原理: 四.框架代码流程: 4.1 主线程: 4.2 获取设备列表显示设备,以及订阅在线的设备: 4.3 点击某设备如何实现携带此设备信息到控制 ...

  10. 做一个微信小程序商城需要多少钱

    这几年,微信小程序特别火,因为易用易传播的特性,很多企业也都都在搭建小程序商城进行宣传拓客.这也催生了网络上提供小程序服务的公司也是铺天盖地,有免费的,几十元的,卖模板的,开店的,倒卖源码的,盗版的, ...

最新文章

  1. MySQL 5.6中如何定位DDL被阻塞的问题
  2. 教育部:不得将研究生当作廉价劳动力!也不得故意拖延毕业时间!
  3. Java多线程:synchronized关键字和Lock
  4. 位置相关属性offset(),position(),scrollTop()等
  5. 实战项目三:爬取QQ群中的人员信息
  6. 文件上传流式处理commons-fileupload
  7. 需求用例分析之七:业务用例之小结
  8. python多线程锁有没有优先级别_全面解析python线程优先级队列(queue)原理
  9. 创建邮箱过程中的问题及解决办法
  10. 只要你上网,哪能不中毒?
  11. 微控制器8位到32位变迁
  12. 图像算法六:【彩色图像处理】彩色模型、彩图处理
  13. dense sift matlab,DenseSift+BOW词袋模型+SVM支持向量机
  14. linux 备份文件时加上日期
  15. 解决方法-SQLserver建表后更改列,显示不允许保存更改。您所做的更改要求删除并重新创建以下表
  16. 值得收藏的UmiJS 教程
  17. 【Linux进程概念】冯 诺依曼体系结构 操作系统 进程 fork 进程状态 优先级
  18. Unity游戏帧同步技术分享篇【01】帧同步解决方案概述
  19. 电脑桌面便签提醒事项到期后怎么清除时间设置?
  20. html css 奥运五环,用css3实现一个奥运五环

热门文章

  1. [转]最世界最牛人博客,你可以学习到太多太多`~~
  2. 工作室流量卡如何做才能不封号?
  3. 使用 Flash 描述复杂的社交网络
  4. Redhat下7-Zip的安装和使用
  5. 【必备知识】摄像机标定基础理论
  6. Android自带语音播报TextToSpeech功能开发记录
  7. 真机试用深度linux,推荐使用
  8. JAVA汽车4s店管理系统前后台
  9. 用 Python 自制成语接龙小游戏!
  10. 2020 智慧城市解决方案(智慧城市系统及相关技术)