哇,很久很久没写东西啦。。。git
这两天实现了一个简单的游戏引擎,能够发牌,能够比较两手牌的大小github
这阶段事后准备用这个引擎来实现一个简单的AI对战,如今先记录一下,实现方面我用的是GO语言算法
接下来我假设你已经懂游戏规则和俗语了数组
首先是牌的储存,2~~A,一共13张牌,我用的是一个14位的二进制区间来储存的,好比2-A,将表示为:11111111111110,辣么第一位是干啥的呢,请继续看下面排序
这样的储存方式除了省空间外还有什么优点呢?咱们顺子的判断为例:
例如顺子10JQKA,在二进制区间将表示为11111000000000,叫它S
如今咱们有手牌2 3 10 J Q K A,那么它的二进制表示是11111000000110,叫它T
那么T&S==S的话,就能够说明T包含一个顺子,而且顺子是10JQKA
S转化为10进制的话是15872
相似的咱们将全部可能的顺子预先保存好,以下表(10用T表示):three
----------------------------------------------------------------------------------------------------游戏
TJQKA | 9TJQK | 89TJQ | 789TJ | 6789T | 56789 | 45678 | 34567 | 23456 | A2345 |get
15872 | 7936 | 3968 | 1984 | 992 | 496 | 248 | 124 | 62 | 31 |源码
-----------------------------------------------------------------------------------------------------it
因为德州扑克里面A 2 3 4 5是最小的顺子,如今你能够明白二进制区间里第0位的做用了,和最高位同样也是保存A
咱们维护一个容量为4的int数组straight,它表示四个花色中每种花色的牌,储存原理见开头,它将被用来快速的判断同花顺,同时还能够用来判断是否为同花
再维护一个int变量hand,它表示全部手牌的并集,不分花色。它将被用来快速的判断是否为顺子
最后维护一个容量为13的int数组count,它用于对每种牌值出现的次数计数
咱们将全部牌型作一个分级:
皇家同花顺:10
同花顺 :9
四条 :8
葫芦 :7
同花 :6
顺子 :5
三条 :4
两对 :3
一对 :2
高牌 :1
比较的时候先比较两手牌的等级,等级相同的状况下,咱们进一步分析每一副手牌的value值。
个人value的算法以下:
对你的手牌进行排序,排序规则是出现次数多的优先,次数相同的则值大的优先,好比:
7 8 4 2 2 A K,排序后为:22AK874,能够理解为16进制:0x22AD874。
须要注意的是,顺子和同花不适应此算法,顺子的value就是该顺子的最高牌;同花的value是该花色的牌并集(具体读者能够本身思考)
各类牌型的判断以及比较:
一、皇家同花顺 royal flush
这个最简单了,直接用四个花色的牌集(详见straight数组),去和15872相与便可(原理见上)
一场牌局只可能出现惟一皇家同花顺,因此只须要记录等级便可,由于只可能win or tie(五张公牌)
二、同花顺straight flush
和皇家同花顺相似,从大到小遍历全部可能的顺子,和它们作与操做。value值是该顺子中最大的高牌
三、四条 four of a kind
维护一个数组count []int用于对每一种牌值进行计数便可。
还有一种方法是将四种花色的牌集相与,最后二进制区间内仍是1的那些就是咱们要的。
四、葫芦 full house
经过count数组先遍历有没有出现三次的,有的话,再遍历有没有出现2次的
五、同花 flush
有两个方法,一个是对每个花色的牌集进行遍历,看看二进制集合里有没有5个1
第二个方法详见代码,判断同花的逻辑处
六、顺子 straight
取全部花色牌的集合,去和全部可能的顺子作与操做
七、三条 three of a kind;两对 two pairs; 一对 one pair
运用count数组计数器
源码开源在github上:https://github.com/SongLiangChen/TexasHoldem.git