You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2518 lines
67 KiB

  1. --[[经典16张
  2. 0x01, 0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d, //黑桃
  3. 0x12, 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d, //红桃
  4. 0x22, 0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d, //梅花
  5. 0x32, 0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d, //方块
  6. ]]
  7. --[[15张
  8. 0x01,0x02, 0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d, //黑桃
  9. 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d, //红桃
  10. 0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d, //梅花
  11. 0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d, //方块
  12. ]]
  13. local GUI_VAL = 0x0e --鬼的牌值
  14. local ER_VAL = 0x0d --2的牌值
  15. local A_VAL = 0x0c --A的牌值
  16. function pokerParse( card )
  17. local tp = math.floor(card/16)
  18. local val = card%16
  19. -- print("---------tp : "..tp.." val : "..val)
  20. return tp, val
  21. end
  22. function pokerPng( card )
  23. local tp , val = pokerParse(card)
  24. return string.format("pdk_cards_%d_%d.png", tp, val)
  25. end
  26. -- 对牌进行排序
  27. function pokerSortPdkCards( cards )
  28. local tmp = {}
  29. for _,card in ipairs(cards) do
  30. local tp, val = pokerParse(card)
  31. table.insert(tmp, {tp=tp, val=val, cid=card})
  32. end
  33. table.sort(tmp, function (a, b)
  34. if a.val == b.val then
  35. return a.tp < b.tp
  36. else
  37. return a.val > b.val
  38. end
  39. end)
  40. return tmp
  41. end
  42. -- 牌的排序函数
  43. local function sortCardsFunc( a, b )
  44. return a.val < b.val
  45. end
  46. -- 获取剩余牌(parseCards)
  47. local function getLeft( src, target )
  48. local have = {}
  49. for _,v in ipairs(target) do
  50. have[tostring(v.cid)] = v
  51. end
  52. local left = {}
  53. for _,v in pairs(src) do
  54. if not have[tostring(v.cid)] then
  55. table.insert(left, v)
  56. end
  57. end
  58. return left
  59. end
  60. local luzhouPokerUtil = class("luzhouPokerUtil")
  61. -- 所有传入参数均为{tp, val, cid}结构集合
  62. function luzhouPokerUtil:ctor(param)
  63. if param.isChai==nil then
  64. param.isChai = false
  65. end
  66. if param.isFAT==nil then--four and three
  67. param.isFAT = false
  68. end
  69. self.isChai = param.isChai
  70. self.isFAT = param.isFAT
  71. end
  72. -- 对牌组按照value进行分类
  73. function luzhouPokerUtil:classifyCards( cards )
  74. local tmpCards = clone(cards)
  75. local result = {}
  76. for _,v in pairs(tmpCards) do
  77. if not result[tostring(v.val)] then
  78. result[tostring(v.val)] = {}
  79. end
  80. table.insert(result[tostring(v.val)], v)
  81. end
  82. local tmp = {}
  83. for _,v in pairs(result) do
  84. table.insert(tmp, v)
  85. end
  86. return tmp
  87. end
  88. -- 对牌组按照value进行分类 返回key-value结构
  89. function luzhouPokerUtil:classifyCardsEx( cards )
  90. local tmpCards = clone(cards)
  91. local result = {}
  92. for _,v in pairs(tmpCards) do
  93. if not result[tostring(v.val)] then
  94. result[tostring(v.val)] = {}
  95. end
  96. table.insert(result[tostring(v.val)], v)
  97. end
  98. return result
  99. end
  100. -- 检测牌的点数是否相同
  101. function luzhouPokerUtil:checkSameVal( cards )
  102. if cards and type(cards)~="table" then return false end
  103. if #cards <= 0 then return false end
  104. local targetVal = cards[1].val
  105. local result = true
  106. for _,v in pairs(cards) do
  107. if v.val ~= targetVal then
  108. result = false
  109. break
  110. end
  111. end
  112. return result
  113. end
  114. -- 检测牌组中是否带2
  115. function luzhouPokerUtil:checkOwnEr(cards)
  116. if cards and type(cards)~="table" then return false end
  117. local result = false
  118. for _,v in pairs(cards) do
  119. if v.val == ER_VAL then
  120. result = true
  121. break
  122. end
  123. end
  124. return result
  125. end
  126. -- 检测牌组中是否包含某一张牌
  127. function luzhouPokerUtil:checkOwnX( cards, card)
  128. if cards and type(cards)~="table" then return false end
  129. local result = false
  130. for _,v in pairs(cards) do
  131. if v.val == card.val then
  132. result = true
  133. break
  134. end
  135. end
  136. return result
  137. end
  138. -- 将牌解析成{tp, val ,cid}牌组
  139. function luzhouPokerUtil:parseCards( cards )
  140. local result = {}
  141. for _,v in ipairs(cards) do
  142. local tp, val = pokerParse(v)
  143. table.insert(result, {tp=tp, val=val, cid=v})
  144. end
  145. return result
  146. end
  147. -- 从分类牌组中查找到指定数量牌的集合
  148. function luzhouPokerUtil:getSameNum( classify, num )
  149. local result = {}
  150. for _,v in pairs(classify) do
  151. if #v == num then
  152. table.insert(result, v)
  153. end
  154. end
  155. return result
  156. end
  157. -- 从分类牌组中查找到指定数量牌的集合,包括大于num的牌组
  158. function luzhouPokerUtil:getSameNumEx( classify, num )
  159. local result = {}
  160. for _,v in pairs(classify) do
  161. if #v >= num then
  162. table.insert(result, v)
  163. end
  164. end
  165. return result
  166. end
  167. -- 从分类牌组中查找到指定数量牌的集合,包括大于num的牌组 key-val存储
  168. function luzhouPokerUtil:getSameNumExEx( classify, num )
  169. local result = {}
  170. for k,v in pairs(classify) do
  171. if #v >= num then
  172. result[tostring(k)] = v
  173. end
  174. end
  175. return result
  176. end
  177. --------------------------------------------------------------------------------------
  178. -- 检测牌型
  179. --------------------------------------------------------------------------------------
  180. -- 检测是否是对子
  181. function luzhouPokerUtil:checkDui( cards )
  182. if cards and type(cards)~="table" then return false end
  183. if #cards ~= 2 then return false end
  184. return self:checkSameVal(cards)
  185. end
  186. -- 检测3不带
  187. function luzhouPokerUtil:checkThree( cards )
  188. if cards and type(cards)~="table" then return false end
  189. if #cards ~= 3 then return false end
  190. return self:checkSameVal(cards)
  191. end
  192. -- 检测4张
  193. function luzhouPokerUtil:checkFour( cards )
  194. if cards and type(cards)~="table" then return false end
  195. if #cards ~= 4 then return false end
  196. return self:checkSameVal(cards)
  197. end
  198. -- 检测是否顺子,至少5张
  199. function luzhouPokerUtil:checkShunzi( cards )
  200. local LessNum = 5
  201. if cards and type(cards)~="table" then return false end
  202. if #cards < LessNum then return false end--牌中是否带2 或者牌张数不够
  203. return self:checkSZ(cards)
  204. end
  205. -- 检测顺子,至少两张
  206. function luzhouPokerUtil:checkSZ(cards)
  207. local LessNum = 2
  208. if cards and type(cards)~="table" then return false end
  209. if #cards < LessNum then return false end--牌中是否带2 或者牌张数不够
  210. local tmpCards = clone(cards)
  211. table.sort(tmpCards, sortCardsFunc)
  212. local idx = 1
  213. local result = true
  214. local classify = self:classifyCards(tmpCards)
  215. local isHaveGui,guiNum = self:checkHaveGui(classify)
  216. for i=2,#tmpCards do
  217. if tmpCards[idx].val == 12 and tmpCards[idx].val+1 == tmpCards[i].val and tmpCards[1].val == 1 then
  218. idx = idx + 1
  219. elseif tmpCards[idx].val == 13 and tmpCards[1].val == 1 then
  220. idx = idx + 1
  221. elseif tmpCards[idx].val == 3 and tmpCards[idx].val+9 == tmpCards[i].val then
  222. idx = idx + 1
  223. --[[elseif tmpCards[i].val == 13 and tmpCards[1].val ~= 1 then
  224. local needgui = tmpCards[1].val-1
  225. if guiNum >= needgui then
  226. guiNum = guiNum - needgui
  227. idx = idx + 1
  228. else
  229. result = false
  230. break
  231. end--]]
  232. elseif tmpCards[idx].val+1 ~= tmpCards[i].val and (tmpCards[i].val ~= 14) then
  233. local needgui = tmpCards[i].val - tmpCards[idx].val-1
  234. if tmpCards[i].val == 13 and tmpCards[1].val == 1 then
  235. idx = idx + 1
  236. elseif tmpCards[i].val == 12 and tmpCards[i+1] and tmpCards[i+1].val == 13 then
  237. if tmpCards[1].val == 1 then
  238. idx = idx + 1
  239. else
  240. local needgui = tmpCards[1].val - 1
  241. if guiNum >= needgui then
  242. guiNum = guiNum - needgui
  243. idx = idx + 1
  244. else
  245. result = false
  246. break
  247. end
  248. end
  249. elseif tmpCards[i].val == 12 and tmpCards[1].val == 1 and guiNum > 0 then
  250. guiNum = guiNum - 1
  251. idx = idx + 1
  252. elseif needgui < 0 then --有相等的牌,必定不是顺子
  253. result = false
  254. break
  255. elseif guiNum >= needgui then
  256. guiNum = guiNum - needgui
  257. idx = idx + 1
  258. else
  259. result = false
  260. break
  261. end
  262. else
  263. idx = idx + 1
  264. end
  265. end
  266. return result
  267. end
  268. -- 检测连对
  269. function luzhouPokerUtil:checkLianDui(cards)
  270. local LessNum = 4
  271. if cards and type(cards)~="table" then return false end
  272. if #cards < LessNum or #cards%2~=0 then return false end--牌中是否带2 或者牌张数不够
  273. local tmpCards = clone(cards)
  274. local yclassify = self:classifyCards(tmpCards)
  275. local classify = self:classifyCardsEx(tmpCards)
  276. --[[if #classify*2 ~= #tmpCards then return false end
  277. -- 确保每组牌四两张
  278. for _,v in pairs(classify) do
  279. if #v~=2 then return false end
  280. end--]]
  281. table.sort(tmpCards, sortCardsFunc)
  282. local tmp = {}
  283. --[[for i=1,#tmpCards do
  284. if i%2==1 then
  285. table.insert(tmp, tmpCards[i])
  286. end
  287. end--]]
  288. for i,v in pairs(classify) do
  289. table.insert(tmp, v[1])
  290. end
  291. return self:checkSZ(tmp)
  292. end
  293. -- 检测三带一(最后四张才能3带一?)
  294. function luzhouPokerUtil:check3And1( cards )
  295. local LessNum = 4
  296. if cards and type(cards)~="table" then return false end
  297. if #cards ~= LessNum then return false end-- 或者牌张数不够
  298. local classify = self:classifyCards(cards)
  299. local own3 = false
  300. for _,v in ipairs(classify) do
  301. if #v == 3 then
  302. own3 = true
  303. break
  304. end
  305. end
  306. return own3
  307. end
  308. -- 检测三带二
  309. function luzhouPokerUtil:check3And2( cards )
  310. local LessNum = 5
  311. if cards and type(cards)~="table" then return false end
  312. if #cards ~= LessNum then return false end--牌张数不够
  313. local classify = self:classifyCards(cards)
  314. local isHaveGui,guiNum = self:checkHaveGui(classify)
  315. local own3 = false
  316. for _,v in ipairs(classify) do
  317. if #v == 3 or (#v == 2 and guiNum == 1) or (guiNum == 2) then
  318. own3 = true
  319. break
  320. end
  321. end
  322. return own3
  323. end
  324. -- 检测四带一
  325. function luzhouPokerUtil:check4And1(cards)
  326. local LessNum = 5
  327. if cards and type(cards)~="table" then return false end
  328. if #cards ~= LessNum then return false end--或者牌张数不够
  329. local classify = self:classifyCards(cards)
  330. local own4 = false
  331. for _,v in ipairs(classify) do
  332. if #v == 4 then
  333. own4 = true
  334. break
  335. end
  336. end
  337. return own4
  338. end
  339. -- 检测四带3
  340. function luzhouPokerUtil:check4And3( cards )
  341. local LessNum = 7
  342. if cards and type(cards)~="table" then return false end
  343. if #cards ~= LessNum then return false end--或者牌张数不够
  344. local classify = self:classifyCards(cards)
  345. local own4 = false
  346. for _,v in ipairs(classify) do
  347. if #v == 4 then
  348. own4 = true
  349. break
  350. end
  351. end
  352. return own4
  353. end
  354. -- 检测 炸弹
  355. function luzhouPokerUtil:checkBomb( cards )
  356. return self:checkFour(cards)
  357. end
  358. -- 检测 是否有鬼牌 cards传已经解析过的牌
  359. function luzhouPokerUtil:checkHaveGui( cards )--返回传递的牌里是否有鬼,和鬼的张数
  360. local ishaveGui = false
  361. local guiNum = 0
  362. for i,v in pairs(cards) do
  363. if v[1].val == 14 then
  364. ishaveGui = true
  365. guiNum = #v
  366. break
  367. end
  368. end
  369. return ishaveGui,guiNum
  370. end
  371. -- 检测 是否有鬼牌 cards没有解析过
  372. function luzhouPokerUtil:checkHaveGui1( cards )--返回传递的牌里是否有鬼,和鬼的张数
  373. local ishaveGui = false
  374. local guiNum = 0
  375. local parseData = {}
  376. for _,v in ipairs(cards) do
  377. local tp, val = pokerParse(v)
  378. table.insert(parseData, {tp=tp, val=val, cid=v})
  379. end
  380. local tCards = self:classifyCards(parseData)
  381. for i,v in pairs(tCards) do
  382. if v[1].val == 14 then
  383. ishaveGui = true
  384. guiNum = #v
  385. break
  386. end
  387. end
  388. return ishaveGui,guiNum
  389. end
  390. -- 检测飞机555666 555666777等+同等数量的对牌,或者双倍单牌
  391. function luzhouPokerUtil:checkPlan( cards, shaoDai )
  392. shaoDai = shaoDai or false
  393. local LessNum = 6 -- 6+4 9+6
  394. local cNum = #cards
  395. -- print("-------------------------checkPlan num: "..cNum)
  396. if not shaoDai then--是否少带
  397. if cNum~=6 and cNum~=10 and cNum~=15 then return false end
  398. end
  399. if cards and type(cards)~="table" then return false end
  400. if #cards < LessNum then return false end--或者牌张数不够
  401. local classify = self:classifyCards(cards)
  402. local result = false
  403. local ThreeCount = 0
  404. local TowCount = 0
  405. local checkShun = {}
  406. local isHaveGui,guiNum = self:checkHaveGui(classify)
  407. if self.isChai then--区分炸弹是否可拆
  408. for _,v in ipairs(classify) do
  409. if #v >= 3 then
  410. ThreeCount = ThreeCount + 1
  411. table.insert(checkShun, v[1])
  412. end
  413. end
  414. else
  415. for _,v in ipairs(classify) do
  416. if #v == 3 then
  417. ThreeCount = ThreeCount + 1
  418. table.insert(checkShun, v[1])
  419. end
  420. if #v == 2 then
  421. TowCount = TowCount + 1
  422. end
  423. end
  424. if guiNum == 1 and ThreeCount == 1 and TowCount >= 1 then
  425. return true
  426. elseif guiNum == 2 and (ThreeCount == 1 or TowCount >= 2) then
  427. return true
  428. elseif guiNum == 3 and (ThreeCount == 1 or TowCount >= 1) then
  429. return true
  430. end
  431. end
  432. if ThreeCount <= 1 then return false end
  433. if #checkShun >= 2 then
  434. table.sort(checkShun, sortCardsFunc)
  435. end
  436. -- print("three count : " ..ThreeCount)
  437. if ThreeCount == 2 then
  438. result = (self:checkSZ(checkShun) and cNum<=10)
  439. elseif ThreeCount == 3 then
  440. result = (self:checkSZ(checkShun) and cNum<=15)
  441. if not result then--三张四张作为翅膀带出去
  442. local firstTwo = {checkShun[1], checkShun[2]}
  443. result = (self:checkSZ(firstTwo) and cNum<=10)
  444. if not result then
  445. local lastTwo = {checkShun[2], checkShun[3]}
  446. result = (self:checkSZ(lastTwo) and cNum<=10)
  447. end
  448. end
  449. else
  450. local maxLen = 1
  451. local bCount = 1
  452. local i, j=1, 2
  453. for i=1,#checkShun-1 do
  454. if checkShun[i].val + 1 == checkShun[j].val then
  455. bCount = bCount + 1
  456. if bCount>maxLen then maxLen = bCount end
  457. else
  458. if bCount>maxLen then maxLen = bCount end
  459. bCount = 1
  460. end
  461. i=i+1
  462. j=j+1
  463. end
  464. result = maxLen>=3 and cNum<=15
  465. end
  466. return result
  467. end
  468. --牌型
  469. local OUT_TYPE = {
  470. SINGLE_CARD = 1, --//单牌
  471. DUI_ZI = 2, --//对子
  472. THREE = 3, --三个
  473. THREE_AND_TWO = 4, --//三带二张
  474. THREE_AND_DUI = 5, --//三带一对
  475. SHUN_ZI = 6, --//顺子
  476. LIAN_DUI = 7, --//连对(至少2连对)
  477. AIRPLANE = 8, --//飞机
  478. AIRPLANE_TOW = 9, --//飞机带散牌
  479. AIRPLANE_DUI = 10, --//飞机带对
  480. BOMB = 11, --//炸弹
  481. NONE = 100, --不适用类型
  482. }
  483. local TYPE_STRING = {
  484. [OUT_TYPE.SINGLE_CARD] = "单牌", --//单牌
  485. [OUT_TYPE.DUI_ZI] = "对子", --//对子
  486. [OUT_TYPE.THREE] = "三不带", --//三个
  487. [OUT_TYPE.THREE_AND_TWO] = "三带二", --//三带二
  488. [OUT_TYPE.THREE_AND_DUI] = "三带一对", --//三带一对
  489. [OUT_TYPE.SHUN_ZI] = "顺子", --//顺子
  490. [OUT_TYPE.LIAN_DUI] = "连对", --//连对
  491. [OUT_TYPE.AIRPLANE] = "飞机", --//飞机
  492. [OUT_TYPE.AIRPLANE_TOW] = "飞机", --//飞机
  493. [OUT_TYPE.AIRPLANE_DUI] = "飞机", --//飞机
  494. [OUT_TYPE.BOMB] = "炸弹", --//炸弹
  495. [OUT_TYPE.NONE] = "错误类型", --//错误类型
  496. }
  497. luzhouPokerUtil.OUT_TYPE = OUT_TYPE
  498. function luzhouPokerUtil:getTypeString( tp )
  499. return TYPE_STRING[tp] or "TP错误"
  500. end
  501. --获取一张服务器下发的牌值装换成客户端用到的牌值
  502. function luzhouPokerUtil:getCardValue( card )
  503. local tp, val = pokerParse(card)
  504. return val
  505. end
  506. --[[-- 检测牌型
  507. function luzhouPokerUtil:checkType( cards )
  508. local cNum = #cards
  509. if cNum <= 0 then return OUT_TYPE.NONE end
  510. if cNum == 1 then return OUT_TYPE.SINGLE_CARD end
  511. local parseData = {}
  512. for _,v in ipairs(cards) do
  513. local tp, val = pokerParse(v)
  514. table.insert(parseData, {tp=tp, val=val, cid=v})
  515. end
  516. if #parseData >=2 then
  517. table.sort(parseData, sortCardsFunc)
  518. end
  519. local tt = {}
  520. local ttt = {}
  521. local tpCardinfo = {}
  522. local classify = self:classifyCardsEx(parseData)
  523. local isHaveGui,guiNum = self:checkHaveGui(classify)
  524. for i,v in pairs(parseData) do
  525. if v.val ~= GUI_VAL then
  526. table.insert(tt,v.val)
  527. table.insert(ttt,v)
  528. end
  529. end
  530. local function tsort(a,b)
  531. return a > b
  532. end
  533. table.sort(tt, tsort)
  534. table.sort(ttt, sortCardsFunc)
  535. if (cNum+guiNum < 3) then
  536. if (tt[1] == tt[cNum]) then
  537. if cNum+guiNum == 1 then
  538. return OUT_TYPE.SINGLE_CARD
  539. elseif cNum+guiNum == 2 then
  540. return OUT_TYPE.DUI_ZI
  541. end
  542. end
  543. elseif (tt[1] == tt[cNum]) then
  544. if cNum+guiNum == 3 then
  545. return OUT_TYPE.THREE
  546. elseif cNum+guiNum == 4 then
  547. return OUT_TYPE.BOMB
  548. end
  549. else
  550. local a = {}
  551. for i=1,4 do
  552. a[i] = {}
  553. end
  554. local valueList = {}
  555. for k,v in pairs(cards) do
  556. local value = self:getCardValue(v)
  557. valueList[value] = valueList[value] or 0
  558. valueList[value] = valueList[value] + 1
  559. end
  560. for k,v in pairs(valueList) do
  561. table.insert(a[v],k)
  562. end
  563. if self:checkPlan(parseData) then
  564. return OUT_TYPE.AIRPLANE
  565. elseif self:checkShunzi(parseData) then
  566. return OUT_TYPE.SHUN_ZI
  567. end
  568. if cNum%2 == 0 then--偶数张 (三带一 连对 炸弹)
  569. if self:checkLianDui(parseData) then
  570. return OUT_TYPE.LIAN_DUI
  571. elseif self:checkBomb(parseData) then
  572. return OUT_TYPE.BOMB
  573. else
  574. return OUT_TYPE.NONE
  575. end
  576. else--奇数张 (三带二 顺子 四带一)
  577. if self:check3And2(parseData) then
  578. return OUT_TYPE.THREE_AND_TWO
  579. elseif self:checkShunzi(parseData) then
  580. return OUT_TYPE.SHUN_ZI
  581. else
  582. return OUT_TYPE.NONE
  583. end
  584. end
  585. end
  586. end--]]
  587. --[[-- 检测牌型
  588. function luzhouPokerUtil:checkType( cards )
  589. local cNum = #cards
  590. if cNum == 1 then return OUT_TYPE.SINGLE_CARD end
  591. local parseData = {}
  592. for _,v in ipairs(cards) do
  593. local tp, val = pokerParse(v)
  594. table.insert(parseData, {tp=tp, val=val, cid=v})
  595. end
  596. if #parseData >=2 then
  597. table.sort(parseData, sortCardsFunc)
  598. end
  599. if cNum == 2 then
  600. if self:checkDui(parseData) then
  601. return OUT_TYPE.DUI_ZI
  602. else
  603. return OUT_TYPE.NONE
  604. end
  605. elseif cNum == 3 then
  606. if self:checkThree(parseData) then
  607. return OUT_TYPE.THREE
  608. end
  609. return OUT_TYPE.NONE
  610. else
  611. --顺子 飞机
  612. if self:checkPlan(parseData) then
  613. if self:check4And3(parseData) and self.isFAT then
  614. return OUT_TYPE.FOUR_AND_THREE
  615. else
  616. return OUT_TYPE.AIRPLANE
  617. end
  618. elseif self:checkShunzi(parseData) then
  619. return OUT_TYPE.SHUN_ZI
  620. end
  621. if cNum%2 == 0 then--偶数张 (三带一 连对 炸弹)
  622. if self:check3And1(parseData) then
  623. return OUT_TYPE.THREE_AND_ONE
  624. elseif self:checkLianDui(parseData) then
  625. return OUT_TYPE.LIAN_DUI
  626. elseif self:checkBomb(parseData) then
  627. return OUT_TYPE.BOMB
  628. else
  629. return OUT_TYPE.NONE
  630. end
  631. else--奇数张 (三带二 顺子 四带一)
  632. if self:check3And2(parseData) then
  633. return OUT_TYPE.THREE_AND_TWO
  634. elseif self:checkShunzi(parseData) then
  635. return OUT_TYPE.SHUN_ZI
  636. elseif self:check4And1(parseData) then
  637. if self.isChai then--炸弹可拆则为3带2
  638. return OUT_TYPE.THREE_AND_TWO
  639. else
  640. return OUT_TYPE.NONE--OUT_TYPE.FOUR_AND_ONE
  641. end
  642. elseif self:check4And3(parseData) then
  643. return OUT_TYPE.FOUR_AND_THREE
  644. else
  645. return OUT_TYPE.NONE
  646. end
  647. end
  648. end
  649. end--]]
  650. function luzhouPokerUtil:getGuiByClassifyCards( classify )
  651. for valStr,cds in pairs(classify) do
  652. if tonumber(valStr) == GUI_VAL then
  653. return cds
  654. end
  655. end
  656. return {}
  657. end
  658. --------------------------------------------------------------------------------------
  659. -- 牌型提示
  660. --------------------------------------------------------------------------------------
  661. --单张提示 cards@{{tp=, val=, cid=,}...} target@{tp=, val=, cid=,}
  662. -- fixed
  663. function luzhouPokerUtil:getSingleTip( cards, target )
  664. local target = target[1]
  665. if target.val == ER_VAL or target.val == GUI_VAL then return nil end
  666. local classify = self:classifyCardsEx(cards)
  667. local singles = {}
  668. local twos = {}
  669. local threes = {}
  670. local fours = {}
  671. for valStr,cds in pairs(classify) do
  672. if tonumber(valStr) > target.val or tonumber(valStr)==ER_VAL or tonumber(valStr)==GUI_VAL then
  673. if #cds == 1 then
  674. table.insert(singles, cds[1])
  675. elseif #cds == 2 then
  676. table.insert(twos, cds[1])
  677. table.insert(twos, cds[2])
  678. elseif #cds == 3 then
  679. table.insert(threes, cds[1])
  680. table.insert(threes, cds[2])
  681. table.insert(threes, cds[3])
  682. elseif #cds == 4 then--炸弹是否可拆决定
  683. if self.isChai then
  684. table.insert(threes, cds[1])
  685. table.insert(threes, cds[2])
  686. table.insert(threes, cds[3])
  687. table.insert(threes, cds[4])
  688. end
  689. end
  690. end
  691. end
  692. if #singles>=2 then --降序排列
  693. table.sort(singles, function ( a, b ) return a.val > b.val end)
  694. end
  695. if #twos>=2 then --升序排列
  696. table.sort(twos, function ( a, b ) return a.val < b.val end)
  697. end
  698. if #threes>=2 then --升序排列
  699. table.sort(threes, function ( a, b ) return a.val < b.val end)
  700. end
  701. for _,v in ipairs(twos) do
  702. table.insert(singles, 1, v)
  703. end
  704. for _,v in ipairs(threes) do
  705. table.insert(singles, 1, v)
  706. end
  707. return singles
  708. end
  709. -- 对子提示cards@{{tp=, val=, cid=,}...} targets@{{tp=, val=, cid=,},{tp=, val=, cid=,}}
  710. -- fixed
  711. function luzhouPokerUtil:getDoubleTip( cards, targets )
  712. local target = targets[1]
  713. if target.val >= ER_VAL then return nil end
  714. local classify = self:classifyCardsEx(cards)
  715. local isHaveGui,guiNum = self:checkHaveGui(classify)
  716. local sigle = {}
  717. local twos = {}
  718. local threes = {}
  719. local fours = {}
  720. local gui = self:getGuiByClassifyCards(classify)
  721. for valStr,cds in pairs(classify) do
  722. if tonumber(valStr) > target.val and #cds>=2 then
  723. if #cds == 2 then
  724. table.insert(twos, cds)
  725. elseif #cds == 3 then
  726. table.insert(threes, clone({cds[1], cds[2]}))
  727. elseif #cds == 4 then--炸弹是否可拆决定
  728. if self.isChai then
  729. table.insert(fours, clone({cds[1], cds[2]}))
  730. end
  731. end
  732. else
  733. if guiNum > 0 and #gui > 0 and tonumber(valStr) > target.val and tonumber(valStr) ~= GUI_VAL then
  734. table.insert(sigle, clone({cds[1], gui[1]}))
  735. end
  736. end
  737. end
  738. if #twos>=2 then --降序排列
  739. table.sort(twos, function ( a, b ) return a[1].val > b[1].val end)
  740. end
  741. if #sigle>=2 then --升序排列
  742. table.sort(sigle, function ( a, b ) return a[1].val < b[1].val end)
  743. end
  744. if #threes>=2 then --升序排列
  745. table.sort(threes, function ( a, b ) return a[1].val < b[1].val end)
  746. end
  747. if #fours>=2 then --升序排列
  748. table.sort(fours, function ( a, b ) return a[1].val < b[1].val end)
  749. end
  750. for _,v in ipairs(sigle) do
  751. table.insert(twos, 1, v)
  752. end
  753. for _,v in ipairs(threes) do
  754. table.insert(twos, 1, v)
  755. end
  756. for _,v in pairs(fours) do
  757. table.insert(twos, 1, v)
  758. end
  759. return twos
  760. end
  761. -- 三张提示
  762. -- fixed
  763. function luzhouPokerUtil:getThreeTip( cards, targets )
  764. local minVal = self:getCardsMin(targets,OUT_TYPE.THREE)
  765. local targetNum = #targets
  766. local cclassify = self:classifyCardsEx(cards)
  767. local isHaveGui,guiNum = self:checkHaveGui(cclassify)
  768. local gui = self:getGuiByClassifyCards(cclassify)
  769. if #cards < 3 then return end
  770. local valueList = {}
  771. local cardList = {}
  772. for k,v in ipairs(cards) do
  773. local value = v.val
  774. if v ~= GUI_VAL then
  775. valueList[value] = valueList[value] or 0
  776. valueList[value] = valueList[value] + 1
  777. cardList[value] = cardList[value] or {}
  778. table.insert(cardList[value], v)
  779. end
  780. end
  781. local result ={}
  782. for i = minVal + 1, 13 do
  783. local _tpIdx = i;
  784. local _tpCount = 0;
  785. local _tpReplace2 = {}
  786. local tpNotAllLai = false;
  787. local _haveLai = guiNum;
  788. valueList[_tpIdx] = valueList[_tpIdx] or 0;
  789. if valueList[_tpIdx] + _haveLai >= 3 then
  790. local _tpNum = 3 - valueList[_tpIdx];
  791. _tpNum = _tpNum >= 0 and _tpNum or 0;
  792. local lai = guiNum - _haveLai + 1
  793. for p = 1, _tpNum do
  794. table.insert(_tpReplace2,gui[lai])
  795. lai = lai + 1
  796. end
  797. for _m = 1, 3 - _tpNum do
  798. table.insert(_tpReplace2, cardList[_tpIdx][_m])
  799. tpNotAllLai = true;
  800. end
  801. _haveLai = _haveLai - _tpNum;
  802. _tpCount = _tpCount + 3
  803. _tpIdx = _tpIdx + 1
  804. if _tpCount == 3 then
  805. table.insert(result,_tpReplace2)
  806. end
  807. end
  808. end;
  809. local resultex = {}
  810. if #result > 0 then
  811. for i = #result,1,-1 do
  812. table.insert(resultex,result[i])
  813. end
  814. end
  815. return resultex
  816. --[[if #cards < #targets then return nil end
  817. local tclassify = self:classifyCards(targets)
  818. local ttarget1 = self:getSameNum(tclassify, 3)
  819. local target
  820. if next(ttarget1) ~= nil then
  821. target = ttarget1[1][1]
  822. else
  823. local ttarget2 = self:getSameNum(tclassify, 2)
  824. if guiNum == 1 then
  825. target = ttarget2[1][1]
  826. elseif guiNum == 2 then
  827. local ttarget3 = self:getSameNum(tclassify, 1)
  828. target = ttarget3[1][1]
  829. elseif guiNum == 3 then
  830. target = {["tp"] = 0,["cid"] = 14,["val"] = 14}
  831. end
  832. end
  833. local classify = self:classifyCardsEx(cards)
  834. local isHaveGui,guiNum = self:checkHaveGui(classify)
  835. local threes = {}
  836. local singles = {}
  837. local twos = {}
  838. local fours = {}
  839. local gui = self:getGuiByClassifyCards(classify)
  840. for valStr,cds in pairs(classify) do
  841. if tonumber(valStr) > target.val and #cds>=3 then
  842. if #cds == 3 then
  843. table.insert(threes, cds)
  844. elseif #cds == 4 then--炸弹是否可拆决定
  845. --if self.isChai then
  846. table.insert(threes, {cds[1], cds[2], cds[3]})
  847. --end
  848. end
  849. else
  850. if #cds == 1 then
  851. table.insert(singles, cds[1])
  852. if guiNum > 1 and #gui > 1 and tonumber(valStr) > target.val and tonumber(valStr) ~= GUI_VAL then
  853. table.insert(threes, {cds[1], gui[1], gui[2]})
  854. end
  855. elseif #cds == 2 then
  856. table.insert(twos, cds)
  857. if guiNum > 0 and #gui > 0 and tonumber(valStr) > target.val and tonumber(valStr) ~= GUI_VAL then
  858. table.insert(threes, {cds[1], cds[2], gui[1]})
  859. end
  860. elseif #cds == 4 then
  861. table.insert(fours, cds)
  862. end
  863. end
  864. end
  865. if #threes <= 0 then return nil end
  866. if #threes>=2 then --降序排列
  867. table.sort(threes, function ( a, b ) return a[1].val > b[1].val end)
  868. end
  869. return threes--]]
  870. end
  871. -- 三带二提示
  872. -- fixed
  873. function luzhouPokerUtil:getThreeAnd2Tip( cards, targets )
  874. local minVal = self:getCardsMin(targets,OUT_TYPE.THREE_AND_TWO)
  875. local targetNum = #targets
  876. local cclassify = self:classifyCardsEx(cards)
  877. local isHaveGui,guiNum = self:checkHaveGui(cclassify)
  878. local gui = self:getGuiByClassifyCards(cclassify)
  879. if #cards < 5 then return end
  880. local valueList = {}
  881. local cardList = {}
  882. for k,v in ipairs(cards) do
  883. local value = v.val
  884. if v ~= GUI_VAL then
  885. valueList[value] = valueList[value] or 0
  886. valueList[value] = valueList[value] + 1
  887. cardList[value] = cardList[value] or {}
  888. table.insert(cardList[value], v)
  889. end
  890. end
  891. local result ={}
  892. for i = minVal + 1, 13 do
  893. local _tpIdx = i;
  894. local _tpCount = 0;
  895. local _tpReplace2 = {}
  896. local tpNotAllLai = false;
  897. local _haveLai = guiNum;
  898. valueList[_tpIdx] = valueList[_tpIdx] or 0;
  899. if valueList[_tpIdx] + _haveLai >= 3 then
  900. local _tpNum = 3 - valueList[_tpIdx];
  901. _tpNum = _tpNum >= 0 and _tpNum or 0;
  902. local lai = guiNum - _haveLai + 1
  903. for p = 1, _tpNum do
  904. table.insert(_tpReplace2,gui[lai])
  905. lai = lai + 1
  906. end
  907. for _m = 1, 3 - _tpNum do
  908. table.insert(_tpReplace2, cardList[_tpIdx][_m])
  909. tpNotAllLai = true;
  910. end
  911. _haveLai = _haveLai - _tpNum;
  912. _tpCount = _tpCount + 3
  913. _tpIdx = _tpIdx + 1
  914. if _tpCount == 3 then
  915. table.insert(result,_tpReplace2)
  916. end
  917. end
  918. end;
  919. local resultex = {}
  920. if #result > 0 then
  921. for i = #result,1,-1 do
  922. table.insert(resultex,result[i])
  923. end
  924. end
  925. return resultex
  926. end
  927. -- 三带一提示 not fixed
  928. function luzhouPokerUtil:getThreeAnd1Tip(cards, targets)
  929. local tclassify = self:classifyCards(targets)
  930. local target = self:getSameNum(tclassify, 3)
  931. local cclassify = self:classifyCards(cards)
  932. local tmps = self:getSameNum(cclassify, 3)
  933. if #tmps == 0 then return nil end
  934. local result = {}
  935. for _,v in ipairs(tmps) do
  936. if v[1].val > target[1].val then
  937. table.insert(result, v)
  938. end
  939. end
  940. local tmpOnes = self:getSameNum(cclassify, 1)
  941. local ones = {}
  942. for _,v in pairs(tmpOnes) do
  943. table.insert(ones, v[1])
  944. end
  945. local twos = self:getSameNum(cclassify, 2)
  946. for _,v in ipairs(twos) do
  947. table.insert(ones, v[1])
  948. table.insert(ones, v[2])
  949. end
  950. if #ones >=1 then
  951. return {result, ones[1]}
  952. else
  953. return nil
  954. end
  955. end
  956. -- 四带一提示
  957. function luzhouPokerUtil:getFourAnd1( cards, targets )
  958. local tclassify = self:classifyCards(targets)
  959. local target = self:getSameNum(tclassify, 4)
  960. local cclassify = self:classifyCards(cards)
  961. local tmps = self:getSameNum(cclassify, 4)
  962. if #tmps == 0 then return nil end
  963. local result = {}
  964. for _,v in ipairs(tmps) do
  965. if v[1].val > target[1].val then
  966. table.insert(result, v)
  967. end
  968. end
  969. local tmpOnes = self:getSameNum(cclassify, 1)
  970. local ones = {}
  971. for _,v in pairs(tmpOnes) do
  972. table.insert(ones, v[1])
  973. end
  974. local twos = self:getSameNum(cclassify, 2)
  975. for _,v in ipairs(twos) do
  976. table.insert(ones, v[1])
  977. table.insert(ones, v[2])
  978. end
  979. local threes = self:getSameNum(cclassify, 3)
  980. for _,v in ipairs(threes) do
  981. table.insert(ones, v[1])
  982. table.insert(ones, v[2])
  983. table.insert(ones, v[3])
  984. end
  985. if #ones >= 1 then
  986. return {result, ones[1]}
  987. else--牌不够数
  988. return nil
  989. end
  990. end
  991. -- 四带三提示(前提是牌足够)
  992. -- fixed
  993. function luzhouPokerUtil:getFourAnd3( cards, targets )
  994. if #cards < #targets then return nil end
  995. local tclassify = self:classifyCards(targets)
  996. local target = self:getSameNum(tclassify, 4)[1][1]
  997. local classify = self:classifyCardsEx(cards)
  998. local threes = {}
  999. local singles = {}
  1000. local twos = {}
  1001. local fours = {}
  1002. local targetFours = {}
  1003. for valStr,cds in pairs(classify) do
  1004. if tonumber(valStr) > target.val and #cds>=4 then
  1005. table.insert(targetFours, cds)
  1006. else
  1007. if #cds == 1 then
  1008. table.insert(singles, cds[1])
  1009. elseif #cds == 2 then
  1010. table.insert(twos, cds)
  1011. elseif #cds == 3 then
  1012. table.insert(threes, cds)
  1013. elseif #cds == 4 then
  1014. table.insert(fours, cds)
  1015. end
  1016. end
  1017. end
  1018. if #threes <= 0 then return nil end
  1019. if #targetFours>=2 then --降序排列
  1020. table.sort(targetFours, function ( a, b ) return a[1].val > b[1].val end)
  1021. end
  1022. if #singles>=2 then --升序排列
  1023. table.sort(singles, function ( a, b ) return a.val < b.val end)
  1024. end
  1025. if #twos>=2 then --升序排列
  1026. table.sort(twos, function ( a, b ) return a[1].val < b[1].val end)
  1027. end
  1028. if #threes>=2 then --升序排列
  1029. table.sort(threes, function ( a, b ) return a[1].val < b[1].val end)
  1030. end
  1031. for _,v in ipairs(twos) do
  1032. table.insert(singles, v[1])
  1033. table.insert(singles, v[2])
  1034. end
  1035. for _,v in ipairs(threes) do
  1036. table.insert(singles, v[1])
  1037. table.insert(singles, v[2])
  1038. table.insert(singles, v[3])
  1039. end
  1040. local result = {}
  1041. if #targetFours==1 then
  1042. if #singles >= 3 then
  1043. table.insert(targetFours[1], singles[1])
  1044. table.insert(targetFours[1], singles[2])
  1045. table.insert(targetFours[1], singles[3])
  1046. table.insert(result, targetFours[1])
  1047. return result
  1048. else
  1049. return nil
  1050. end
  1051. else
  1052. if #singles >= 3 then
  1053. for _,v in ipairs(targetFours) do
  1054. local cv = clone(v)
  1055. table.insert(v, singles[1])
  1056. table.insert(v, singles[2])
  1057. table.insert(v, singles[3])
  1058. table.insert(result, cv)
  1059. end
  1060. return result
  1061. else--多个四张,玩家自己拆牌
  1062. return targetFours
  1063. end
  1064. end
  1065. end
  1066. -- 检测牌组是否是连续的parseCards@sorted
  1067. function luzhouPokerUtil:getSubLine( parseCards )
  1068. local sub = {}
  1069. local tCards = self:classifyCards(parseCards)
  1070. local isHaveGui,guiNum = self:checkHaveGui(tCards)
  1071. for i=#parseCards,1,-1 do
  1072. if parseCards[i] and parseCards[i-1] and parseCards[i].val ~= GUI_VAL and parseCards[i-1].val ~= GUI_VAL then
  1073. if parseCards[i].val-1~=parseCards[i-1].val then
  1074. if guiNum > 0 then
  1075. guiNum = guiNum - 1
  1076. else
  1077. --断开了
  1078. local tmp = {}
  1079. for j=#parseCards,i,-1 do
  1080. table.insert(tmp, parseCards[j])
  1081. end
  1082. table.insert(sub, clone(tmp))
  1083. for j=#parseCards,i,-1 do
  1084. table.remove(parseCards, j)
  1085. end
  1086. end
  1087. else
  1088. if i == 2 then
  1089. table.insert(sub, clone(parseCards))
  1090. end
  1091. end
  1092. end
  1093. end
  1094. return sub
  1095. end
  1096. -- 从连续的牌组中获得顺子
  1097. function luzhouPokerUtil:getSzTip( hands, targets )
  1098. local tmpNoKey = clone(hands)
  1099. table.sort(targets, sortCardsFunc)
  1100. local minVal = targets[1].val
  1101. local targetNum = #targets
  1102. if #tmpNoKey<targetNum then return nil end
  1103. local count = #tmpNoKey-targetNum
  1104. if count == 0 then return {tmpNoKey} end
  1105. local getMS = function ( tab, len )
  1106. if #tab < len then return nil end
  1107. local rst = {}
  1108. for i=#tab,1,-1 do
  1109. if #rst<len then
  1110. table.insert(rst, 1, tab[i])
  1111. else
  1112. break
  1113. end
  1114. end
  1115. return rst
  1116. end
  1117. local result = {}
  1118. for i=#tmpNoKey,1,-1 do
  1119. local rst = getMS(tmpNoKey, targetNum)
  1120. if rst then
  1121. table.insert(result, 1, clone(rst))
  1122. table.remove(tmpNoKey, #tmpNoKey)
  1123. else
  1124. break
  1125. end
  1126. end
  1127. return result
  1128. end
  1129. -- 顺子提示
  1130. -- fixed
  1131. function luzhouPokerUtil:getShunziTip( cards, targets )
  1132. local minVal = self:getCardsMin(targets,OUT_TYPE.SHUN_ZI)
  1133. local targetNum = #targets
  1134. local cclassify = self:classifyCardsEx(cards)
  1135. local isHaveGui,guiNum = self:checkHaveGui(cclassify)
  1136. local gui = self:getGuiByClassifyCards(cclassify)
  1137. local isHaveA = false
  1138. if targets and next(targets) ~= nil then
  1139. for i,v in pairs(targets) do
  1140. if v.val == 12 then
  1141. isHaveA = true
  1142. end
  1143. end
  1144. end
  1145. local isMinSz = (minVal == 0 and isHaveA)
  1146. local valueList = {}
  1147. local cardList = {}
  1148. for k,v in ipairs(cards) do
  1149. local value = v.val
  1150. if v ~= GUI_VAL then
  1151. valueList[value] = valueList[value] or 0
  1152. valueList[value] = valueList[value] + 1
  1153. cardList[value] = cardList[value] or {}
  1154. table.insert(cardList[value], v)
  1155. end
  1156. end
  1157. local result ={}
  1158. for i = minVal + 1, 13 - targetNum do
  1159. local _tpIdx = i;
  1160. local _tpCount = 0;
  1161. local _tpReplace2 = {}
  1162. local tpNotAllLai = false;
  1163. local _haveLai = guiNum;
  1164. while _tpCount < #cards and _tpCount < targetNum and _tpIdx <= 12 do
  1165. valueList[_tpIdx] = valueList[_tpIdx] or 0;
  1166. if (not (valueList[_tpIdx] + _haveLai >= 1)) then break end;
  1167. local _tpNum = 1 - valueList[_tpIdx];
  1168. _tpNum = _tpNum >= 0 and _tpNum or 0;
  1169. local lai = guiNum - _haveLai + 1
  1170. for p = 1, _tpNum do
  1171. table.insert(_tpReplace2,gui[lai])
  1172. lai = lai + 1
  1173. end
  1174. for _m = 1, 1 - _tpNum do
  1175. table.insert(_tpReplace2, cardList[_tpIdx][_m])
  1176. tpNotAllLai = true;
  1177. end
  1178. _haveLai = _haveLai - _tpNum;
  1179. _tpCount = _tpCount + 1;
  1180. _tpIdx = _tpIdx + 1
  1181. end
  1182. if _tpCount == targetNum then
  1183. table.insert(result,_tpReplace2)
  1184. end
  1185. end
  1186. targetNum = targetNum - 1
  1187. valueList[13] = valueList[13] or 0
  1188. if isMinSz and (valueList[13] and valueList[13] > 0) then--找一下少一张牌的然后补2
  1189. for i = minVal + 1, 13 - targetNum do
  1190. local _tpIdx = i;
  1191. local _tpCount = 0;
  1192. local _tpReplace2 = {}
  1193. local tpNotAllLai = false;
  1194. local _haveLai = guiNum;
  1195. while _tpCount < #cards and _tpCount < targetNum and _tpIdx <= 12 do
  1196. valueList[_tpIdx] = valueList[_tpIdx] or 0;
  1197. if (not (valueList[_tpIdx] + _haveLai >= 1)) then break end;
  1198. local _tpNum = 1 - valueList[_tpIdx];
  1199. _tpNum = _tpNum >= 0 and _tpNum or 0;
  1200. local lai = guiNum - _haveLai + 1
  1201. for p = 1, _tpNum do
  1202. table.insert(_tpReplace2,gui[lai])
  1203. lai = lai + 1
  1204. end
  1205. for _m = 1, 1 - _tpNum do
  1206. table.insert(_tpReplace2, cardList[_tpIdx][_m])
  1207. tpNotAllLai = true;
  1208. end
  1209. _haveLai = _haveLai - _tpNum;
  1210. _tpCount = _tpCount + 1;
  1211. _tpIdx = _tpIdx + 1
  1212. end
  1213. if _tpCount == targetNum then
  1214. if _tpReplace2[1].val == 1 or (_tpReplace2[targetNum-1].val == targetNum and _tpReplace2[targetNum].val == 14 ) then
  1215. if cardList[13] and cardList[13][1] then
  1216. table.insert(_tpReplace2, cardList[13][1])--补一张2
  1217. table.insert(result,_tpReplace2)
  1218. end
  1219. end
  1220. end
  1221. end
  1222. end
  1223. local resultex = {}
  1224. if #result > 0 then
  1225. for i = #result,1,-1 do
  1226. table.insert(resultex,result[i])
  1227. end
  1228. end
  1229. return resultex
  1230. end
  1231. -- 获取连对提示
  1232. -- fixed
  1233. function luzhouPokerUtil:getLianduiTip( cards, targets )
  1234. local minVal = self:getCardsMin(targets,OUT_TYPE.LIAN_DUI)
  1235. local targetNum = #targets
  1236. local cclassify = self:classifyCardsEx(cards)
  1237. local isHaveGui,guiNum = self:checkHaveGui(cclassify)
  1238. local gui = self:getGuiByClassifyCards(cclassify)
  1239. local valueList = {}
  1240. local cardList = {}
  1241. for k,v in ipairs(cards) do
  1242. local value = v.val
  1243. if v ~= GUI_VAL then
  1244. valueList[value] = valueList[value] or 0
  1245. valueList[value] = valueList[value] + 1
  1246. cardList[value] = cardList[value] or {}
  1247. table.insert(cardList[value], v)
  1248. end
  1249. end
  1250. local result ={}
  1251. for i = minVal + 1, 14 - targetNum/2 do
  1252. local _tpIdx = i;
  1253. local _tpCount = 0;
  1254. local _tpReplace2 = {}
  1255. local tpNotAllLai = false;
  1256. local _haveLai = guiNum;
  1257. while _tpCount < #cards and _tpCount < targetNum and _tpIdx <= 12 do
  1258. valueList[_tpIdx] = valueList[_tpIdx] or 0;
  1259. if (not (valueList[_tpIdx] + _haveLai >= 2)) then break end;
  1260. local _tpNum = 2 - valueList[_tpIdx];
  1261. _tpNum = _tpNum >= 0 and _tpNum or 0;
  1262. local lai = guiNum - _haveLai + 1
  1263. for p = 1, _tpNum do
  1264. table.insert(_tpReplace2,gui[lai])
  1265. lai = lai + 1
  1266. end
  1267. for _m = 1, 2 - _tpNum do
  1268. table.insert(_tpReplace2, cardList[_tpIdx][_m])
  1269. tpNotAllLai = true;
  1270. end
  1271. _haveLai = _haveLai - _tpNum;
  1272. _tpCount = _tpCount + 2;
  1273. _tpIdx = _tpIdx + 1
  1274. end
  1275. if _tpCount == targetNum then
  1276. table.insert(result,_tpReplace2)
  1277. end
  1278. end
  1279. if minVal == 0 and targetNum == 4 then--如果出的是aa22,则加上2233的提示
  1280. local _haveLai = guiNum;
  1281. local _tpCount = 0;
  1282. local _tpReplace2 = {}
  1283. valueList[13] = valueList[13] or 0;
  1284. if (valueList[13] + _haveLai >= 2) then
  1285. local _tpNum = 2 - valueList[13];
  1286. _tpNum = _tpNum >= 0 and _tpNum or 0;
  1287. local lai = guiNum - _haveLai + 1
  1288. for p = 1, _tpNum do
  1289. table.insert(_tpReplace2,gui[lai])
  1290. lai = lai + 1
  1291. end
  1292. for _m = 1, 2 - _tpNum do
  1293. table.insert(_tpReplace2, cardList[13][_m])
  1294. end
  1295. _haveLai = _haveLai - _tpNum;
  1296. _tpCount = _tpCount + 2;
  1297. end
  1298. valueList[1] = valueList[1] or 0;
  1299. if (valueList[1] + _haveLai >= 2) then
  1300. local _tpNum = 2 - valueList[1];
  1301. _tpNum = _tpNum >= 0 and _tpNum or 0;
  1302. local lai = guiNum - _haveLai + 1
  1303. for p = 1, _tpNum do
  1304. table.insert(_tpReplace2,gui[lai])
  1305. lai = lai + 1
  1306. end
  1307. for _m = 1, 2 - _tpNum do
  1308. table.insert(_tpReplace2, cardList[1][_m])
  1309. end
  1310. _haveLai = _haveLai - _tpNum;
  1311. _tpCount = _tpCount + 2;
  1312. end
  1313. if _tpCount == targetNum and valueList[13] > 0 and valueList[1] > 0 then
  1314. table.insert(result,_tpReplace2)
  1315. end
  1316. end
  1317. local resultex = {}
  1318. if #result > 0 then
  1319. for i = #result,1,-1 do
  1320. table.insert(resultex,result[i])
  1321. end
  1322. end
  1323. return resultex
  1324. end
  1325. -- 获取炸弹提示
  1326. function luzhouPokerUtil:getBombTip( cards, targets )
  1327. local minVal = self:getCardsMin(targets,OUT_TYPE.BOMB)
  1328. local cclassify = self:classifyCardsEx(cards)
  1329. local isHaveGui,guiNum = self:checkHaveGui(cclassify)
  1330. local gui = self:getGuiByClassifyCards(cclassify)
  1331. local valueList = {}
  1332. local cardList = {}
  1333. for k,v in ipairs(cards) do
  1334. local value =v.val
  1335. if v ~= GUI_VAL then
  1336. valueList[value] = valueList[value] or 0
  1337. valueList[value] = valueList[value] + 1
  1338. cardList[value] = cardList[value] or {}
  1339. table.insert(cardList[value], v)
  1340. end
  1341. end
  1342. local result ={}
  1343. local _tpIndex = 1
  1344. for _i14 = minVal+1, 13 do
  1345. local _tpReplace4 = {}
  1346. valueList[_i14] = valueList[_i14] or 0
  1347. if (valueList[_i14] > 0 and valueList[_i14] + guiNum >= 4) then
  1348. local _tpNum4 = 4 - valueList[_i14];
  1349. _tpNum4 = _tpNum4 >= 0 and _tpNum4 or 0
  1350. for _l4 = 1, _tpNum4 do
  1351. table.insert(_tpReplace4,gui[_l4])
  1352. end
  1353. for _m4 = 1, 4 - _tpNum4 do
  1354. table.insert(_tpReplace4,cardList[_i14][_m4])
  1355. end
  1356. table.insert(result,_tpReplace4)
  1357. end
  1358. end
  1359. local resultex = {}
  1360. if #result > 0 then
  1361. for i = #result,1,-1 do
  1362. table.insert(resultex,result[i])
  1363. end
  1364. end
  1365. return resultex
  1366. end
  1367. -- 获取牌组中所有炸弹
  1368. function luzhouPokerUtil:getAllBomb( cards, isAaaBomb )
  1369. local parseHands = self:parseCards(cards)
  1370. local cclassify = self:classifyCardsEx(parseHands)
  1371. local isHaveGui,guiNum = self:checkHaveGui(cclassify)
  1372. local gui = self:getGuiByClassifyCards(cclassify)
  1373. local valueList = {}
  1374. local cardList = {}
  1375. for k,v in ipairs(parseHands) do
  1376. local value =v.val
  1377. if v ~= GUI_VAL then
  1378. valueList[value] = valueList[value] or 0
  1379. valueList[value] = valueList[value] + 1
  1380. cardList[value] = cardList[value] or {}
  1381. table.insert(cardList[value], v)
  1382. end
  1383. end
  1384. local result ={}
  1385. local _tpIndex = 1
  1386. for _i14 = 1, 13 do
  1387. local _tpReplace4 = {}
  1388. valueList[_i14] = valueList[_i14] or 0
  1389. if (valueList[_i14] > 0 and valueList[_i14] + guiNum >= 4) then
  1390. local _tpNum4 = 4 - valueList[_i14];
  1391. _tpNum4 = _tpNum4 >= 0 and _tpNum4 or 0
  1392. for _l4 = 1, _tpNum4 do
  1393. table.insert(_tpReplace4,gui[_l4])
  1394. end
  1395. for _m4 = 1, 4 - _tpNum4 do
  1396. table.insert(_tpReplace4,cardList[_i14][_m4])
  1397. end
  1398. table.insert(result,_tpReplace4)
  1399. end
  1400. end
  1401. return result
  1402. end
  1403. -- 获取飞机提示(手牌足够)
  1404. function luzhouPokerUtil:getPlanTip( cards, targets )
  1405. local minVal = self:getCardsMin(targets,OUT_TYPE.AIRPLANE)
  1406. local targetNum = #targets
  1407. local cclassify = self:classifyCardsEx(cards)
  1408. local isHaveGui,guiNum = self:checkHaveGui(cclassify)
  1409. local gui = self:getGuiByClassifyCards(cclassify)
  1410. local valueList = {}
  1411. local cardList = {}
  1412. for k,v in ipairs(cards) do
  1413. local value = v.val
  1414. if v ~= GUI_VAL then
  1415. valueList[value] = valueList[value] or 0
  1416. valueList[value] = valueList[value] + 1
  1417. cardList[value] = cardList[value] or {}
  1418. table.insert(cardList[value], v)
  1419. end
  1420. end
  1421. local result ={}
  1422. local needCardNum = 6
  1423. if targetNum == 9 then
  1424. needCardNum = 9
  1425. elseif targetNum == 12 then
  1426. needCardNum = 12
  1427. end
  1428. for i = minVal + 1, 14 - needCardNum/3 do
  1429. local _tpIdx = i;
  1430. local _tpCount = 0;
  1431. local _tpReplace2 = {}
  1432. local tpNotAllLai = false;
  1433. local _haveLai = guiNum;
  1434. while _tpCount < #cards and _tpCount < needCardNum and _tpIdx <= 12 do
  1435. valueList[_tpIdx] = valueList[_tpIdx] or 0;
  1436. if (not (valueList[_tpIdx] + _haveLai >= 3)) then break end;
  1437. local _tpNum = 3 - valueList[_tpIdx];
  1438. _tpNum = _tpNum >= 0 and _tpNum or 0;
  1439. local lai = guiNum - _haveLai + 1
  1440. for p = 1, _tpNum do
  1441. table.insert(_tpReplace2,gui[lai])
  1442. lai = lai + 1
  1443. end
  1444. for _m = 1, 3 - _tpNum do
  1445. table.insert(_tpReplace2, cardList[_tpIdx][_m])
  1446. tpNotAllLai = true;
  1447. end
  1448. _haveLai = _haveLai - _tpNum;
  1449. _tpCount = _tpCount + 3;
  1450. _tpIdx = _tpIdx + 1
  1451. end
  1452. if _tpCount == needCardNum or (_tpCount == 6 and needCardNum == 10) then
  1453. function checkIsHaveA2(tmptb)--判断是否有a2
  1454. if tmptb and next(tmptb) ~= nil then
  1455. local isHaveA = false
  1456. local isHave2 = false
  1457. for i,v in pairs(tmptb) do
  1458. if v.val == 12 then
  1459. isHaveA = true
  1460. elseif v.val == 13 then
  1461. isHave2 = true
  1462. end
  1463. end
  1464. return isHaveA and isHave2
  1465. end
  1466. end
  1467. if _tpCount == 6 and checkIsHaveA2(_tpReplace2) then--3顺aaa222最小
  1468. else
  1469. table.insert(result,_tpReplace2)
  1470. end
  1471. end
  1472. end
  1473. local resultex = {}
  1474. if #result > 0 then
  1475. for i = #result,1,-1 do
  1476. table.insert(resultex,result[i])
  1477. end
  1478. end
  1479. return resultex
  1480. --[[local tclassify = self:classifyCards(targets)
  1481. local target = self:getSameNum(tclassify, 3)
  1482. local cclassify = self:classifyCards(cards)
  1483. local tmps = self:getSameNumEx(cclassify, 3)
  1484. if #target > #tmps then return nil end
  1485. local tmpThree = {}
  1486. for _,v in pairs(tmps) do
  1487. if v[1].val > target[1][1].val then
  1488. while #v>3 do
  1489. table.remove(v, #v)
  1490. end
  1491. table.insert(tmpThree, v)
  1492. end
  1493. end
  1494. if #tmpThree > 1 then
  1495. table.sort(tmpThree, function ( a, b ) return a[1].val < b[1].val end)
  1496. end
  1497. local tmp = {}--一维数组
  1498. for _,v in pairs(tmpThree) do
  1499. for _,c in ipairs(v) do
  1500. table.insert(tmp, c)
  1501. end
  1502. end
  1503. if #target > #tmpThree then return nil end
  1504. if #target == 2 then--两组
  1505. if #tmpThree > 2 then
  1506. local t = {}
  1507. t = {tmpThree[1], tmpThree[2]}
  1508. tmpThree = clone(t)
  1509. end
  1510. if math.abs(tmpThree[1][1].val-tmpThree[2][1].val)==1 then
  1511. local left = getLeft(cards, tmp)
  1512. if #left<4 then
  1513. return nil
  1514. else
  1515. local tail = clone(left)
  1516. while #tail>4 do
  1517. table.remove(tail, #tail)
  1518. end
  1519. for _,v in pairs(tmpThree) do
  1520. for _,c in pairs(v) do
  1521. table.insert(tail, c)
  1522. end
  1523. end
  1524. return {tail}
  1525. end
  1526. else
  1527. return nil
  1528. end
  1529. elseif #target == 3 then--三组
  1530. if #tmpThree > 3 then
  1531. local t = {}
  1532. t = {tmpThree[1], tmpThree[2], tmpThree[3]}
  1533. tmpThree = clone(t)
  1534. end
  1535. if self:checkSZ({tmpThree[1][1], tmpThree[2][1], tmpThree[3][1]}) then
  1536. local left = getLeft(cards, tmp)
  1537. if #left<4 then
  1538. return nil
  1539. else
  1540. local tail = clone(left)
  1541. while #tail>6 do
  1542. table.remove(tail, #tail)
  1543. end
  1544. return {tmpThree, tail}
  1545. end
  1546. else
  1547. return nil
  1548. end
  1549. end
  1550. return nil --]]
  1551. end
  1552. -- 获取牌型提示
  1553. function luzhouPokerUtil:getOnlyTip( handCards, cards )
  1554. if #handCards < #cards then return nil end
  1555. local parseHands = self:parseCards(handCards)
  1556. local parseCards = self:parseCards(cards)
  1557. local tp = self:checkType(cards)
  1558. if tp >= OUT_TYPE.NONE then
  1559. return nil
  1560. end
  1561. local result = nil
  1562. if tp == OUT_TYPE.SINGLE_CARD then
  1563. result = self:getSingleTip(parseHands, parseCards)
  1564. elseif tp == OUT_TYPE.DUI_ZI then
  1565. result = self:getDoubleTip(parseHands, parseCards)
  1566. elseif tp == OUT_TYPE.THREE then
  1567. result = self:getThreeTip(parseHands, parseCards)
  1568. elseif tp == OUT_TYPE.THREE_AND_TWO or tp == OUT_TYPE.THREE_AND_DUI then
  1569. result = self:getThreeAnd2Tip(parseHands, parseCards)
  1570. elseif tp == OUT_TYPE.SHUN_ZI then
  1571. result = self:getShunziTip(parseHands, parseCards)
  1572. elseif tp == OUT_TYPE.LIAN_DUI then
  1573. result = self:getLianduiTip(parseHands, parseCards)
  1574. if result==nil then return nil end
  1575. local tmp = {}
  1576. for _,group in ipairs(result) do
  1577. local t = {}
  1578. for _,vv in ipairs(group) do
  1579. for _,v in ipairs(vv) do
  1580. table.insert(t, v)
  1581. end
  1582. end
  1583. table.insert(tmp, clone(t))
  1584. end
  1585. result = tmp
  1586. -- return tmp
  1587. elseif tp == OUT_TYPE.AIRPLANE then
  1588. result = self:getPlanTip(parseHands, parseCards)
  1589. elseif tp == OUT_TYPE.FOUR_AND_THREE then
  1590. result = self:getFourAnd3(parseHands, parseCards)
  1591. elseif tp == OUT_TYPE.BOMB then
  1592. result = self:getBombTip(parseHands, parseCards)
  1593. elseif tp == OUT_TYPE.FOUR_AND_ONE then
  1594. result = self:getFourAnd1(parseHands, parseCards)
  1595. end
  1596. if tp~= OUT_TYPE.BOMB then
  1597. local bombs = self:getAllBomb(handCards)
  1598. if #bombs==1 then
  1599. if result then
  1600. table.insert(result, bombs[1])
  1601. --[[for _,v in pairs(bombs) do
  1602. end]]--
  1603. else
  1604. result={bombs[1]}
  1605. --result = bombs[1]
  1606. end
  1607. end
  1608. end
  1609. if result and #result==1 then
  1610. return result
  1611. end
  1612. return nil
  1613. end
  1614. -- 获取只有一种牌型提示
  1615. function luzhouPokerUtil:getTip( handCards, cards )
  1616. if #handCards < #cards then return nil end
  1617. if app.room.isMustBomb and app.room.isMustBomb == 1 then return nil end
  1618. local parseHands = self:parseCards(handCards)
  1619. local parseCards = self:parseCards(cards)
  1620. local tp = self:checkType(cards)
  1621. if app.room.lastOutType and app.room.lastOutType >0 and app.room.lastOutType < OUT_TYPE.NONE then
  1622. tp = app.room.lastOutType
  1623. end
  1624. if tp >= OUT_TYPE.NONE then
  1625. return nil
  1626. end
  1627. if tp == OUT_TYPE.SINGLE_CARD then
  1628. return self:getSingleTip(parseHands, parseCards)
  1629. elseif tp == OUT_TYPE.DUI_ZI then
  1630. local result = self:getDoubleTip(parseHands, parseCards)
  1631. return result
  1632. elseif tp == OUT_TYPE.THREE then
  1633. return self:getThreeTip(parseHands, parseCards)
  1634. elseif tp == OUT_TYPE.THREE_AND_TWO or tp == OUT_TYPE.THREE_AND_DUI then
  1635. return self:getThreeAnd2Tip(parseHands, parseCards)
  1636. elseif tp == OUT_TYPE.SHUN_ZI then
  1637. local result = self:getShunziTip(parseHands, parseCards)
  1638. return result
  1639. elseif tp == OUT_TYPE.LIAN_DUI then
  1640. local result = self:getLianduiTip(parseHands, parseCards)
  1641. if result==nil then return nil end
  1642. --[[local tmp = {}
  1643. for _,group in ipairs(result) do
  1644. local t = {}
  1645. for _,vv in ipairs(group) do
  1646. for _,v in ipairs(vv) do
  1647. table.insert(t, v)
  1648. end
  1649. end
  1650. table.insert(tmp, clone(t))
  1651. end--]]
  1652. return result
  1653. elseif tp == OUT_TYPE.AIRPLANE or tp == OUT_TYPE.AIRPLANE_TOW or tp == OUT_TYPE.AIRPLANE_DUI then
  1654. return self:getPlanTip(parseHands, parseCards)
  1655. elseif tp == OUT_TYPE.FOUR_AND_THREE then
  1656. return self:getFourAnd3(parseHands, parseCards)
  1657. elseif tp == OUT_TYPE.BOMB then
  1658. return self:getBombTip(parseHands, parseCards)
  1659. elseif tp == OUT_TYPE.FOUR_AND_ONE then
  1660. return self:getFourAnd1(parseHands, parseCards)
  1661. else
  1662. return nil
  1663. end
  1664. end
  1665. -- 第一手出牌提示
  1666. function luzhouPokerUtil:getFirstTip( handCards )
  1667. if #handCards<=0 then return nil end
  1668. local parseHands = self:parseCards(handCards)
  1669. local classify = self:classifyCardsEx(parseHands)
  1670. local singles = {}
  1671. local fours = {}
  1672. for valStr,cds in pairs(classify) do
  1673. if #cds == 1 then
  1674. table.insert(singles, cds)
  1675. elseif #cds == 2 then
  1676. table.insert(singles, cds)
  1677. elseif #cds == 3 then
  1678. table.insert(singles, cds)
  1679. elseif #cds == 4 then
  1680. table.insert(fours, cds)
  1681. end
  1682. end
  1683. if #singles > 0 then
  1684. if #singles>=2 then
  1685. table.sort(singles, function ( a, b )
  1686. return a[1].val > b[1].val
  1687. end)
  1688. end
  1689. return singles
  1690. else
  1691. if #fours>0 then
  1692. return fours
  1693. end
  1694. end
  1695. end
  1696. -- 检测最后一手牌能否一次出完
  1697. function luzhouPokerUtil:checkOnceOut( handCards )
  1698. local tp = self:checkType(handCards) or OUT_TYPE.NONE
  1699. if tp == OUT_TYPE.THREE_AND_TWO then
  1700. --[[if self.isChai then --将3带2还原成4带1
  1701. local parseHands = self:parseCards(handCards)
  1702. if self:check4And1(parseHands) then
  1703. tp = OUT_TYPE.FOUR_AND_ONE
  1704. end
  1705. end--]]
  1706. end
  1707. if tp == OUT_TYPE.AIRPLANE then--还原4带3
  1708. --[[if self.isFAT then
  1709. local parseHands = self:parseCards(handCards)
  1710. if self:check4And3(parseHands) then
  1711. tp = OUT_TYPE.FOUR_AND_THREE
  1712. end
  1713. end--]]
  1714. end
  1715. print("----------------------------------once out : ", tp)
  1716. if tp and (tp < OUT_TYPE.NONE) then
  1717. return (tp==OUT_TYPE.SINGLE_CARD
  1718. or tp==OUT_TYPE.DUI_ZI
  1719. or tp==OUT_TYPE.SHUN_ZI
  1720. or tp==OUT_TYPE.THREE_AND_TWO
  1721. or tp==OUT_TYPE.THREE_AND_DUI
  1722. or tp==OUT_TYPE.THREE
  1723. or tp==OUT_TYPE.LIAN_DUI
  1724. or tp==OUT_TYPE.AIRPLANE
  1725. or tp==OUT_TYPE.AIRPLANE_DUI
  1726. or tp==OUT_TYPE.AIRPLANE_TOW), tp
  1727. else--unwork dead code
  1728. --检测是否是三个带不全
  1729. if #handCards > 4 then
  1730. return false, tp
  1731. else
  1732. --不检测三带一
  1733. --[[local parseHands = self:parseCards(handCards)
  1734. local classify = self:classifyCards(parseHands)
  1735. local tmps = self:getSameNum(classify, 3)
  1736. if #tmps>=1 then
  1737. return true, tp
  1738. else
  1739. return false, tp
  1740. end--]]
  1741. end
  1742. end
  1743. return false , tp
  1744. end
  1745. -- 判断牌是否是手牌中最大的牌
  1746. function luzhouPokerUtil:isMaxCard(handCards, card)
  1747. local targetTp, targetVal = pokerParse(card)
  1748. local parseHands = self:parseCards(handCards)
  1749. local result = true
  1750. for _,v in pairs(parseHands) do
  1751. if v.val ~= GUI_VAL and v.val > targetVal then
  1752. result = false
  1753. break
  1754. end
  1755. end
  1756. return result
  1757. end
  1758. -- 检测是否拆了炸弹
  1759. function luzhouPokerUtil:isChaiBombs( handCards, selects )
  1760. local parseSelects = self:parseCards(selects)
  1761. --检测手上是否有炸弹
  1762. local bombs = self:getAllBomb(handCards)
  1763. if #bombs > 0 then
  1764. for _,bomb in pairs(bombs) do
  1765. if self:checkOwnX(parseSelects, bomb[1]) then
  1766. local classifySelects = self:classifyCardsEx(parseSelects)
  1767. local target = classifySelects[tostring(bomb[1].val)]
  1768. if #target < 4 then
  1769. return true
  1770. end
  1771. end
  1772. end
  1773. else
  1774. return false
  1775. end
  1776. return false
  1777. end
  1778. -- 判断三带不全出牌
  1779. function luzhouPokerUtil:checkThreeOut( handCards ,targets)
  1780. local parseHands = self:parseCards(handCards)
  1781. local parseTargets = self:parseCards(targets)
  1782. local handsThree = self:getSameNumExEx(parseHands)
  1783. local targetThree = self:getSameNumExEx(parseTargets)
  1784. local handVal = nil
  1785. local targetVal = nil
  1786. for k,v in pairs(targetThree) do
  1787. targetVal = tonumber(k)
  1788. end
  1789. for k,v in pairs(handsThree) do
  1790. handVal = tonumber(k)
  1791. end
  1792. if targetVal and handVal then
  1793. return targetVal < handVal
  1794. end
  1795. return false
  1796. end
  1797. --
  1798. function luzhouPokerUtil:leftCards( handCards, targets)
  1799. local result = {}
  1800. local ts = {}
  1801. for _,group in pairs(targets) do
  1802. for _,card in pairs(group) do
  1803. table.insert(ts, card.cid)--将能出的牌汇集到一起
  1804. end
  1805. end
  1806. for _,hcid in pairs(handCards) do
  1807. local own = false
  1808. for _,tcid in pairs(ts) do
  1809. if hcid == tcid then--包含了同一张牌
  1810. own = true
  1811. end
  1812. end
  1813. if not own then
  1814. table.insert(result, hcid)
  1815. end
  1816. end
  1817. return result
  1818. end
  1819. -- 提示,只剩大于最小牌的牌
  1820. function luzhouPokerUtil:leftCardsEx( handCards, targets)
  1821. local result = {}
  1822. local ts = {}
  1823. local minVal = 100
  1824. for _,group in pairs(targets) do
  1825. for _,card in pairs(group) do
  1826. table.insert(ts, card.cid)--将能出的牌汇集到一起
  1827. if card.val < minVal then
  1828. minVal = card.val--能出牌的最小张
  1829. end
  1830. end
  1831. end
  1832. for _,hcid in pairs(handCards) do
  1833. local own = false
  1834. for _,tcid in pairs(ts) do
  1835. local _, val = pokerParse(hcid)
  1836. if hcid == tcid or val >= minVal then
  1837. own = true
  1838. end
  1839. end
  1840. if not own then
  1841. table.insert(result, hcid)
  1842. end
  1843. end
  1844. return result
  1845. end
  1846. --
  1847. function luzhouPokerUtil:leftSingleCards( handCards, targets)
  1848. local result = {}
  1849. local ts = {}
  1850. for _,card in pairs(targets) do
  1851. if card.cid == nil and type(card)=='table' and #card>0 then
  1852. for _,v in ipairs(card) do
  1853. table.insert(ts, v.cid)
  1854. end
  1855. else
  1856. table.insert(ts, card.cid)
  1857. end
  1858. end
  1859. for _,hcid in pairs(handCards) do
  1860. local own = false
  1861. for _,tcid in pairs(ts) do
  1862. if hcid == tcid then
  1863. own = true
  1864. end
  1865. end
  1866. if not own then
  1867. table.insert(result, hcid)
  1868. end
  1869. end
  1870. return result
  1871. end
  1872. --是否是AAA
  1873. function luzhouPokerUtil:isAAA( cards )
  1874. if #cards ~= 3 then return false end
  1875. local result = true
  1876. for i,v in ipairs(cards) do
  1877. local _, val = pokerParse(v)
  1878. if val ~= A_VAL then
  1879. result = false
  1880. break
  1881. end
  1882. end
  1883. return result
  1884. end
  1885. function luzhouPokerUtil:checkType(cards)
  1886. local cardsLen = table.nums(cards)
  1887. if cardsLen == 0 then
  1888. return
  1889. end
  1890. local valueList = {}
  1891. local cardList = {}
  1892. local laiCount = 0
  1893. local a = {}
  1894. for k,v in ipairs(cards) do
  1895. local value = self:getCardValue(v)
  1896. if value == GUI_VAL then
  1897. laiCount = laiCount + 1
  1898. else
  1899. valueList[value] = valueList[value] or 0
  1900. valueList[value] = valueList[value] + 1
  1901. cardList[value] = cardList[value] or {}
  1902. table.insert(cardList[value], v)
  1903. end
  1904. end
  1905. if laiCount == cardsLen then
  1906. if laiCount == 1 then
  1907. return OUT_TYPE.SINGLE_CARD
  1908. elseif laiCount == 2 then
  1909. return OUT_TYPE.DUI_ZI
  1910. elseif laiCount == 3 then
  1911. return OUT_TYPE.THREE
  1912. end
  1913. end
  1914. for k,v in ipairs(valueList) do
  1915. a[v] = a[v] or {}
  1916. table.insert(a[v], v)
  1917. end
  1918. local typesEx = {}
  1919. --默认纯赖子不可打出
  1920. if cardsLen == 1 and table.nums(valueList) == 1 then
  1921. --单张
  1922. table.insert(typesEx, "单张")
  1923. return OUT_TYPE.SINGLE_CARD
  1924. elseif cardsLen == 2 and table.nums(valueList) == 1 then
  1925. --对子
  1926. table.insert(typesEx, "对子")
  1927. return OUT_TYPE.DUI_ZI
  1928. elseif cardsLen == 3 and table.nums(valueList) == 1 then
  1929. --三张
  1930. table.insert(typesEx, "三张")
  1931. return OUT_TYPE.THREE
  1932. else
  1933. if cardsLen == 4 and table.nums(valueList) == 1 then
  1934. --炸弹
  1935. table.insert(typesEx, "炸弹")
  1936. return OUT_TYPE.BOMB
  1937. else
  1938. --三代二
  1939. if cardsLen == 5 and table.nums(valueList) <= 3 then
  1940. for i = 1, 13 do
  1941. local cardsEx = {}
  1942. local laiCountEx = laiCount
  1943. local valueCountEx = valueList[i] or 0
  1944. if valueCountEx >= 1 and valueCountEx <= 3 and valueCountEx + laiCountEx >= 3 then
  1945. local userLaiCount = 3 - valueCountEx
  1946. userLaiCount = userLaiCount > 0 and userLaiCount or 0
  1947. for i = 1, userLaiCount do
  1948. table.insert(cardsEx, 0x0e)
  1949. end
  1950. for i = 1, 2 - userLaiCount do
  1951. table.insert(cardsEx, cardList[i])
  1952. end
  1953. --三代二
  1954. table.insert(typesEx, "三代二")
  1955. return OUT_TYPE.THREE_AND_TWO
  1956. end
  1957. end
  1958. end
  1959. --顺子
  1960. if cardsLen >= 5 then
  1961. for i = 1, 12 do
  1962. local iEx = i
  1963. local countEx = 0
  1964. local cardsEx = {}
  1965. local laiCountEx = laiCount
  1966. while iEx <= 12 and countEx < cardsLen do
  1967. local valueCountEx = valueList[iEx] or 0
  1968. if valueCountEx + laiCountEx >= 1 then
  1969. local userLaiCount = 1 - valueCountEx
  1970. userLaiCount = userLaiCount > 0 and userLaiCount or 0
  1971. for i = 1, userLaiCount do
  1972. table.insert(cardsEx, 0x0f)
  1973. end
  1974. for i = 1, 1 - userLaiCount do
  1975. table.insert(cardsEx, cardList[i])
  1976. end
  1977. iEx = iEx + 1
  1978. countEx = countEx + 1
  1979. laiCountEx = laiCountEx - userLaiCount
  1980. else
  1981. break
  1982. end
  1983. end
  1984. if countEx == cardsLen then
  1985. --顺子
  1986. table.insert(typesEx, "顺子")
  1987. return OUT_TYPE.SHUN_ZI
  1988. end
  1989. end
  1990. local parseData = {}
  1991. for _,v in ipairs(cards) do
  1992. local tp, val = pokerParse(v)
  1993. table.insert(parseData, {tp=tp, val=val, cid=v})
  1994. end
  1995. if #parseData >=2 then
  1996. table.sort(parseData, sortCardsFunc)
  1997. end
  1998. if self:checkShunzi(parseData) then
  1999. return OUT_TYPE.SHUN_ZI
  2000. end
  2001. end
  2002. --连对
  2003. if cardsLen % 2 == 0 and cardsLen >= 4 then
  2004. for i = 1, 13 do
  2005. local iEx = i
  2006. local countEx = 0
  2007. local cardsEx = {}
  2008. local laiCountEx = laiCount
  2009. while iEx <= 13 and countEx < cardsLen do
  2010. local valueCountEx = valueList[iEx] or 0
  2011. if valueCountEx + laiCountEx >= 2 then
  2012. local userLaiCount = 2 - valueCountEx
  2013. userLaiCount = userLaiCount > 0 and userLaiCount or 0
  2014. for i = 1, userLaiCount do
  2015. table.insert(cardsEx, 0x0f)
  2016. end
  2017. for i = 1, 2 - userLaiCount do
  2018. table.insert(cardsEx, cardList[i])
  2019. end
  2020. iEx = iEx + 1
  2021. countEx = countEx + 2
  2022. laiCountEx = laiCountEx - userLaiCount
  2023. else
  2024. break
  2025. end
  2026. end
  2027. if countEx == cardsLen then
  2028. --连对
  2029. if cardsLen > 4 and valueList[13] and valueList[13] >= 1 then--连对只有AA22可以出,KKAA22和QQKKAA22都不可以出
  2030. else
  2031. table.insert(typesEx, "连对")
  2032. return OUT_TYPE.LIAN_DUI
  2033. end
  2034. end
  2035. end
  2036. if valueList[13] and valueList[13] >= 1 and valueList[1] and valueList[1] >= 1 and
  2037. (cardsLen/2 == table.nums(valueList) + math.floor(laiCount/2) or cardsLen/2 == table.nums(valueList))then
  2038. local ishaveThree = false
  2039. for i,v in pairs(valueList) do
  2040. if v > 2 then
  2041. ishaveThree = true
  2042. break
  2043. end
  2044. end
  2045. if not ishaveThree then
  2046. return OUT_TYPE.LIAN_DUI
  2047. end
  2048. end
  2049. end
  2050. --三顺
  2051. if cardsLen % 3 == 0 and cardsLen >= 6 then
  2052. for i = 1, 13 do
  2053. local iEx = i
  2054. local countEx = 0
  2055. local cardsEx = {}
  2056. local laiCountEx = laiCount
  2057. while iEx <= 13 and countEx < cardsLen do
  2058. local valueCountEx = valueList[iEx] or 0
  2059. if valueCountEx + laiCountEx >= 3 then
  2060. local userLaiCount = 3 - valueCountEx
  2061. userLaiCount = userLaiCount > 0 and userLaiCount or 0
  2062. for i = 1, userLaiCount do
  2063. table.insert(cardsEx, 0x0f)
  2064. end
  2065. for i = 1, 3 - userLaiCount do
  2066. table.insert(cardsEx, cardList[i])
  2067. end
  2068. iEx = iEx + 1
  2069. countEx = countEx + 3
  2070. laiCountEx = laiCountEx - userLaiCount
  2071. else
  2072. break
  2073. end
  2074. end
  2075. if countEx == cardsLen then
  2076. --三顺
  2077. if cardsLen > 6 and valueList[13] and valueList[13] >= 1 then--三顺只有AAA222可以出,KKKAAA222和QQQKKKAAA222都不可以出
  2078. else
  2079. table.insert(typesEx, "三顺")
  2080. return OUT_TYPE.AIRPLANE
  2081. end
  2082. end
  2083. end
  2084. if valueList[13] and valueList[13] >= 1 and valueList[1] and valueList[1] >= 1 and cardsLen/3 == table.nums(valueList) + math.floor(laiCount/3) then
  2085. if cardsLen == 6 then
  2086. return OUT_TYPE.AIRPLANE
  2087. elseif cardsLen == 9 then
  2088. if (valueList[12] and valueList[12] >= 1) or (valueList[2] and valueList[2] >= 1) or laiCount == 3 then
  2089. return OUT_TYPE.AIRPLANE
  2090. end
  2091. elseif cardsLen == 12 then
  2092. if laiCount == 3 and (valueList[12] and valueList[12] >= 1) or (valueList[2] and valueList[2] >= 1) then
  2093. return OUT_TYPE.AIRPLANE
  2094. elseif (valueList[12] and valueList[12] >= 1) and (valueList[2] and valueList[2] >= 1) or
  2095. (valueList[3] and valueList[3] >= 1) and (valueList[2] and valueList[2] >= 1) then
  2096. return OUT_TYPE.AIRPLANE
  2097. end
  2098. end
  2099. end
  2100. end
  2101. --飞机
  2102. if cardsLen % 5 == 0 and cardsLen >= 10 and table.nums(valueList) <= cardsLen / 5 * 3 then
  2103. for i = 1, 13 do
  2104. local iEx = i
  2105. local countEx = 0
  2106. local cardsEx = {}
  2107. local laiCountEx = laiCount
  2108. while iEx <= 13 and countEx < cardsLen / 5 do
  2109. local valueCountEx = valueList[iEx] or 0
  2110. if valueCountEx + laiCountEx >= 3 then
  2111. local userLaiCount = 3 - valueCountEx
  2112. userLaiCount = userLaiCount > 0 and userLaiCount or 0
  2113. for i = 1, userLaiCount do
  2114. table.insert(cardsEx, 0x0f)
  2115. end
  2116. for i = 1, 3 - userLaiCount do
  2117. table.insert(cardsEx, cardList[i])
  2118. end
  2119. iEx = iEx + 1
  2120. countEx = countEx + 1
  2121. laiCountEx = laiCountEx - userLaiCount
  2122. else
  2123. break
  2124. end
  2125. end
  2126. if countEx == cardsLen / 5 then
  2127. --飞机
  2128. local threeNum = 0
  2129. for i,v in pairs(valueList) do
  2130. if v >= 3 then
  2131. threeNum = threeNum + 1
  2132. end
  2133. end
  2134. if threeNum > 2 then
  2135. else
  2136. table.insert(typesEx, "飞机")
  2137. return OUT_TYPE.AIRPLANE_TOW
  2138. end
  2139. end
  2140. end
  2141. if valueList[13] and valueList[13] >= 1 and valueList[1] and valueList[1] >= 1 and valueList[13]+valueList[1]+laiCount>=6 then
  2142. return OUT_TYPE.AIRPLANE_TOW
  2143. end
  2144. end
  2145. end
  2146. end
  2147. return OUT_TYPE.NONE
  2148. end
  2149. --根据牌类型获取最小值
  2150. function luzhouPokerUtil:getCardsMin(cards,cardtype)
  2151. local cardsLen = table.nums(cards)
  2152. if cardsLen == 0 then
  2153. return
  2154. end
  2155. local valueList = {}
  2156. local cardList = {}
  2157. local laiCount = 0
  2158. local a = {}
  2159. for k,v in ipairs(cards) do
  2160. local value = v.val
  2161. if value == GUI_VAL then
  2162. laiCount = laiCount + 1
  2163. else
  2164. valueList[value] = valueList[value] or 0
  2165. valueList[value] = valueList[value] + 1
  2166. cardList[value] = cardList[value] or {}
  2167. table.insert(cardList[value], v)
  2168. end
  2169. end
  2170. if laiCount == cardsLen then
  2171. return
  2172. end
  2173. for k,v in ipairs(valueList) do
  2174. a[v] = a[v] or {}
  2175. table.insert(a[v], v)
  2176. end
  2177. local typesEx = {}
  2178. --默认纯赖子不可打出
  2179. if cardtype == OUT_TYPE.SINGLE_CARD and cardsLen == 1 and table.nums(valueList) == 1 then
  2180. for i,v in pairs(cardList) do
  2181. return v[1].val
  2182. end
  2183. elseif cardtype == OUT_TYPE.DUI_ZI and cardsLen == 2 and table.nums(valueList) == 1 then
  2184. --对子
  2185. table.insert(typesEx, "对子")
  2186. for i,v in pairs(cardList) do
  2187. return v[1].val
  2188. end
  2189. elseif cardtype == OUT_TYPE.THREE and cardsLen == 3 and table.nums(valueList) == 1 then
  2190. --三张
  2191. table.insert(typesEx, "三张")
  2192. for i,v in pairs(cardList) do
  2193. return v[1].val
  2194. end
  2195. else
  2196. if cardtype == OUT_TYPE.BOMB and cardsLen == 4 and table.nums(valueList) == 1 then
  2197. --炸弹
  2198. table.insert(typesEx, "炸弹")
  2199. for i,v in pairs(cardList) do
  2200. return v[1].val
  2201. end
  2202. else
  2203. --三代二
  2204. if cardtype == OUT_TYPE.THREE_AND_TWO and cardsLen == 5 and table.nums(valueList) <= 3 then
  2205. for i = 13, 1,-1 do
  2206. local cardsEx = {}
  2207. local laiCountEx = laiCount
  2208. local valueCountEx = valueList[i] or 0
  2209. if valueCountEx >= 1 and valueCountEx <= 3 and valueCountEx + laiCountEx >= 3 then
  2210. local userLaiCount = 3 - valueCountEx
  2211. userLaiCount = userLaiCount > 0 and userLaiCount or 0
  2212. for k = 1, userLaiCount do
  2213. table.insert(cardsEx, 0x0f)
  2214. end
  2215. for k = 1, 2 - userLaiCount do
  2216. table.insert(cardsEx, cardList[k])
  2217. end
  2218. --三代二
  2219. table.insert(typesEx, "三代二")
  2220. return i
  2221. end
  2222. end
  2223. end
  2224. --顺子
  2225. if cardtype == OUT_TYPE.SHUN_ZI and cardsLen >= 5 then
  2226. for i = 1, 12 do
  2227. local iEx = i
  2228. local countEx = 0
  2229. local cardsEx = {}
  2230. local laiCountEx = laiCount
  2231. while iEx <= 12 and countEx < cardsLen do
  2232. local valueCountEx = valueList[iEx] or 0
  2233. if valueCountEx + laiCountEx >= 1 then
  2234. local userLaiCount = 1 - valueCountEx
  2235. userLaiCount = userLaiCount > 0 and userLaiCount or 0
  2236. for k = 1, userLaiCount do
  2237. table.insert(cardsEx, 0x0f)
  2238. end
  2239. for k = 1, 1 - userLaiCount do
  2240. table.insert(cardsEx, cardList[k])
  2241. end
  2242. iEx = iEx + 1
  2243. countEx = countEx + 1
  2244. laiCountEx = laiCountEx - userLaiCount
  2245. else
  2246. break
  2247. end
  2248. end
  2249. if countEx == cardsLen then
  2250. --顺子
  2251. table.insert(typesEx, "顺子")
  2252. for k = cardsLen,1,-1 do
  2253. if cards[k].val == 13 then
  2254. return 0
  2255. end
  2256. end
  2257. return i
  2258. end
  2259. end
  2260. local isMinTime = 0
  2261. for i,v in pairs(cards) do
  2262. if v.val == 13 then
  2263. isMinTime = isMinTime + 1
  2264. return 0
  2265. elseif v.val ==1 or v.val==12 then
  2266. isMinTime = isMinTime + 1
  2267. end
  2268. end
  2269. if isMinTime >= 2 then
  2270. return 0
  2271. end
  2272. return 0
  2273. end
  2274. --连对
  2275. if cardtype == OUT_TYPE.LIAN_DUI and cardsLen % 2 == 0 and cardsLen >= 4 then
  2276. for i = 1, 13 do
  2277. local iEx = i
  2278. local countEx = 0
  2279. local cardsEx = {}
  2280. local laiCountEx = laiCount
  2281. while iEx <= 13 and countEx < cardsLen do
  2282. local valueCountEx = valueList[iEx] or 0
  2283. if valueCountEx + laiCountEx >= 2 then
  2284. local userLaiCount = 2 - valueCountEx
  2285. userLaiCount = userLaiCount > 0 and userLaiCount or 0
  2286. for k = 1, userLaiCount do
  2287. table.insert(cardsEx, 0x0f)
  2288. end
  2289. for k = 1, 2 - userLaiCount do
  2290. table.insert(cardsEx, cardList[k])
  2291. end
  2292. iEx = iEx + 1
  2293. countEx = countEx + 2
  2294. laiCountEx = laiCountEx - userLaiCount
  2295. else
  2296. break
  2297. end
  2298. end
  2299. if countEx == cardsLen then
  2300. --连对
  2301. table.insert(typesEx, "连对")
  2302. for k = cardsLen,1,-1 do
  2303. if cards[k].val == 13 then
  2304. return 0
  2305. end
  2306. end
  2307. return i
  2308. end
  2309. end
  2310. for k = cardsLen,1,-1 do
  2311. if cards[k].val == 13 then
  2312. return 0
  2313. end
  2314. end
  2315. end
  2316. --三顺
  2317. if (cardtype >= OUT_TYPE.AIRPLANE and cardtype <= OUT_TYPE.AIRPLANE_DUI) and cardsLen % 3 == 0 and cardsLen >= 6 then
  2318. for i = 1, 12 do
  2319. local iEx = i
  2320. local countEx = 0
  2321. local cardsEx = {}
  2322. local laiCountEx = laiCount
  2323. while iEx <= 12 and countEx < cardsLen do
  2324. local valueCountEx = valueList[iEx] or 0
  2325. if valueCountEx + laiCountEx >= 3 then
  2326. local userLaiCount = 3 - valueCountEx
  2327. userLaiCount = userLaiCount > 0 and userLaiCount or 0
  2328. for k = 1, userLaiCount do
  2329. table.insert(cardsEx, 0x0f)
  2330. end
  2331. for k = 1, 3 - userLaiCount do
  2332. table.insert(cardsEx, cardList[k])
  2333. end
  2334. iEx = iEx + 1
  2335. countEx = countEx + 3
  2336. laiCountEx = laiCountEx - userLaiCount
  2337. else
  2338. break
  2339. end
  2340. end
  2341. if countEx == cardsLen then
  2342. --三顺
  2343. table.insert(typesEx, "三顺")
  2344. return i
  2345. end
  2346. end
  2347. if cardsLen == 6 and valueList[13] and valueList[13] >= 1 and valueList[12] and valueList[12] >= 1 and cardsLen/3 == table.nums(valueList) + math.floor(laiCount/3) then--AAA222
  2348. return 0-- 三A三2
  2349. end
  2350. end
  2351. --飞机
  2352. if (cardtype >= OUT_TYPE.AIRPLANE and cardtype <= OUT_TYPE.AIRPLANE_DUI) and cardsLen % 5 == 0 and cardsLen >= 10 and table.nums(valueList) <= cardsLen / 5 * 3 then
  2353. for i = 1, 12 do
  2354. local iEx = i
  2355. local countEx = 0
  2356. local cardsEx = {}
  2357. local laiCountEx = laiCount
  2358. while iEx <= 12 and countEx < cardsLen / 5 do
  2359. local valueCountEx = valueList[iEx] or 0
  2360. if valueCountEx + laiCountEx >= 3 then
  2361. local userLaiCount = 3 - valueCountEx
  2362. userLaiCount = userLaiCount > 0 and userLaiCount or 0
  2363. for k = 1, userLaiCount do
  2364. table.insert(cardsEx, 0x0f)
  2365. end
  2366. for k = 1, 3 - userLaiCount do
  2367. table.insert(cardsEx, cardList[k])
  2368. end
  2369. iEx = iEx + 1
  2370. countEx = countEx + 1
  2371. laiCountEx = laiCountEx - userLaiCount
  2372. else
  2373. break
  2374. end
  2375. end
  2376. if countEx == cardsLen / 5 then
  2377. --飞机
  2378. table.insert(typesEx, "飞机")
  2379. return i
  2380. end
  2381. end
  2382. end
  2383. end
  2384. end
  2385. return 1
  2386. end
  2387. return luzhouPokerUtil