实现人机麻将程序,关键在于出牌和胡牌部分。出牌的好坏最终决定了胡牌速度,而胡牌部分相对简单,只要满足胡牌公式就行。实现后可安排四个人机进行对战一万场,然后分析自摸的概率,分析不同打牌策略下的胜率问题,从而继续优化AI深度,……
一、规则介绍
本文采用oracle数据库的实现方式,没有UI,只描述实现逻辑和方法。而规则采用的是通用麻将游戏,胡牌公式为:x123+y111+11(其中123表示顺子,111表示坎子,11表示对子,x和y表示个数)
为方便代码处理,用数字来代表麻将牌,如下:
1~9 表示 一到九万
11~19 表示 一饼到九饼
21~29表示 一条到九条
31 中 32 发 33白
二、数据库设计
物理模型如下
其中
三、核心思路
开局前的摇色定庄,获取初始抓牌位置,以及首轮抓牌等一次性操作比较简单,不做具体的描述。重点讲述依次出牌碰牌的过程。
(1) 轮流出牌,从出牌开始循环,当轮到下一个人出牌时重新开始新一轮判断,直到有人自摸、点炮或者黄庄结束。具体流程图如下:
(2)根据胡牌算法,判断是否自摸。如果没有自摸,判断是否听牌。方法为拿所有手牌以及手牌的上一张和下一张依次用胡牌算法判断能不能胡,能胡则表示听牌,并把能胡的牌存入表tmp_tag。
举个栗子:
依次将这些同上面的13张牌组合在一起用胡牌算法判断能不能胡,结果是已经听牌,并且能胡的牌是4,5,6,7,9
(3)出牌策略,优先出单张不连号,并且最靠边的牌;其次单张连号但不够三张的;再次就是非单张的。
(4)每次出完牌后,需重新理牌,即标记出可碰、杠的牌,并标记到表tmp_tag。当别人出牌时直接查表tmp_tag,而不用重新判断哪个人可以碰或者胡
四、补充说明
取其中一场游戏结束后的手牌看看
用存储过程实现棋牌类游戏不是主流方式,但是存储过程胜在方便处理和存储数据,而不需要另外连接数据库。
完整代码参考:添加链接描述
关于出牌策略仅罗列最基本的打牌套路,复杂的方法可参考:
麻将胡牌算法可参考:添加链接描述