• 十三水中各种牌型判断LUA版


    近期回归程序行业,由于业务需求需要做十三水游戏,什么是十三水就不在多讲,下面是判断十三水牌型的方法(带大小王)

    1. GetSSSPaiType = {};
    2. local this = GetSSSPaiType;
    3. local huaseTable = {};
    4. local numTable = {};
    5. function GetSSSPaiType.Gtetype(cardList)
    6. --首先清空数组
    7. huaseTable = {};
    8. numTable = {};
    9. --格式化牌
    10. for i,card in ipairs(cardList) do
    11. local num,huase = GetPokerHasJoker(card)
    12. table.insert(huaseTable,huase);
    13. table.insert(numTable,num);
    14. end
    15. --获取是第几墩牌需要判断
    16. if(#cardList==3)then --是头道 只判断是三条顺子或者散牌 头道只需要判断是三条还是对子
    17. return SSSPaiData[this.GtetSanZhangype(numTable)].imageName;
    18. elseif (#cardList==5)then
    19. return SSSPaiData[this.GtetWuZhangType(huaseTable,numTable)].imageName;
    20. else
    21. return SSSPaiData[SSSPaiType.Error].imageName; --数组越界 return
    22. end
    23. end
    24. function GetSSSPaiType.GtetSanZhangype(cards) --判断头道是否三条
    25. if cards[1] == cards[2] and cards[1]==cards[3]then --是三条
    26. return SSSPaiType.SanTiao;
    27. else
    28. if cards[1] == cards[2] or cards[1] == cards[3] or cards[3] == cards[2] then --是对子
    29. return SSSPaiType.DuiZi;
    30. else --是散牌
    31. return SSSPaiType.SanPai;
    32. end
    33. end
    34. end
    35. --牌大小优先级 五同>同花顺>炸弹>葫芦>同花>顺子>三条>两对>对子>散牌
    36. function GetSSSPaiType.GtetWuZhangType(huaNums,dianNums) --五张牌需要两个参数 花色和点数
    37. if(table.ContainsValue(dianNums,0))then --带王 特殊判断
    38. table.RemoveValue(dianNums, 0) --首先吧王移除
    39. table.RemoveValue(huaNums, 5) --花色也需要移除
    40. if (table.ContainsValue(dianNums,0))then --再次判断是否有王 防止有两个王 --有两个王
    41. table.RemoveValue(dianNums, 0) --有两个王再次移除掉王
    42. table.RemoveValue(huaNums, 5) --花色也需要移除
    43. if(this.isWuTongHasTwoJoker(dianNums))then --两个王 是五同
    44. return SSSPaiType.WuTong;
    45. elseif(this.isTongHuaHasTwoJoker(huaNums) and this.isShunZi(dianNums,2) and table.getrepeat(dianNums)==3)then --同花顺
    46. return SSSPaiType.TongHuaShun;
    47. elseif(this.isTeShuShunZiHasTwoJoker(dianNums) and this.isTongHuaHasTwoJoker(huaNums)) then --特殊同花顺
    48. return SSSPaiType.ShunZi;
    49. elseif(this.isZhaDanHasTwoJoker(dianNums))then --是炸弹
    50. return SSSPaiType.ZhaDan;
    51. elseif(this.isTongHuaHasTwoJoker(huaNums))then --同花
    52. return SSSPaiType.TongHua;
    53. elseif(this.isShunZi(dianNums,2))then --顺子
    54. return SSSPaiType.ShunZi;
    55. elseif(this.isTeShuShunZiHasTwoJoker(dianNums))then --特殊顺子
    56. return SSSPaiType.ShunZi;
    57. else
    58. return SSSPaiType.SanTiao; --有两个王 最次也是个三条 不能是葫芦
    59. end
    60. else --只有一个王
    61. if(this.isWuTongHasOneJoker(dianNums))then --一个王 是五同
    62. return SSSPaiType.WuTong;
    63. elseif (this.isTongHuaHasOneJoker(huaNums) and this.isShunZi(dianNums,1) and table.getrepeat(dianNums)==4)then --是同花顺
    64. return SSSPaiType.TongHuaShun;
    65. elseif(this.isTeShuShunZiHasOneJoker(dianNums)and this.isTongHuaHasOneJoker(huaNums))then --特殊同花顺
    66. return SSSPaiType.TongHuaShun;
    67. elseif(this.isZhaDanHasOneJoker(dianNums))then --是炸弹
    68. return SSSPaiType.ZhaDan;
    69. elseif(this.isHuLuHasOneJoker(dianNums))then --是葫芦
    70. return SSSPaiType.HuLu;
    71. elseif(this.isTongHuaHasOneJoker(huaNums) and not this.isShunZi(dianNums,1))then --是同花 但不是顺子
    72. return SSSPaiType.TongHua;
    73. elseif(this.isShunZi(dianNums,1) and not this.isTongHuaHasOneJoker(huaNums) and table.getrepeat(dianNums)==4)then --是顺子 但不同花
    74. return SSSPaiType.ShunZi;
    75. elseif(this.isTeShuShunZiHasOneJoker(dianNums)and not this.isTongHuaHasOneJoker(huaNums))then --特殊顺子 但不是同花
    76. return SSSPaiType.ShunZi;
    77. elseif(this.isSnaTiaoHasOneJoker(dianNums))then --是三条
    78. return SSSPaiType.SanTiao;
    79. elseif(this.isLiangDuiHasOneJoker(dianNums))then --是两对
    80. return SSSPaiType.LiangDui;
    81. else
    82. return SSSPaiType.DuiZi; --有一个王 最低也是个对子
    83. end
    84. end
    85. else --不带王 直接判断
    86. if(this.isWuTong(dianNums))then --是五同
    87. return SSSPaiType.WuTong;
    88. elseif(this.isShunZi(dianNums,0) and this.isTongHua(huaNums))then --是同花顺
    89. return SSSPaiType.TongHuaShun;
    90. elseif(this.isTeShuShunZi(dianNums) and this.isTongHua(huaNums))then --特殊同花顺
    91. return SSSPaiType.ShunZi;
    92. elseif(this.isZhaDan(dianNums))then --炸弹
    93. return SSSPaiType.ZhaDan;
    94. elseif(this.isHuLu(dianNums)) then --是葫芦
    95. return SSSPaiType.HuLu;
    96. elseif(this.isTongHua(huaNums))then --是同花
    97. return SSSPaiType.TongHua;
    98. elseif(this.isShunZi(dianNums,0) and table.getrepeat(dianNums)==5)then --只有连续的数才是顺子 不能有重复的
    99. return SSSPaiType.ShunZi;
    100. elseif(this.isTeShuShunZi(dianNums))then --12345也是顺子
    101. return SSSPaiType.ShunZi;
    102. elseif(this.isSanTiao(dianNums))then --是三条
    103. return SSSPaiType.SanTiao;
    104. elseif(this.isLiangDui(dianNums))then --是两对
    105. return SSSPaiType.LiangDui;
    106. elseif(this.isDuiZi(dianNums))then --不对子
    107. return SSSPaiType.DuiZi;
    108. else
    109. return SSSPaiType.SanPai;
    110. end
    111. end
    112. end
    113. --判断是否顺子 带王
    114. function GetSSSPaiType.isShunZi(paiNums,jokerNum)
    115. local joker = 0;
    116. if(jokerNum==1)then
    117. joker = 1;
    118. elseif(jokerNum==2)then
    119. joker = 2;
    120. else
    121. joker = 0;
    122. end
    123. local n = #paiNums
    124. --排序
    125. local sortt = function(a, b)
    126. return a < b
    127. end
    128. table.sort(paiNums,sortt)
    129. local pre = paiNums[1]
    130. --计算总的补充数量
    131. local x = 0
    132. for i=2,n do
    133. local tx = paiNums[i] - pre
    134. x = x + tx - 1
    135. pre = paiNums[i]
    136. end
    137. --如果x比0的数量少,那么可以将数列补充成连续的
    138. if x <= joker then --是顺子
    139. return true;
    140. else
    141. --不是顺子
    142. return false;
    143. end
    144. end
    145. --12345也是顺子 特殊判断
    146. function GetSSSPaiType.isTeShuShunZi(paiNums)
    147. local teshu = {2,3,4,5,14};
    148. table.sort(paiNums)
    149. if(table.isEquation(teshu,paiNums))then
    150. return true;
    151. else
    152. return false;
    153. end
    154. end
    155. --是否同花
    156. function GetSSSPaiType.isTongHua(huaNums)
    157. if(huaNums[1]==huaNums[2] and huaNums[1]==huaNums[3] and huaNums[1]==huaNums[3] and huaNums[1]==huaNums[4] and huaNums[1]==huaNums[5]) then
    158. return true;
    159. else
    160. return false;
    161. end
    162. end
    163. --是否五同
    164. function GetSSSPaiType.isWuTong(paiNums)
    165. if(paiNums[1]==paiNums[2] and paiNums[1]==paiNums[3] and paiNums[1]==paiNums[3] and paiNums[1]==paiNums[4] and paiNums[1]==paiNums[5]) then
    166. return true;
    167. else
    168. return false;
    169. end
    170. return false;
    171. end
    172. --判断是否葫芦
    173. function GetSSSPaiType.isHuLu(paiNums)
    174. if paiNums[1] == paiNums[2] and paiNums[1] == paiNums[3] then
    175. if paiNums[4] == paiNums[5] then
    176. return true
    177. end
    178. end
    179. if paiNums[3] == paiNums[4] and paiNums[3] == paiNums[5] then
    180. if paiNums[1] == paiNums[2] then
    181. return true
    182. end
    183. end
    184. return false
    185. end
    186. --判断是否三条
    187. function GetSSSPaiType.isSanTiao(paiNums)
    188. table.sort(paiNums)
    189. if(paiNums[1]==paiNums[2]and paiNums[2]==paiNums[3])then
    190. return true;
    191. elseif(paiNums[2]==paiNums[3]and paiNums[3]==paiNums[4])then
    192. return true;
    193. elseif(paiNums[3]==paiNums[4]and paiNums[4]==paiNums[5])then
    194. return true;
    195. else
    196. return false
    197. end
    198. end
    199. --判断是否炸弹
    200. function GetSSSPaiType.isZhaDan(paiNums)
    201. table.sort(paiNums) --避免浪费性能 排序后单牌只会在1或者5
    202. if paiNums[1] == paiNums[2] and paiNums[1] == paiNums[3] and paiNums[1] == paiNums[4] then
    203. return true
    204. elseif paiNums[2] == paiNums[3] and paiNums[2] == paiNums[4] and paiNums[2] == paiNums[5] then
    205. return true
    206. else
    207. return false
    208. end
    209. end
    210. --判断是否两对
    211. function GetSSSPaiType.isLiangDui(paiNums)
    212. table.sort(paiNums) --避免浪费性能 排序后单牌只会在1 3 5
    213. if paiNums[1] == paiNums[2] and paiNums[4] == paiNums[5] then
    214. return true
    215. elseif paiNums[2] == paiNums[3] and paiNums[4] == paiNums[5] then
    216. return true
    217. elseif paiNums[1] == paiNums[2] and paiNums[2] == paiNums[3] then
    218. return true
    219. else
    220. return false
    221. end
    222. end
    223. --判断是否是对子 没有王
    224. function GetSSSPaiType.isDuiZi(paiNums)
    225. table.sort(paiNums)
    226. if(paiNums[1]==paiNums[2] or paiNums[2]==paiNums[3] or paiNums[3]==paiNums[4] or paiNums[4]==paiNums[5])then
    227. return true
    228. else
    229. return false
    230. end
    231. end
    232. -------------------------有一个王判断-------------------------
    233. --判断是否五同 有一个王
    234. function GetSSSPaiType.isWuTongHasOneJoker(paiNums)
    235. if (paiNums[1]==paiNums[2] and paiNums[1]==paiNums[3] and paiNums[1]==paiNums[4])then
    236. return true
    237. else
    238. return false
    239. end
    240. end
    241. --判断是否同花 有一个王
    242. function GetSSSPaiType.isTongHuaHasOneJoker(huaNums)
    243. if(huaNums[1]==huaNums[2] and huaNums[1]==huaNums[3] and huaNums[1]==huaNums[4])then
    244. return true
    245. else
    246. return false
    247. end
    248. end
    249. --判断是否特殊顺子 有一个王 就是和王能组成A2345的顺子
    250. function GetSSSPaiType.isTeShuShunZiHasOneJoker(paiNums)
    251. table.sort(paiNums) --首先吧自己的手牌格式化
    252. local teshu2 = {3,4,5,14};
    253. local teshu3 = {2,4,5,14};
    254. local teshu4 = {2,3,5,14};
    255. local teshu5 = {2,3,4,14};
    256. if(table.isEquation(teshu2,paiNums) or table.isEquation(teshu3,paiNums) or table.isEquation(teshu4,paiNums) or table.isEquation(teshu5,paiNums))then
    257. return true;
    258. else
    259. return false;
    260. end
    261. end
    262. --判断是否是炸弹 有一个王
    263. function GetSSSPaiType.isZhaDanHasOneJoker(paiNums)
    264. table.sort(paiNums) --格式化牌 让散牌在1或者4
    265. if(paiNums[1]==paiNums[2] and paiNums[1]==paiNums[3])then
    266. return true;
    267. elseif(paiNums[2]==paiNums[3] and paiNums[2]==paiNums[4])then
    268. return true;
    269. else
    270. return false;
    271. end
    272. end
    273. --判断是否是葫芦 有一个王
    274. function GetSSSPaiType.isHuLuHasOneJoker(paiNums)
    275. table.sort(paiNums)
    276. if(paiNums[1]==paiNums[2] and paiNums[3] == paiNums[4])then
    277. return true;
    278. else
    279. return false;
    280. end
    281. end
    282. --判断是否三条 有一个王
    283. function GetSSSPaiType.isSnaTiaoHasOneJoker(paiNums)
    284. table.sort(paiNums)
    285. if paiNums[1] == paiNums[2] or paiNums[2] == paiNums[3] or paiNums[3]==paiNums[4] then
    286. return true
    287. else
    288. return false
    289. end
    290. end
    291. --判断是否两对 有一个王
    292. function GetSSSPaiType.isLiangDuiHasOneJoker(paiNums)
    293. table.sort(paiNums)
    294. if(paiNums[1]==paiNums[2] or paiNums[2]==paiNums[3] or paiNums[3]==paiNums[4])then
    295. return true
    296. else
    297. return false
    298. end
    299. end
    300. -------------------------有两个王判断-------------------------
    301. --判断是否五同
    302. function GetSSSPaiType.isWuTongHasTwoJoker(paiNums)
    303. if(paiNums[1] == paiNums[2] and paiNums[1] == paiNums[3])then
    304. return true;
    305. else
    306. return false;
    307. end
    308. end
    309. --判断是否同花
    310. function GetSSSPaiType.isTongHuaHasTwoJoker(huaNums)
    311. if(huaNums[1] == huaNums[2] and huaNums[1] == huaNums[3])then
    312. return true;
    313. else
    314. return false;
    315. end
    316. end
    317. --判断是否炸弹
    318. function GetSSSPaiType.isZhaDanHasTwoJoker(paiNums)
    319. table.sort(paiNums)
    320. if(paiNums[1] == paiNums[2] or paiNums[2] == paiNums[3])then
    321. return true;
    322. else
    323. return false;
    324. end
    325. end
    326. --特殊顺子 就是和王能组成A2345的顺子
    327. function GetSSSPaiType.isTeShuShunZiHasTwoJoker(paiNums)
    328. table.sort(paiNums)
    329. local teshu1 = {2,3,14};
    330. local teshu2 = {2,4,14};
    331. local teshu3 = {2,5,14};
    332. local teshu4 = {3,4,14};
    333. local teshu5 = {3,5,14};
    334. if(table.isEquation(teshu1,paiNums) or table.isEquation(teshu2,paiNums) or table.isEquation(teshu3,paiNums) or table.isEquation(teshu4,paiNums) or table.isEquation(teshu5,paiNums))then
    335. return true;
    336. else
    337. return false;
    338. end
    339. end

    使用时仅需调用GetSSSPaiType.Gtetype()即可,牌类型如下:

    用到的牌型枚举:

    1. --十三水牌型枚举
    2. SSSPaiType =
    3. {
    4. SanPai = 0; --散牌
    5. DuiZi = 1; --对子
    6. LiangDui = 2; --两对
    7. SanTiao = 3; --三条 --三代二
    8. ShunZi = 4; --顺子
    9. TongHua = 5; --同花
    10. HuLu = 6; --葫芦
    11. ZhaDan = 7; --炸弹 --四代一
    12. TongHuaShun = 8; --同花顺
    13. WuTong = 9; --五同 五张牌一样
    14. Error = 10; --错误 没有这种牌型
    15. }
    16. SSSPaiData = {};
    17. SSSPaiData[SSSPaiType.SanPai] = {typeName = "散牌",imageName = "sanpai"};
    18. SSSPaiData[SSSPaiType.DuiZi] = {typeName = "对子",imageName = "duizi"};
    19. SSSPaiData[SSSPaiType.LiangDui] = {typeName = "两对",imageName = "liangdui"};
    20. SSSPaiData[SSSPaiType.SanTiao] = {typeName = "三条",imageName = "santiao"};
    21. SSSPaiData[SSSPaiType.ShunZi] = {typeName = "顺子",imageName = "shunzi"};
    22. SSSPaiData[SSSPaiType.TongHua] = {typeName = "同花",imageName = "tonghua"};
    23. SSSPaiData[SSSPaiType.HuLu] = {typeName = "葫芦",imageName = "hulu"};
    24. SSSPaiData[SSSPaiType.ZhaDan] = {typeName = "炸弹",imageName = "zhadan"};
    25. SSSPaiData[SSSPaiType.TongHuaShun] = {typeName = "同花顺",imageName = "tonghuashun"};
    26. SSSPaiData[SSSPaiType.WuTong] = {typeName = "五同",imageName = "tiezhi"};
    27. SSSPaiData[SSSPaiType.Error] = {typeName = "错误",imageName = "error"};

    用到的公共方法:可以放本类,也可以放全局,个人认为放全局会方便一点,这样其他地方也可以使用全局进行调用

    1. --切割牌 带王
    2. function GetPokerHasJoker(pkId)
    3. local sets = string.split(pkId, "_");
    4. local color = tonumber(sets[1]);
    5. local num = tonumber(sets[2]);
    6. if(num == 1) then
    7. num = 14;
    8. end
    9. if(color == 5)then --如果是王 就吧点数当成0
    10. num = 0;
    11. end
    12. return num, color;
    13. end
    14. --判断value是否存在
    15. --字典/数组
    16. function table.ContainsValue(tb, val)
    17. if(type(tb) == "table") then
    18. for k, v in pairs(tb) do
    19. if equals(v, val) then
    20. return true;
    21. end
    22. end
    23. else
    24. return equals(tb, val);
    25. end
    26. return false;
    27. end
    28. --删除字典中值
    29. function table.RemoveValue(tb, val)
    30. for k, v in pairs(tb) do
    31. if(v == val) then
    32. table.remove(tb, k);
    33. return;
    34. end
    35. end
    36. end
    37. --判断两个数组是否相等
    38. function table.isEquation(tb1,tb2)
    39. if(#tb1~=#tb2)then
    40. return false;
    41. end
    42. for i,v in pairs(tb1) do
    43. if tb1[i] ~= tb2[i]then
    44. return false;
    45. end
    46. end
    47. return true;
    48. end
    49. --检查表内相同元素个数
    50. function table.getrepeat(t)
    51. local check = {}
    52. local n = {}
    53. for key, value in pairs(t) do
    54. if not check[value] then
    55. n[key] = value
    56. check[value] = value
    57. end
    58. end
    59. return #n;
    60. end

    bug修复历史

    2023-10-29 有王的顺子判断会失败已经修复,牌型枚举忘记要放牌型已经添加

    写在后面:方法是临时拼凑,可能会有bug,我会持续修复,直至修复完美!!

  • 相关阅读:
    MyBatis【一】
    鸿蒙HarmonyOS实战-ArkUI动画(弹簧曲线动画)
    自定义Lua解析器管理器-------演化脚本V0.5
    go中读写锁(rwmutex)源码解读实现原理
    音视频开发常用工具
    【数据结构】从链表到LinkedList类
    【spring cloud】(三)服务降级——Hystrix
    C++标准模板(STL)- 类型支持 (数值极限,C 数值极限接口)
    【java算法专场】双指针(上)
    笔记:Windows故障转移集群下的oracle打补丁
  • 原文地址:https://blog.csdn.net/Superficialtise/article/details/133965333