Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

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