Advertisement
Guest User

Untitled

a guest
Apr 20th, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.35 KB | None | 0 0
  1. package finalProject;
  2.  
  3. import static java.util.Arrays.asList;
  4.  
  5. import java.util.List;
  6.  
  7. /***************************************************************************
  8. Copyright (c) 2000:
  9. University of Alberta,
  10. Deptartment of Computing Science
  11. Computer Poker Research Group
  12.  
  13. See "Liscence.txt"
  14. ***************************************************************************/
  15. /**
  16. * Class for identifying / comparing / ranking Hands.
  17. *
  18. * @author Aaron Davidson, Darse Billings, Denis Papp
  19. */
  20.  
  21. public class HandEvaluator {
  22.  
  23. public static void main(String args[]){
  24. Hand hand1 = new Hand("Ac Kc");
  25. Hand hand2 = new Hand("Ac Kc Qc Jc Tc Qd Ad");
  26.  
  27. HandEvaluator handEval = new HandEvaluator();
  28.  
  29. System.out.println(handEval.getBest5CardHand(hand1));
  30. System.out.println(handEval.getBest5CardHand(hand2));
  31.  
  32. System.out.println(handEval.rankHand(hand1));
  33. System.out.println(handEval.rankHand(hand2));
  34.  
  35. System.out.println(handEval.nameHand(hand1));
  36. System.out.println(handEval.nameHand(hand2));
  37.  
  38. System.out.println(handEval.compareHands(hand1, hand2));
  39.  
  40. }
  41.  
  42. /**
  43. * Get a numerical ranking of this hand.
  44. *
  45. * @param c1
  46. * first hole card
  47. * @param c2
  48. * second hole card
  49. * @param h
  50. * a 3-5 card hand
  51. * @return a unique number representing the hand strength of the best 5-card
  52. * poker hand in the given cards and board. The higher the number,
  53. * the better the hand is.
  54. */
  55. public int rankHand(Card c1, Card c2, Hand h) {
  56. h.addCard(c1);
  57. h.addCard(c2);
  58. int rank = rankHand(h);
  59. h.removeCard();
  60. h.removeCard();
  61. return rank;
  62. }
  63.  
  64. /**
  65. * Given a hand, return a string naming the hand ('Ace High Flush', etc..)
  66. */
  67. public static String nameHand(Hand h) {
  68. return name_hand(rankHand(h));
  69. }
  70.  
  71. /**
  72. * Compares two hands against each other.
  73. *
  74. * @param h1
  75. * The first hand
  76. * @param h2
  77. * The second hand
  78. * @return 1 = first hand is best, 2 = second hand is best, 0 = tie
  79. */
  80. public int compareHands(Hand h1, Hand h2) {
  81. int r1 = rankHand(h1);
  82. int r2 = rankHand(h2);
  83.  
  84. if (r1 > r2)
  85. return 1;
  86. if (r1 < r2)
  87. return 2;
  88. return 0;
  89. }
  90.  
  91. /**
  92. * Compares two 5-7 card hands against each other.
  93. *
  94. * @param rank1
  95. * The rank of the first hand
  96. * @param h2
  97. * The second hand
  98. * @return 1 = first hand is best, 2 = second hand is best, 0 = tie
  99. */
  100. public int compareHands(int rank1, Hand h2) {
  101. int r1 = rank1;
  102. int r2 = rankHand(h2);
  103.  
  104. if (r1 > r2)
  105. return 1;
  106. if (r1 < r2)
  107. return 2;
  108. return 0;
  109. }
  110.  
  111. /**
  112. * Given a board, cache all possible two card combinations of hand ranks, so
  113. * that lightenting fast hand comparisons may be done later.
  114. */
  115. public int[][] getRanks(Hand board) {
  116. Hand myhand = new Hand(board);
  117. int[][] rc = new int[52][52];
  118. int i, j, v, n1, n2;
  119. Deck d = new Deck();
  120. d.extractHand(board);
  121.  
  122. // tabulate ranks
  123. for (i = d.getTopCardIndex(); i < Deck.NUM_CARDS; i++) {
  124. myhand.addCard(d.getCard(i));
  125. n1 = d.getCard(i).getIndex();
  126. for (j = i + 1; j < Deck.NUM_CARDS; j++) {
  127. myhand.addCard(d.getCard(j));
  128. n2 = d.getCard(j).getIndex();
  129. rc[n1][n2] = rc[n2][n1] = rankHand(myhand);
  130. myhand.removeCard();
  131. }
  132. myhand.removeCard();
  133. }
  134. return rc;
  135. }
  136.  
  137. /** ******************************************************************* */
  138. // MORE HAND COMPARISON STUFF (Adapted from C code by Darse Billings)
  139. /** ******************************************************************* */
  140.  
  141. /**
  142. * Get the best 5 card poker hand from a 7 card hand
  143. *
  144. * @param h
  145. * Any 7 card poker hand
  146. * @return A Hand containing the highest ranked 5 card hand possible from the
  147. * input.
  148. */
  149. public Hand getBest5CardHand(Hand h) {
  150. int[] ch = h.getCardArray();
  151. int[] bh = new int[6];
  152. int j = Find_Hand(ch, bh);
  153. Hand nh = new Hand();
  154. for (int i = 0; i < 5; i++)
  155. nh.addCard(bh[i + 1]);
  156. return nh;
  157. }
  158.  
  159. private final static int unknown = -1;
  160. private final static int strflush = 9;
  161. private final static int quads = 8;
  162. private final static int fullhouse = 7;
  163. private final static int flush = 6;
  164. private final static int straight = 5;
  165. private final static int trips = 4;
  166. private final static int twopair = 3;
  167. private final static int pair = 2;
  168. private final static int nopair = 1;
  169. private final static int highcard = 1;
  170.  
  171. /**
  172. * Get a string from a hand type.
  173. *
  174. * @param handtype
  175. * number coding a hand type
  176. * @return name of hand type
  177. */
  178. private String drb_Name_Hand(int handtype) {
  179. switch (handtype) {
  180. case -1:
  181. return ("Hidden Hand");
  182. case 1:
  183. return ("High Card");
  184. case 2:
  185. return ("Pair");
  186. case 3:
  187. return ("Two Pair");
  188. case 4:
  189. return ("Three of a Kind");
  190. case 5:
  191. return ("Straight");
  192. case 6:
  193. return ("Flush");
  194. case 7:
  195. return ("Full House");
  196. case 8:
  197. return ("Four of a Kind");
  198. case 9:
  199. return ("Straight Flush");
  200. default:
  201. return ("Very Weird hand indeed");
  202. }
  203. }
  204.  
  205. /* drbcont: want to Find_ the _best_ flush and _best_ strflush ( >9 cards) */
  206.  
  207. private static boolean Check_StrFlush(int[] hand, int[] dist, int[] best) {
  208. int i, j, suit, strght, strtop;
  209. boolean returnvalue;
  210. int[] suitvector = new int[14];
  211. /*
  212. * _23456789TJQKA boolean vector 01234567890123 indexing
  213. */
  214.  
  215. returnvalue = false; /* default */
  216.  
  217. /* do flat distribution of whole suits (cdhs are 0123 respectively) */
  218.  
  219. for (suit = 0; suit <= 3; suit++) {
  220.  
  221. /* explicitly initialize suitvector */
  222. suitvector[0] = 13;
  223. for (i = 1; i <= suitvector[0]; i++) {
  224. suitvector[i] = 0;
  225. }
  226. for (i = 1; i <= hand[0]; i++) {
  227. if ((hand[i] != unknown) && ((hand[i] / 13) == suit)) {
  228. suitvector[(hand[i] % 13) + 1] = 1;
  229. };
  230. }
  231.  
  232. /* now look for straights */
  233. if (suitvector[13] >= 1) /* Ace low straight */
  234. {
  235. strght = 1;
  236. } else
  237. strght = 0;
  238. strtop = 0;
  239.  
  240. for (i = 1; i <= 13; i++) {
  241. if (suitvector[i] >= 1) {
  242. strght++;
  243. if (strght >= 5) {
  244. strtop = i - 1;
  245. };
  246. } else
  247. strght = 0;
  248. }
  249.  
  250. /* determine if there was a straight flush and copy it to best[] */
  251.  
  252. if (strtop > 0) { /* no 2-high straight flushes */
  253. for (j = 1; j <= 5; j++) {
  254. best[j] = ((13 * suit) + strtop + 1 - j);
  255. }
  256. /* Adjust for case of Ace low (five high) straight flush */
  257. if (strtop == 3) {
  258. best[5] = best[5] + 13;
  259. }
  260. returnvalue = true;
  261. }
  262. }
  263. return (returnvalue);
  264. }
  265.  
  266. private void Find_Quads(int[] hand, int[] dist, int[] best) {
  267. int i, j, quadrank = 0, kicker;
  268.  
  269. /* find rank of largest quads */
  270. for (i = 1; i <= 13; i++) {
  271. if (dist[i] >= 4) {
  272. quadrank = i - 1;
  273. }
  274. ;
  275. }
  276.  
  277. /* copy those quads */
  278. i = 1; /* position in hand[] */
  279. j = 1; /* position in best[] */
  280. while (j <= 4) { /* assume all four will be found before i > hand[0] */
  281. if ((hand[i] != unknown) && ((hand[i] % 13) == quadrank)) {
  282. best[j] = hand[i];
  283. j++;
  284. }
  285. ;
  286. i++;
  287. }
  288.  
  289. /* find best kicker */
  290. kicker = unknown; /* default is unknown kicker */
  291. for (i = 1; i <= 13; i++) { /* find rank of largest kicker */
  292. if ((dist[i] >= 1) && ((i - 1) != quadrank)) {
  293. kicker = i - 1;
  294. }
  295. }
  296.  
  297. /* copy kicker */
  298. if (kicker != unknown) {
  299. i = 1; /* position in hand[] */
  300. while (j <= 5) { /* assume kicker will be found before i > hand[0] */
  301. if ((hand[i] != unknown) && ((hand[i] % 13) == kicker)) {
  302. best[j] = hand[i];
  303. j++;
  304. }
  305. ;
  306. i++;
  307. }
  308. } else {
  309. best[j] = unknown;
  310. j++;
  311. }
  312. }
  313.  
  314. private void Find_FullHouse(int[] hand, int[] dist, int[] best) {
  315. int i, j, tripsrank = 0, pairrank = 0;
  316.  
  317. /* find rank of largest trips */
  318. for (i = 1; i <= 13; i++) {
  319. if (dist[i] >= 3) {
  320. tripsrank = i - 1;
  321. }
  322. ;
  323. }
  324.  
  325. /* copy those trips */
  326. i = 1; /* position in hand[] */
  327. j = 1; /* position in best[] */
  328. while (j <= 3) { /* assume all three will be found before i > hand[0] */
  329. if ((hand[i] != unknown) && ((hand[i] % 13) == tripsrank)) {
  330. best[j] = hand[i];
  331. j++;
  332. }
  333. ;
  334. i++;
  335. }
  336.  
  337. /* find best pair */
  338. i = 13;
  339. pairrank = -1;
  340. while (pairrank < 0) { /* assume kicker will be found before i = 0 */
  341. if ((dist[i] >= 2) && ((i - 1) != tripsrank)) {
  342. pairrank = i - 1;
  343. } else
  344. i--;
  345. }
  346.  
  347. /* copy best pair */
  348. i = 1; /* position in hand[] */
  349. while (j <= 5) { /* assume pair will be found before i > hand[0] */
  350. if ((hand[i] != unknown) && ((hand[i] % 13) == pairrank)) {
  351. best[j] = hand[i];
  352. j++;
  353. }
  354. ;
  355. i++;
  356. }
  357. }
  358.  
  359. private void Find_Flush(int[] hand, int[] dist, int[] best) { /*
  360. * finds only
  361. * the best
  362. * flush in
  363. * highest
  364. * suit
  365. */
  366. int i, j, flushsuit = 0;
  367. int[] suitvector = new int[14];
  368. /*
  369. * _23456789TJQKA boolean vector 01234567890123 indexing
  370. */
  371. /* find flushsuit */
  372. for (i = 14; i <= 17; i++) {
  373. if (dist[i] >= 5) {
  374. flushsuit = i - 14;
  375. }
  376. ;
  377. }
  378.  
  379. /* explicitly initialize suitvector */
  380. suitvector[0] = 13;
  381. for (i = 1; i <= suitvector[0]; i++) {
  382. suitvector[i] = 0;
  383. }
  384.  
  385. /* do flat distribution of whole flushsuit */
  386. for (i = 1; i <= hand[0]; i++) {
  387. if ((hand[i] != unknown) && ((hand[i] / 13) == flushsuit)) {
  388. suitvector[(hand[i] % 13) + 1] = 1;
  389. }
  390. ;
  391. }
  392.  
  393. /* determine best five cards in flushsuit */
  394. i = 13;
  395. j = 1;
  396. while (j <= 5) { /* assume all five flushcards will be found before i < 1 */
  397. if (suitvector[i] >= 1) {
  398. best[j] = (13 * flushsuit) + i - 1;
  399. j++;
  400. }
  401. ;
  402. i--;
  403. }
  404. }
  405.  
  406. private void Find_Straight(int[] hand, int[] dist, int[] best) {
  407. int i, j, strght, strtop;
  408.  
  409. /* look for highest straight */
  410. if (dist[13] >= 1) /* Ace low straight */
  411. {
  412. strght = 1;
  413. } else
  414. strght = 0;
  415. strtop = 0;
  416.  
  417. for (i = 1; i <= 13; i++) {
  418. if (dist[i] >= 1) {
  419. strght++;
  420. if (strght >= 5) {
  421. strtop = i - 1;
  422. }
  423. ;
  424. } else
  425. strght = 0;
  426. }
  427.  
  428. /* copy the highest straight */
  429. if (strtop > 3) { /* note: different extraction from others */
  430. for (j = 1; j <= 5; j++) {
  431. for (i = 1; i <= hand[0]; i++) {
  432. if ((hand[i] != unknown) && (hand[i] % 13 == (strtop + 1 - j))) {
  433. best[j] = hand[i];
  434. }
  435. ;
  436. }
  437. }
  438. } else if (strtop == 3) {
  439. for (j = 1; j <= 4; j++) {
  440. for (i = 1; i <= hand[0]; i++) {
  441. if ((hand[i] != unknown) && (hand[i] % 13 == (strtop + 1 - j))) {
  442. best[j] = hand[i];
  443. }
  444. ;
  445. }
  446. }
  447. for (i = 1; i <= hand[0]; i++) { /* the Ace in a low straight */
  448. if ((hand[i] != unknown) && (hand[i] % 13 == 12)) {
  449. best[5] = hand[i];
  450. }
  451. ;
  452. }
  453. }
  454. }
  455.  
  456. private void Find_Trips(int[] hand, int[] dist, int[] best) {
  457. int i, j, tripsrank = 0, kicker1, kicker2;
  458.  
  459. /* find rank of largest trips */
  460. for (i = 1; i <= 13; i++) {
  461. if (dist[i] >= 3) {
  462. tripsrank = i - 1;
  463. }
  464. ;
  465. }
  466.  
  467. /* copy those trips */
  468. i = 1; /* position in hand[] */
  469. j = 1; /* position in best[] */
  470. while (j <= 3) { /* assume all three will be found before i > hand[0] */
  471. if ((hand[i] != unknown) && ((hand[i] % 13) == tripsrank)) {
  472. best[j] = hand[i];
  473. j++;
  474. }
  475. ;
  476. i++;
  477. }
  478.  
  479. /* find best kickers */
  480. kicker1 = unknown; /* default is unknown kicker */
  481. for (i = 1; i <= 13; i++) { /* find rank of largest kicker */
  482. if ((dist[i] >= 1) && ((i - 1) != tripsrank)) {
  483. kicker1 = i - 1;
  484. }
  485. ;
  486. }
  487.  
  488. kicker2 = unknown;
  489. for (i = 1; i <= kicker1; i++) { /* find rank of second kicker */
  490. if ((dist[i] >= 1) && ((i - 1) != tripsrank)) {
  491. kicker2 = i - 1;
  492. }
  493. ;
  494. }
  495.  
  496. /* copy kickers */
  497. if (kicker1 != unknown) {
  498. i = 1; /* position in hand[] */
  499. while (j <= 4) { /* assume kicker1 will be found before i > hand[0] */
  500. if ((hand[i] != unknown) && ((hand[i] % 13) == kicker1)) {
  501. best[j] = hand[i];
  502. j++;
  503. }
  504. ;
  505. i++;
  506. }
  507. } else {
  508. best[j] = unknown;
  509. j++;
  510. }
  511.  
  512. if (kicker2 != unknown) {
  513. i = 1; /* position in hand[] */
  514. while (j <= 5) { /* assume kicker2 will be found before i > hand[0] */
  515. if ((hand[i] != unknown) && ((hand[i] % 13) == kicker2)) {
  516. best[j] = hand[i];
  517. j++;
  518. }
  519. ;
  520. i++;
  521. }
  522. } else {
  523. best[j] = unknown;
  524. j++;
  525. }
  526. }
  527.  
  528. private void Find_TwoPair(int[] hand, int[] dist, int[] best) {
  529. int i, j, pairrank1 = 0, pairrank2 = 0, kicker;
  530.  
  531. /* find rank of largest pair */
  532. for (i = 1; i <= 13; i++) {
  533. if (dist[i] >= 2) {
  534. pairrank1 = i - 1;
  535. }
  536. ;
  537. }
  538. /* find rank of second largest pair */
  539. for (i = 1; i <= 13; i++) {
  540. if ((dist[i] >= 2) && ((i - 1) != pairrank1)) {
  541. pairrank2 = i - 1;
  542. }
  543. ;
  544. }
  545.  
  546. /* copy those pairs */
  547. i = 1; /* position in hand[] */
  548. j = 1; /* position in best[] */
  549. while (j <= 2) { /* assume both will be found before i > hand[0] */
  550. if ((hand[i] != unknown) && ((hand[i] % 13) == pairrank1)) {
  551. best[j] = hand[i];
  552. j++;
  553. }
  554. ;
  555. i++;
  556. }
  557. i = 1; /* position in hand[] */
  558. while (j <= 4) { /* assume both will be found before i > hand[0] */
  559. if ((hand[i] != unknown) && ((hand[i] % 13) == pairrank2)) {
  560. best[j] = hand[i];
  561. j++;
  562. }
  563. ;
  564. i++;
  565. }
  566.  
  567. /* find best kicker */
  568. kicker = unknown; /* default is unknown kicker */
  569. for (i = 1; i <= 13; i++) { /* find rank of largest kicker */
  570. if ((dist[i] >= 1) && ((i - 1) != pairrank1) && ((i - 1) != pairrank2)) {
  571. kicker = i - 1;
  572. }
  573. }
  574.  
  575. /* copy kicker */
  576. if (kicker != unknown) {
  577. i = 1; /* position in hand[] */
  578. while (j <= 5) { /* assume kicker will be found before i > hand[0] */
  579. if ((hand[i] != unknown) && ((hand[i] % 13) == kicker)) {
  580. best[j] = hand[i];
  581. j++;
  582. }
  583. ;
  584. i++;
  585. }
  586. } else {
  587. best[j] = unknown;
  588. j++;
  589. }
  590. }
  591.  
  592. private void Find_Pair(int[] hand, int[] dist, int[] best) {
  593. int i, j, pairrank = 0, kicker1, kicker2, kicker3;
  594.  
  595. /* find rank of largest pair */
  596. for (i = 1; i <= 13; i++) {
  597. if (dist[i] >= 2) {
  598. pairrank = i - 1;
  599. }
  600. ;
  601. }
  602.  
  603. /* copy that pair */
  604. i = 1; /* position in hand[] */
  605. j = 1; /* position in best[] */
  606. while (j <= 2) { /* assume both will be found before i > hand[0] */
  607. if ((hand[i] != unknown) && ((hand[i] % 13) == pairrank)) {
  608. best[j] = hand[i];
  609. j++;
  610. }
  611. ;
  612. i++;
  613. }
  614.  
  615. /* find best kickers */
  616. kicker1 = unknown; /* default is unknown kicker */
  617. for (i = 1; i <= 13; i++) { /* find rank of largest kicker */
  618. if ((dist[i] >= 1) && ((i - 1) != pairrank)) {
  619. kicker1 = i - 1;
  620. }
  621. ;
  622. }
  623. kicker2 = unknown;
  624. for (i = 1; i <= kicker1; i++) { /* find rank of second kicker */
  625. if ((dist[i] >= 1) && ((i - 1) != pairrank)) {
  626. kicker2 = i - 1;
  627. }
  628. ;
  629. }
  630. kicker3 = unknown;
  631. for (i = 1; i <= kicker2; i++) { /* find rank of third kicker */
  632. if ((dist[i] >= 1) && ((i - 1) != pairrank)) {
  633. kicker3 = i - 1;
  634. }
  635. }
  636.  
  637. /* copy kickers */
  638. if (kicker1 != unknown) {
  639. i = 1; /* position in hand[] */
  640. while (j <= 3) { /* assume kicker1 will be found before i > hand[0] */
  641. if ((hand[i] != unknown) && ((hand[i] % 13) == kicker1)) {
  642. best[j] = hand[i];
  643. j++;
  644. }
  645. ;
  646. i++;
  647. }
  648. } else {
  649. best[j] = unknown;
  650. j++;
  651. }
  652.  
  653. if (kicker2 != unknown) {
  654. i = 1; /* position in hand[] */
  655. while (j <= 4) { /* assume kicker2 will be found before i > hand[0] */
  656. if ((hand[i] != unknown) && ((hand[i] % 13) == kicker2)) {
  657. best[j] = hand[i];
  658. j++;
  659. }
  660. ;
  661. i++;
  662. }
  663. } else {
  664. best[j] = unknown;
  665. j++;
  666. }
  667.  
  668. if (kicker3 != unknown) {
  669. i = 1; /* position in hand[] */
  670. while (j <= 5) { /* assume kicker3 will be found before i > hand[0] */
  671. if ((hand[i] != unknown) && ((hand[i] % 13) == kicker3)) {
  672. best[j] = hand[i];
  673. j++;
  674. }
  675. ;
  676. i++;
  677. }
  678. } else {
  679. best[j] = unknown;
  680. j++;
  681. }
  682. }
  683.  
  684. private void Find_NoPair(int[] hand, int[] dist, int[] best) {
  685. int i, j, kicker1, kicker2, kicker3, kicker4, kicker5;
  686.  
  687. /* find best kickers */
  688. kicker1 = unknown; /* default is unknown kicker */
  689. for (i = 1; i <= 13; i++) { /* find rank of largest kicker */
  690. if (dist[i] >= 1) {
  691. kicker1 = i - 1;
  692. }
  693. ;
  694. }
  695. kicker2 = unknown;
  696. for (i = 1; i <= kicker1; i++) { /* find rank of second kicker */
  697. if (dist[i] >= 1) {
  698. kicker2 = i - 1;
  699. }
  700. ;
  701. }
  702. kicker3 = unknown;
  703. for (i = 1; i <= kicker2; i++) { /* find rank of third kicker */
  704. if (dist[i] >= 1) {
  705. kicker3 = i - 1;
  706. }
  707. ;
  708. }
  709. kicker4 = unknown;
  710. for (i = 1; i <= kicker3; i++) { /* find rank of fourth kicker */
  711. if (dist[i] >= 1) {
  712. kicker4 = i - 1;
  713. }
  714. ;
  715. }
  716. kicker5 = unknown;
  717. for (i = 1; i <= kicker4; i++) { /* find rank of fifth kicker */
  718. if (dist[i] >= 1) {
  719. kicker5 = i - 1;
  720. }
  721. ;
  722. }
  723.  
  724. /* copy kickers */
  725. j = 1; /* position in best[] */
  726.  
  727. if (kicker1 != unknown) {
  728. i = 1; /* position in hand[] */
  729. while (j <= 1) { /* assume kicker1 will be found before i > hand[0] */
  730. if ((hand[i] != unknown) && ((hand[i] % 13) == kicker1)) {
  731. best[j] = hand[i];
  732. j++;
  733. }
  734. ;
  735. i++;
  736. }
  737. } else {
  738. best[j] = unknown;
  739. j++;
  740. }
  741.  
  742. if (kicker2 != unknown) {
  743. i = 1; /* position in hand[] */
  744. while (j <= 2) { /* assume kicker2 will be found before i > hand[0] */
  745. if ((hand[i] != unknown) && ((hand[i] % 13) == kicker2)) {
  746. best[j] = hand[i];
  747. j++;
  748. }
  749. ;
  750. i++;
  751. }
  752. } else {
  753. best[j] = unknown;
  754. j++;
  755. }
  756.  
  757. if (kicker3 != unknown) {
  758. i = 1; /* position in hand[] */
  759. while (j <= 3) { /* assume kicker3 will be found before i > hand[0] */
  760. if ((hand[i] != unknown) && ((hand[i] % 13) == kicker3)) {
  761. best[j] = hand[i];
  762. j++;
  763. }
  764. ;
  765. i++;
  766. }
  767. } else {
  768. best[j] = unknown;
  769. j++;
  770. }
  771.  
  772. if (kicker4 != unknown) {
  773. i = 1; /* position in hand[] */
  774. while (j <= 4) { /* assume kicker4 will be found before i > hand[0] */
  775. if ((hand[i] != unknown) && ((hand[i] % 13) == kicker4)) {
  776. best[j] = hand[i];
  777. j++;
  778. }
  779. ;
  780. i++;
  781. }
  782. } else {
  783. best[j] = unknown;
  784. j++;
  785. }
  786.  
  787. if (kicker5 != unknown) {
  788. i = 1; /* position in hand[] */
  789. while (j <= 5) { /* assume kicker5 will be found before i > hand[0] */
  790. if ((hand[i] != unknown) && ((hand[i] % 13) == kicker5)) {
  791. best[j] = hand[i];
  792. j++;
  793. }
  794. ;
  795. i++;
  796. }
  797. } else {
  798. best[j] = unknown;
  799. j++;
  800. }
  801. }
  802.  
  803. private int Best_Hand(int[] hand1, int[] hand2) { /*
  804. * sorted 5-card hands,
  805. * both same type
  806. */
  807. /* could check for proper hand types... */
  808.  
  809. /* check value of top cards, then on down */
  810. if ((hand1[1] % 13) > (hand2[1] % 13))
  811. return (1);
  812. else if ((hand1[1] % 13) < (hand2[1] % 13))
  813. return (2);
  814.  
  815. /* same top, check second */
  816. else if ((hand1[2] % 13) > (hand2[2] % 13))
  817. return (1);
  818. else if ((hand1[2] % 13) < (hand2[2] % 13))
  819. return (2);
  820.  
  821. /* same second, check third */
  822. else if ((hand1[3] % 13) > (hand2[3] % 13))
  823. return (1);
  824. else if ((hand1[3] % 13) < (hand2[3] % 13))
  825. return (2);
  826.  
  827. /* same third, check fourth */
  828. else if ((hand1[4] % 13) > (hand2[4] % 13))
  829. return (1);
  830. else if ((hand1[4] % 13) < (hand2[4] % 13))
  831. return (2);
  832.  
  833. /* same fourth, check fifth */
  834. else if ((hand1[5] % 13) > (hand2[5] % 13))
  835. return (1);
  836. else if ((hand1[5] % 13) < (hand2[5] % 13))
  837. return (2);
  838.  
  839. else
  840. /* same hands */
  841. return (0);
  842. }
  843.  
  844. private int Find_Hand(int[] hand, int[] best) { /* -1 means unknown card */
  845. int i, card, rank, suit, hand_type, rankmax1, rankmax2, flushmax, strght, strmax;
  846. int[] dist = new int[18];
  847. /*
  848. * _23456789TJQKAcdhs distribution vector 012345678901234567 indexing
  849. */
  850.  
  851. /* explicitly initialize distribution vector */
  852. dist[0] = 17;
  853. for (i = 1; i <= dist[0]; i++) {
  854. dist[i] = 0;
  855. }
  856.  
  857. for (i = 1; i <= hand[0]; i++) {
  858. if (hand[i] != unknown) {
  859. card = hand[i];
  860. rank = card % 13;
  861. suit = card / 13;
  862.  
  863. if (!((rank < 0) || (rank > 12))) {
  864. dist[rank + 1]++;
  865. }
  866.  
  867. if (!((suit < 0) || (suit > 3))) {
  868. dist[suit + 14]++;
  869. }
  870. }
  871. }
  872.  
  873. /* scan the distribution array for maximums */
  874. rankmax1 = 0;
  875. rankmax2 = 0;
  876. flushmax = 0;
  877. strmax = 0;
  878.  
  879. if (dist[13] >= 1) {
  880. strght = 1;
  881. } else
  882. strght = 0; /* Ace low straight */
  883.  
  884. for (i = 1; i <= 13; i++) {
  885. if (dist[i] > rankmax1) {
  886. rankmax2 = rankmax1;
  887. rankmax1 = dist[i];
  888. } else if (dist[i] > rankmax2) {
  889. rankmax2 = dist[i];
  890. }
  891. ;
  892.  
  893. if (dist[i] >= 1) {
  894. strght++;
  895. if (strght > strmax) {
  896. strmax = strght;
  897. }
  898. } else
  899. strght = 0;
  900. }
  901.  
  902. for (i = 14; i <= 17; i++) {
  903. if (dist[i] > flushmax) {
  904. flushmax = dist[i];
  905. }
  906. }
  907.  
  908. hand_type = unknown;
  909.  
  910. if ((flushmax >= 5) && (strmax >= 5)) {
  911. if (Check_StrFlush(hand, dist, best)) {
  912. hand_type = strflush;
  913. } else {
  914. hand_type = flush;
  915. Find_Flush(hand, dist, best);
  916. }
  917. ;
  918. } else if (rankmax1 >= 4) {
  919. hand_type = quads;
  920. Find_Quads(hand, dist, best);
  921. } else if ((rankmax1 >= 3) && (rankmax2 >= 2)) {
  922. hand_type = fullhouse;
  923. Find_FullHouse(hand, dist, best);
  924. } else if (flushmax >= 5) {
  925. hand_type = flush;
  926. Find_Flush(hand, dist, best);
  927. } else if (strmax >= 5) {
  928. hand_type = straight;
  929. Find_Straight(hand, dist, best);
  930. } else if (rankmax1 >= 3) {
  931. hand_type = trips;
  932. Find_Trips(hand, dist, best);
  933. } else if ((rankmax1 >= 2) && (rankmax2 >= 2)) {
  934. hand_type = twopair;
  935. Find_TwoPair(hand, dist, best);
  936. } else if (rankmax1 >= 2) {
  937. hand_type = pair;
  938. Find_Pair(hand, dist, best);
  939. } else {
  940. hand_type = nopair;
  941. Find_NoPair(hand, dist, best);
  942. }
  943. ;
  944.  
  945. return (hand_type);
  946. }
  947.  
  948. /** ******************************************************************* */
  949. // DENIS PAPP'S HAND RANK IDENTIFIER CODE:
  950. /** ******************************************************************* */
  951.  
  952. private static final int POKER_HAND = 5;
  953.  
  954. public static final int HIGH = 0;
  955. public static final int PAIR = 1;
  956. public static final int TWOPAIR = 2;
  957. public static final int THREEKIND = 3;
  958. public static final int STRAIGHT = 4;
  959. public static final int FLUSH = 5;
  960. public static final int FULLHOUSE = 6;
  961. public static final int FOURKIND = 7;
  962. public static final int STRAIGHTFLUSH = 8;
  963. public static final int FIVEKIND = 9;
  964. public static final int NUM_HANDS = 10;
  965.  
  966. private static final int NUM_RANKS = 13;
  967.  
  968. private static final int ID_GROUP_SIZE = (Card.NUM_RANKS * Card.NUM_RANKS
  969. * Card.NUM_RANKS * Card.NUM_RANKS * Card.NUM_RANKS);
  970.  
  971. private final static byte ID_ExistsStraightFlush(Hand h, byte major_suit) {
  972. boolean[] present = new boolean[Card.NUM_RANKS];
  973. // for (i=0;i<Card.NUM_RANKS;i++) present[i]=false;
  974.  
  975. for (int i = 0; i < h.size(); i++) {
  976. int cind = h.getCardIndex(i + 1);
  977. if (Card.getSuit(cind) == major_suit) {
  978. present[Card.getRank(cind)] = true;
  979. }
  980. }
  981. int straight = present[Card.ACE] ? 1 : 0;
  982. byte high = 0;
  983. for (int i = 0; i < Card.NUM_RANKS; i++) {
  984. if (present[i]) {
  985. if ((++straight) >= POKER_HAND) {
  986. high = (byte) i;
  987. }
  988. } else {
  989. straight = 0;
  990. }
  991. }
  992. return high;
  993. }
  994.  
  995. // suit: Card.NUM_SUITS means any
  996. // not_allowed: Card.NUM_RANKS means any
  997. // returns ident value
  998. private final static int ID_KickerValue(byte[] paired, int kickers,
  999. byte[] not_allowed) {
  1000. int i = Card.ACE;
  1001. int value = 0;
  1002. while (kickers != 0) {
  1003. while (paired[i] == 0 || i == not_allowed[0] || i == not_allowed[1])
  1004. i--;
  1005. kickers--;
  1006. value += pow(Card.NUM_RANKS, kickers) * i;
  1007. i--;
  1008. }
  1009. return value;
  1010. }
  1011.  
  1012. private final static int ID_KickerValueSuited(Hand h, int kickers, byte suit) {
  1013. int i;
  1014. int value = 0;
  1015.  
  1016. boolean[] present = new boolean[Card.NUM_RANKS];
  1017. // for (i=0;i<Card.NUM_RANKS;i++) present[i] = false;
  1018.  
  1019. for (i = 0; i < h.size(); i++)
  1020. if (h.getCard(i + 1).getSuit() == suit)
  1021. present[h.getCard(i + 1).getRank()] = true;
  1022.  
  1023. i = Card.ACE;
  1024. while (kickers != 0) {
  1025. while (present[i] == false)
  1026. i--;
  1027. kickers--;
  1028. value += pow(Card.NUM_RANKS, kickers) * i;
  1029. i--;
  1030. }
  1031. return value;
  1032. }
  1033.  
  1034. /**
  1035. * Get a numerical ranking of this hand. Uses java based code, so may be
  1036. * slower than using the native methods, but is more compatible this way.
  1037. *
  1038. * Based on Denis Papp's Loki Hand ID code (id.cpp) Given a 1-9 card hand,
  1039. * will return a unique rank such that any two hands will be ranked with the
  1040. * better hand having a higher rank.
  1041. *
  1042. * @param h a 1-9 card hand
  1043. * @return a unique number representing the hand strength of the best 5-card
  1044. * poker hand in the given 7 cards. The higher the number, the better
  1045. * the hand is.
  1046. */
  1047. public final static int rankHand(Hand h) {
  1048. boolean straight = false;
  1049. boolean flush = false;
  1050. byte max_hand = (byte) (h.size() >= POKER_HAND ? POKER_HAND : h.size());
  1051. int r, c;
  1052. byte rank, suit;
  1053.  
  1054. // pair data
  1055. byte[] group_size = new byte[POKER_HAND + 1]; // array to track the groups or cards in your hand
  1056. byte[] paired = new byte[Card.NUM_RANKS]; // array to track paired carsd
  1057. byte[][] pair_rank = new byte[POKER_HAND + 1][2]; // array to track the rank of our pairs
  1058. // straight
  1059. byte straight_high = 0; // track the high card (rank) of our straight
  1060. byte straight_size;
  1061. // flush
  1062. byte[] suit_size = new byte[Card.NUM_SUITS];
  1063. byte major_suit = 0;
  1064.  
  1065. // determine pairs, dereference order data, check flush
  1066. // for (r=0;r<Card.NUM_RANKS;r++) paired[r] = 0;
  1067. // for (r=0;r<Card.NUM_SUITS;r++) suit_size[r] = 0;
  1068. // for (r=0;r<=POKER_HAND;r++) group_size[r] = 0;
  1069. for (r = 0; r < h.size(); r++) {
  1070. int cind = h.getCardIndex(r + 1);
  1071.  
  1072. rank = (byte) Card.getRank(cind);
  1073. suit = (byte) Card.getSuit(cind);
  1074.  
  1075. paired[rank]++; // Add rank of card to paired array to track the pairs we have.
  1076. group_size[paired[rank]]++; // keep track of the groups in our hand (1-pair, 2-pair, 1-trips, 1-trips 1-pair)
  1077. if (paired[rank] != 0) // To prevent looking at group_size[-1], which would be bad.
  1078. group_size[paired[rank] - 1]--; // Decrese the previous group by one. group_size[0] should end up at -5.
  1079. if ((++suit_size[suit]) >= POKER_HAND) { // Add suit to suit array, then check for a flush.
  1080. flush = true;
  1081. major_suit = suit;
  1082. }
  1083. }
  1084. // Card.ACE low? Add to straight_size if so.
  1085. straight_size = (byte) (paired[Card.ACE] != 0 ? 1 : 0);
  1086.  
  1087. for (int i = 0; i < (POKER_HAND + 1); i++) {
  1088. pair_rank[i][0] = (byte) Card.NUM_RANKS;
  1089. pair_rank[i][1] = (byte) Card.NUM_RANKS;
  1090. }
  1091.  
  1092. // check for straight and pair data
  1093. // Start at the Deuce. straight_size = 1 if we have an ace.
  1094. for (r = 0; r < Card.NUM_RANKS; r++) {
  1095. // check straight
  1096. if (paired[r] != 0) {
  1097. if ((++straight_size) >= POKER_HAND) { // Do we have five cards in a row (a straight!)
  1098. straight = true; // We sure do.
  1099. straight_high = (byte) r; // Keep track of that high card
  1100. }
  1101. } else { // Missing a card for our straight. start the count over.
  1102. straight_size = 0;
  1103. }
  1104. // get pair ranks, keep two highest of each
  1105. c = paired[r];
  1106. if (c != 0) {
  1107. pair_rank[c][1] = pair_rank[c][0];
  1108. pair_rank[c][0] = (byte) r;
  1109. }
  1110. }
  1111.  
  1112. // now id type
  1113. int ident;
  1114.  
  1115. if (group_size[POKER_HAND] != 0) { // we have five cards of the same rank in our hand.
  1116. ident = FIVEKIND * ID_GROUP_SIZE; // must have five of a kind !!
  1117. ident += pair_rank[POKER_HAND][0];
  1118. return ident;
  1119. }
  1120.  
  1121. if (straight && flush) {
  1122. byte hi = ID_ExistsStraightFlush(h, major_suit);
  1123. if (hi > 0) {
  1124. ident = STRAIGHTFLUSH * ID_GROUP_SIZE;
  1125. ident += hi;
  1126. return ident;
  1127. }
  1128. }
  1129.  
  1130. if (group_size[4] != 0) {
  1131. ident = FOURKIND * ID_GROUP_SIZE;
  1132. ident += pair_rank[4][0] * Card.NUM_RANKS;
  1133. pair_rank[4][1] = (byte) Card.NUM_RANKS; // just in case 2 sets quads
  1134. ident += ID_KickerValue(paired, 1, pair_rank[4]);
  1135. } else if (group_size[3] >= 2) {
  1136. ident = FULLHOUSE * ID_GROUP_SIZE;
  1137. ident += pair_rank[3][0] * Card.NUM_RANKS;
  1138. ident += pair_rank[3][1];
  1139. } else if (group_size[3] == 1 && group_size[2] != 0) {
  1140. ident = FULLHOUSE * ID_GROUP_SIZE;
  1141. ident += pair_rank[3][0] * Card.NUM_RANKS;
  1142. ident += pair_rank[2][0];
  1143. } else if (flush) {
  1144. ident = FLUSH * ID_GROUP_SIZE;
  1145. ident += ID_KickerValueSuited(h, 5, major_suit);
  1146. } else if (straight) {
  1147. ident = STRAIGHT * ID_GROUP_SIZE;
  1148. ident += straight_high;
  1149. } else if (group_size[3] == 1) {
  1150. ident = THREEKIND * ID_GROUP_SIZE;
  1151. ident += pair_rank[3][0] * Card.NUM_RANKS * Card.NUM_RANKS;
  1152. ident += ID_KickerValue(paired, max_hand - 3, pair_rank[3]);
  1153. } else if (group_size[2] >= 2) { // TWO PAIR
  1154. ident = TWOPAIR * ID_GROUP_SIZE;
  1155. ident += pair_rank[2][0] * Card.NUM_RANKS * Card.NUM_RANKS;
  1156. ident += pair_rank[2][1] * Card.NUM_RANKS;
  1157. ident += ID_KickerValue(paired, max_hand - 4, pair_rank[2]);
  1158. } else if (group_size[2] == 1) { // A PAIR
  1159. ident = PAIR * ID_GROUP_SIZE;
  1160. ident += pair_rank[2][0] * Card.NUM_RANKS * Card.NUM_RANKS
  1161. * Card.NUM_RANKS;
  1162. ident += ID_KickerValue(paired, max_hand - 2, pair_rank[2]);
  1163. } else { // A Low
  1164. ident = HIGH * ID_GROUP_SIZE;
  1165. ident += ID_KickerValue(paired, max_hand, pair_rank[2]);
  1166. }
  1167. return ident;
  1168. }
  1169.  
  1170. private static int pow(int n, int p) {
  1171. int res = 1;
  1172. while (p-- > 0)
  1173. res *= n;
  1174. return res;
  1175. }
  1176.  
  1177. private static final String[] hand_name = { "HIGH", "PAIR", "TWO PAIR",
  1178. "THREE KIND", "STRAIGHT", "FLUSH", "FULL HOUSE", "FOUR KIND",
  1179. "STRAIGHT FLUSH", "FIVE KIND" };
  1180.  
  1181. private static final String[] rank_name = { "Two", "Three", "Four", "Five",
  1182. "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace" };
  1183.  
  1184. /**
  1185. * Return a string naming the hand
  1186. *
  1187. * @param rank
  1188. * calculated by rankHand_java()
  1189. */
  1190. private static String name_hand(int rank) {
  1191.  
  1192. int type = (int) (rank / ID_GROUP_SIZE);
  1193. int ident = (int) (rank % ID_GROUP_SIZE), ident2;
  1194.  
  1195. String t = new String();
  1196.  
  1197. switch (type) {
  1198. case HIGH:
  1199. ident /= NUM_RANKS * NUM_RANKS * NUM_RANKS * NUM_RANKS;
  1200. t = rank_name[ident] + " High";
  1201. break;
  1202. case FLUSH:
  1203. ident /= NUM_RANKS * NUM_RANKS * NUM_RANKS * NUM_RANKS;
  1204. t = "a Flush, " + rank_name[ident] + " High";
  1205. break;
  1206. case PAIR:
  1207. ident /= NUM_RANKS * NUM_RANKS * NUM_RANKS;
  1208. t = "a Pair of " + rank_name[ident] + "s";
  1209. break;
  1210. case TWOPAIR:
  1211. ident2 = ident / (NUM_RANKS * NUM_RANKS);
  1212. ident = (ident % (NUM_RANKS * NUM_RANKS)) / NUM_RANKS;
  1213. t = "Two Pair, " + rank_name[ident2] + "s and " + rank_name[ident]
  1214. + "s";
  1215. break;
  1216. case THREEKIND:
  1217. t = "Three of a Kind, " + rank_name[ident / (NUM_RANKS * NUM_RANKS)]
  1218. + "s";
  1219. break;
  1220. case FULLHOUSE:
  1221. t = "a Full House, " + rank_name[ident / NUM_RANKS] + "s over "
  1222. + rank_name[ident % NUM_RANKS] + "s";
  1223. break;
  1224. case FOURKIND:
  1225. t = "Four of a Kind, " + rank_name[ident / NUM_RANKS] + "s";
  1226. break;
  1227. case STRAIGHT:
  1228. t = "a " + rank_name[ident] + " High Straight";
  1229. break;
  1230. case STRAIGHTFLUSH:
  1231. t = "a " + rank_name[ident] + " High Straight Flush";
  1232. break;
  1233. case FIVEKIND:
  1234. t = "Five of a Kind, " + rank_name[ident] + "s";
  1235. break;
  1236. default:
  1237. t = hand_name[type];
  1238. }
  1239.  
  1240. return t;
  1241. }
  1242.  
  1243.  
  1244.  
  1245. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement