cards.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. package algorithm
  2. type Cards []byte
  3. // todo 两对和四张起脚牌的判定
  4. var StraightMask = []uint16{15872, 7936, 3968, 1984, 992, 496, 248, 124, 62, 31}
  5. // 顺子(Straight,亦称“蛇”)
  6. // 此牌由五张顺序扑克牌组成。
  7. // 平手牌:如果不止一人抓到此牌,则五张牌中点数最大的赢得此局,
  8. // 如果所有牌点数都相同,平分彩池。
  9. func (c *Cards) straight() uint32 {
  10. var handvalue uint16
  11. for _, v := range *c {
  12. value := v & 0xF
  13. // 0xE 1110
  14. if value == 0xE {
  15. handvalue |= 1
  16. }
  17. //0b0011111000000000, // 15872: A-2-3-4-5(特殊顺子,A作为1) 0b0000000000011111, // 31: 10-J-Q-K-A(A作为14)
  18. handvalue |= (1 << (value - 1))
  19. }
  20. for i := uint8(0); i < 10; i++ {
  21. if handvalue&StraightMask[i] == StraightMask[i] {
  22. // 10-i+4 代表顺子中最大牌型
  23. return En(STRAIGHT, uint32(10-i+4))
  24. }
  25. }
  26. return 0
  27. }
  28. // 同花顺(Straight Flush)
  29. // 五张同花色的连续牌。
  30. // 平手牌:如果摊牌时有两副或多副同花顺,连续牌的头张牌大的获得筹码。
  31. // 如果是两副或多副相同的连续牌,平分筹码。
  32. func (c *Cards) straightFlush() uint32 {
  33. cards := *c
  34. for i := byte(0); i < SUITSIZE; i++ {
  35. var handvalue uint16
  36. for _, v := range cards {
  37. if (v >> 4) == i {
  38. value := v & 0xF
  39. if value == 0xE {
  40. handvalue |= 1
  41. }
  42. handvalue |= (1 << (value - 1))
  43. }
  44. }
  45. for i := uint8(0); i < 10; i++ {
  46. if handvalue&StraightMask[i] == StraightMask[i] {
  47. return En(STRAIGHT_FLUSH, uint32(10-i+4))
  48. }
  49. }
  50. }
  51. return 0
  52. }
  53. // 皇家同花顺(Royal Flush)
  54. // 同花色的A, K, Q, J和10。
  55. // 平手牌:在摊牌的时候有两副多副皇家同花顺时,平分筹码。
  56. func (c *Cards) royalFlush() uint32 {
  57. cards := *c
  58. for i := byte(0); i < SUITSIZE; i++ {
  59. var handvalue uint16
  60. for _, v := range cards {
  61. if (v >> 4) == i {
  62. value := v & 0xF
  63. if value == 0xE {
  64. handvalue |= 1
  65. }
  66. handvalue |= (1 << (value - 1))
  67. }
  68. }
  69. if handvalue&StraightMask[0] == StraightMask[0] {
  70. return En(ROYAL_FLUSH, 0)
  71. }
  72. }
  73. return 0
  74. }
  75. // 四条(Four of a Kind,亦称“铁支”、“四张”或“炸弹”)
  76. // 其中四张是相同点数但不同花的扑克牌,第五张是随意的一张牌。
  77. // 平手牌:如果两组或者更多组摊牌,则四张牌中的最大者赢局,如果一组人持有的四张牌是一样的,
  78. // 那么第五张牌最大者赢局(起脚牌,2张起手牌中小的那张就叫做起脚牌)。如果起脚牌也一样,平分彩池。
  79. func (c *Cards) four(counter *ValueCounter) uint32 {
  80. cards := *c
  81. if counter.Get(cards[len(cards)-1]) == 4 {
  82. return En(FOUR, ToValue(cards))
  83. }
  84. return 0
  85. }
  86. // 满堂彩(Fullhouse,葫芦,三带二)
  87. // 由三张相同点数及任何两张其他相同点数的扑克牌组成。
  88. // 平手牌:如果两组或者更多组摊牌,那么三张相同点数中较大者赢局。
  89. // 如果三张牌都一样,则两张牌中点数较大者赢局,如果所有的牌都一样,则平分彩池。
  90. func (c *Cards) fullFouse(counter *ValueCounter) uint32 {
  91. cards := *c
  92. length := len(cards)
  93. if length >= 5 {
  94. if cards[length-1]&0xF == cards[length-2]&0xF &&
  95. cards[length-3]&0xF == cards[length-1]&0xF &&
  96. cards[length-4]&0xF == cards[length-5]&0xF {
  97. return En(FULL_HOUSE, ToValue(cards))
  98. }
  99. }
  100. return 0
  101. }
  102. // 同花(Flush,简称“花”)
  103. // 此牌由五张不按顺序但相同花的扑克牌组成。
  104. // 平手牌:如果不止一人抓到此牌相,则牌点最高的人赢得该局,
  105. // 如果最大点相同,则由第二、第三、第四或者第五张牌来决定胜负,如果所有的牌都相同,平分彩池。
  106. func (c *Cards) flush() uint32 {
  107. cards := *c
  108. for i := byte(0); i < SUITSIZE; i++ {
  109. var count uint8
  110. for _, v := range cards {
  111. if (v >> 4) == i {
  112. count++
  113. }
  114. }
  115. if count >= 5 {
  116. var handvalue uint16
  117. fCards := cards[len(cards)-5:]
  118. for _, v1 := range fCards {
  119. if (v1 >> 4) == i {
  120. value := v1 & 0xF
  121. if value == 0xE {
  122. handvalue |= 1
  123. }
  124. handvalue |= 1 << (value - 1)
  125. }
  126. }
  127. return En(FLUSH, uint32(handvalue))
  128. }
  129. }
  130. return 0
  131. }
  132. // 三条(Three of a kind,亦称“三张”)
  133. // 由三张相同点数和两张不同点数的扑克组成。
  134. // 平手牌:如果不止一人抓到此牌,则三张牌中最大点数者赢局,
  135. // 如果三张牌都相同,比较第四张牌,必要时比较第五张,点数大的人赢局。如果所有牌都相同,则平分彩池。
  136. func (c *Cards) three(counter *ValueCounter) uint32 {
  137. cards := *c
  138. if counter.Get(cards[len(cards)-1]) == 3 {
  139. return En(THREE, ToValue(cards))
  140. }
  141. return 0
  142. }
  143. // 两对(Two Pairs)
  144. // 两对点数相同但两两不同的扑克和随意的一张牌组成。
  145. // 平手牌:如果不止一人抓大此牌相,牌点比较大的人赢,如果比较大的牌点相同,那么较小牌点中的较大者赢,
  146. // 如果两对牌点相同,那么第五张牌点较大者赢(起脚牌,2张起手牌中小的那张就叫做起脚牌)。如果起脚牌也相同,则平分彩池。
  147. func (c *Cards) twoPair() uint32 {
  148. cards := *c
  149. length := len(cards)
  150. if length >= 4 {
  151. if cards[length-1]&0xF == cards[length-2]&0xF &&
  152. cards[length-3]&0xF == cards[length-4]&0xF {
  153. return En(TWO_PAIR, ToValue(cards))
  154. }
  155. }
  156. return 0
  157. }
  158. // 一对(One Pair)
  159. // 由两张相同点数的扑克牌和另三张随意的牌组成。
  160. // 平手牌:如果不止一人抓到此牌,则两张牌中点数大的赢,如果对牌都一样,则比较另外三张牌中大的赢,
  161. // 如果另外三张牌中较大的也一样则比较第二大的和第三大的,如果所有的牌都一样,则平分彩池。
  162. func (c *Cards) onePair() uint32 {
  163. cards := *c
  164. length := len(cards)
  165. if length >= 2 {
  166. if cards[length-1]&0xF == cards[length-2]&0xF {
  167. return En(ONE_PAIR, ToValue(cards))
  168. }
  169. }
  170. return 0
  171. }
  172. func ToValue(cards []byte) uint32 {
  173. var res uint32
  174. for i := len(cards) - 1; i >= 0; i-- {
  175. res *= 10
  176. res += uint32(cards[i] & 0xF)
  177. }
  178. return res
  179. }
  180. // ToValueHex 如果牌面值可能 ≥10,可以用 16 进制 或 分段编码;16 进制编码(支持 0~15)
  181. func ToValueHex(cards []byte) uint32 {
  182. var res uint32
  183. for i := len(cards) - 1; i >= 0; i-- {
  184. res <<= 4 // 左移 4 位(相当于 *16)
  185. res |= uint32(cards[i] & 0xF)
  186. }
  187. return res
  188. }
  189. // 示例:[0x0A, 0x0B] → 0xAB(171)
  190. func De(v uint32) (uint8, uint32) {
  191. return uint8(v >> 24), v & 0xFFFFFF
  192. }
  193. // En 高 8 位(bits 24~31) 存储 t(类型)。
  194. // 低 24 位(bits 0~23) 存储 v(数值)
  195. func En(t uint8, v uint32) uint32 {
  196. v1 := v | (uint32(t) << 24)
  197. return v1
  198. }