PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/PokerAI/PowerRating.cs

https://github.com/juliusba/PokerBot
C# | 671 lines | 336 code | 36 blank | 299 comment | 166 complexity | 07d98ceb0affdbe943e149f827c9c958 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace PokerAI
  6. {
  7. class PowerRating
  8. {
  9. public int first { get; private set; }
  10. public int second { get; private set; }
  11. public int third { get; private set; }
  12. public int fourth { get; private set; }
  13. public int fift { get; private set; }
  14. public int sixth { get; private set; }
  15. public PowerRating(List<Card> hand)
  16. {
  17. string s = "";
  18. foreach (Card c in hand) s += c.ToString() + " ";
  19. //Console.WriteLine(s);
  20. if (hand.Count == 2)
  21. {
  22. if (hand[0].Value == hand[1].Value)
  23. {
  24. first = (hand[0].Value / 3) * 2;
  25. }
  26. else if (hand[0].Suit == hand[1].Suit)
  27. {
  28. first = 6;
  29. }
  30. else
  31. {
  32. first = (hand[0].Value / 2);
  33. }
  34. return;
  35. }
  36. hand = hand.OrderByDescending(c => c.Value).ToList();
  37. if (flushORstraightFlush(hand)) return;
  38. var ValueGroup = hand.GroupBy(c => c.Value).Select(g => new { value = g.Key, count = g.Count(), cards = g }).ToList();
  39. var valueGroupByCount = ValueGroup.OrderByDescending(vc => vc.count).ToList();
  40. int highestQuantity = valueGroupByCount.First().count;
  41. int highestQuantityValue = valueGroupByCount.First().value;
  42. if (highestQuantity == 4)
  43. {
  44. #region 4 of a kind
  45. first = 7;
  46. second = highestQuantityValue;
  47. third = ValueGroup[0].value == second ? ValueGroup[1].value : ValueGroup[0].value;
  48. #endregion
  49. }
  50. else
  51. {
  52. if (highestQuantity == 3 && valueGroupByCount[1].count > 1)
  53. {
  54. #region Full house
  55. first = 6;
  56. second = highestQuantityValue;
  57. if (valueGroupByCount.Count > 2 && valueGroupByCount[2].count > 1)
  58. third = Math.Max(valueGroupByCount[1].value, valueGroupByCount[2].value);
  59. else
  60. third = valueGroupByCount[1].value;
  61. #endregion
  62. }
  63. else
  64. {
  65. #region Check for straight
  66. int i = 0;
  67. while (i + 4 < ValueGroup.Count)
  68. {
  69. if (ValueGroup[i].value == ValueGroup[i + 4].value + 4)
  70. {
  71. first = 4;
  72. second = ValueGroup[i].value;
  73. return;
  74. }
  75. i++;
  76. }
  77. #endregion
  78. if (highestQuantity == 3)
  79. {
  80. #region 3 of a kind
  81. first = 3;
  82. second = highestQuantityValue;
  83. if (ValueGroup[0].value == second)
  84. third = ValueGroup[1].value;
  85. else
  86. third = ValueGroup[0].value;
  87. if (ValueGroup[1].value == second || ValueGroup[1].value == third)
  88. fourth = ValueGroup[2].value;
  89. else
  90. fourth = ValueGroup[1].value;
  91. #endregion
  92. }
  93. else if (highestQuantity == 2)
  94. {
  95. if (valueGroupByCount[1].count > 1)
  96. {
  97. #region Two pairs
  98. first = 2;
  99. second = highestQuantityValue;
  100. if (valueGroupByCount[2].count > 1)
  101. third = Math.Max(valueGroupByCount[1].value, valueGroupByCount[2].value);
  102. else
  103. third = valueGroupByCount[1].value;
  104. fourth = ValueGroup.First(vc => vc.value != second && vc.value != third).value;
  105. #endregion
  106. }
  107. else
  108. {
  109. #region One Pair
  110. first = 1;
  111. second = highestQuantityValue;
  112. i = 0;
  113. if (ValueGroup[0].value == highestQuantityValue) i = 1;
  114. third = ValueGroup[i].value;
  115. if (ValueGroup[1].value == highestQuantityValue) i = 1;
  116. fourth = ValueGroup[i + 1].value;
  117. if (ValueGroup[2].value == highestQuantityValue) i = 1;
  118. fift = ValueGroup[i + 2].value;
  119. return;
  120. #endregion
  121. }
  122. }
  123. else
  124. {
  125. #region Highcard
  126. first = 0;
  127. second = highestQuantityValue;
  128. third = ValueGroup[1].value;
  129. fourth = ValueGroup[2].value;
  130. fift = ValueGroup[3].value;
  131. sixth = ValueGroup[4].value;
  132. #endregion
  133. }
  134. }
  135. }
  136. }
  137. #region Unused code
  138. //var ValueGroup = hand.GroupBy(c => c.Value).Select(g => new { value = g.Key, count = g.Count() }).OrderBy(vc => vc.count).ThenBy(vc => vc.value).ToList();
  139. //switch (ValueGroup[0].count)
  140. //{
  141. // case 4:
  142. // break;
  143. //}
  144. //List<int> valueCount = new List<int>(13){0,0,0,0,0,0,0,0,0,0,0,0,0};
  145. //List<int> suitCount = new List<int>(4){0,0,0,0};
  146. //foreach (Card c in hand)
  147. //{
  148. // suitCount[(int)c.Suit]++;
  149. // valueCount[c.Value]++;
  150. //}
  151. //bool flush = suitCount.Max() >= 5;
  152. //int straightCount = 0;
  153. //int highest = -1;
  154. //bool straight = false;
  155. //for (int i = 12; i >= 0; i--)
  156. //{
  157. // if (valueCount[i] > 0)
  158. // {
  159. // straightCount++;
  160. // if (straightCount == 5)
  161. // {
  162. // straight = true;
  163. // highest = i+4;
  164. // break;
  165. // }
  166. // }
  167. // else straightCount = 0;
  168. //}
  169. //if (straightCount >= 4 && valueCount[12] > 0)
  170. //{
  171. // straight = true;
  172. // highest = 12;
  173. //}
  174. //if (flush & straight)
  175. //{
  176. // List<Card> temp = hand.Where(c => ((int) c.Suit) == suitCount.IndexOf(suitCount.Max())).OrderByDescending(c => c.Value).ToList();
  177. // int i = 0;
  178. // while (i + 4 < temp.Count)
  179. // {
  180. // if (temp[i].Value == temp[i + 4].Value + 4)
  181. // {
  182. // first = 8;
  183. // second = temp[i].Value;
  184. // return;
  185. // }
  186. // i++;
  187. // }
  188. //}
  189. //int highestValueQuantity = ValueGroup.Max();
  190. //switch (highestValueQuantity)
  191. //{
  192. // case 4:
  193. // first = 7;
  194. // second = ValueGroup.IndexOf(4);
  195. // third = Math.Max(Math.Max(ValueGroup.IndexOf(3), ValueGroup.IndexOf(2)), ValueGroup.IndexOf(1));
  196. // break;
  197. // case 3:
  198. // first = 6;
  199. // second = ValueGroup.LastIndexOf(3);
  200. // third = Math.Max(ValueGroup.LastIndexOf(second - 1, 3), ValueGroup.LastIndexOf(2));
  201. // if (third == -1)
  202. // {
  203. // first = 3;
  204. // third = ValueGroup.LastIndexOf(1);
  205. // fourth = ValueGroup.FindLastIndex(third - 1, v => v == 1);
  206. // }
  207. // break;
  208. // case 2:
  209. // if (!straight && !flush)
  210. // {
  211. // second = ValueGroup.LastIndexOf(2);
  212. // third = ValueGroup.FindLastIndex(second - 1, v => v == 2);
  213. // if (third != -1)
  214. // {
  215. // first = 2;
  216. // fourth = ValueGroup.LastIndexOf(1);
  217. // }
  218. // else
  219. // {
  220. // first = 1;
  221. // third = ValueGroup.LastIndexOf(1);
  222. // fourth = ValueGroup.FindLastIndex(third - 1, v => v == 1);
  223. // fift = ValueGroup.FindLastIndex(fourth - 1, v => v == 1);
  224. // }
  225. // }
  226. // break;
  227. // case 1:
  228. // if (!straight && !flush)
  229. // {
  230. // first = 0;
  231. // second = ValueGroup.LastIndexOf(1);
  232. // third = ValueGroup.FindLastIndex(second - 1, v => v == 0);
  233. // fourth = ValueGroup.FindLastIndex(third - 1, v => v == 0);
  234. // fift = ValueGroup.FindLastIndex(fourth - 1, v => v == 0);
  235. // sixth = ValueGroup.FindLastIndex(fift - 1, v => v == 0);
  236. // }
  237. // break;
  238. //}
  239. //}
  240. //private straight(var )
  241. //{
  242. // while (i + 4 < ValueGroup.Count)
  243. // {
  244. // if (ValueGroup[i].value == ValueGroup[i + 4].value + 4)
  245. // {
  246. // first = 4;
  247. // second = ValueGroup[i].Value;
  248. // return;
  249. // }
  250. // i++;
  251. // }
  252. //}
  253. #endregion
  254. private bool flushORstraightFlush(List<Card> hand)
  255. {
  256. var flushGroup = hand.GroupBy(c => c.Suit).FirstOrDefault(g => g.Count() >= 5);
  257. bool flush = flushGroup != null;
  258. if (flush)
  259. {
  260. var flushCards = flushGroup.ToList();
  261. int i = 0;
  262. while (i + 4 < flushCards.Count)
  263. {
  264. if (flushCards[i].Value == flushCards[i + 4].Value + 4)
  265. {
  266. first = 8;
  267. second = flushCards[i].Value;
  268. return true;
  269. }
  270. i++;
  271. }
  272. first = 5;
  273. second = flushCards[0].Value;
  274. third = flushCards[1].Value;
  275. fourth = flushCards[2].Value;
  276. fift = flushCards[3].Value;
  277. sixth = flushCards[4].Value;
  278. return true;
  279. }
  280. return false;
  281. }
  282. public int betterThan(PowerRating other)
  283. {
  284. if (this.first != other.first) return this.first > other.first ? 1 : -1;
  285. else if (this.second != other.second) return this.second > other.second ? 1 : -1;
  286. else if (this.third != other.third) return this.third > other.third ? 1 : -1;
  287. else if (this.fourth != other.fourth) return this.fourth > other.fourth ? 1 : -1;
  288. else if (this.fift != other.fift) return this.fift > other.fift ? 1 : -1;
  289. else if (this.sixth != other.sixth) return this.sixth > other.sixth ? 1 : -1;
  290. else return 0;
  291. }
  292. public string ToString()
  293. {
  294. return "(" + first + ", " + second + ", " + third + ", " + fourth + ", " + fift + ", " + sixth + ")";
  295. }
  296. public bool betterThan(List<Card> hand)
  297. {
  298. /*
  299. hand = hand.OrderByDescending(c => c.Value).ToList();
  300. var ValueGroup = hand.GroupBy(c => c.Value).Select(g => new { value = g.Key, count = g.Count(), cards = g }).ToList();
  301. var valueGroupByCount = ValueGroup.OrderByDescending(vc => vc.count).ToList();
  302. int highestQuantity = valueGroupByCount.First().count;
  303. int highestQuantityValue = valueGroupByCount.First().value;
  304. bool falseIfStraight;
  305. bool falseIfFlush;
  306. bool falseIfStraightFlush;
  307. bool temp = false;
  308. switch (first)
  309. {
  310. case 0:
  311. if (valueGroupByCount[0].value > 1 || straightOrFlush(hand))
  312. return true;
  313. else if (second > ValueGroup[0].value) return true;
  314. else if (third > ValueGroup[1].value) return true;
  315. else if (fourth > ValueGroup[2].value) return true;
  316. else if (fift > ValueGroup[3].value) return true;
  317. else
  318. {
  319. temp = sixth >= ValueGroup[4].value;
  320. }
  321. break;
  322. case 1:
  323. if (valueGroupByCount[0].value > 2 || (valueGroupByCount[0].value == 2 && valueGroupByCount[1].count > 2))
  324. return true;
  325. else if (valueGroupByCount[0].value == 1)
  326. return false;
  327. else
  328. {
  329. if (straightOrFlush(hand)) return false;
  330. }
  331. return 0;
  332. break;
  333. }
  334. */
  335. var ValueGroup = hand.GroupBy(c => c.Value).Select(g => new { value = g.Key, count = g.Count(), cards = g }).ToList();
  336. var valueGroupByCount = ValueGroup.OrderByDescending(vc => vc.count).ToList();
  337. int highestQuantity = valueGroupByCount.First().count;
  338. int highestQuantityValue = valueGroupByCount.First().value;
  339. var flushGroup = hand.GroupBy(c => c.Suit).FirstOrDefault(g => g.Count() >= 5);
  340. bool flush = flushGroup != null;
  341. if (flush)
  342. {
  343. if (first < 5)
  344. return true;
  345. var flushCards = flushGroup.ToList();
  346. int i = 0;
  347. while (i + 4 < flushCards.Count)
  348. {
  349. if (flushCards[i].Value == flushCards[i + 4].Value + 4)
  350. {
  351. return first == 8 && second >= flushCards[i].Value;
  352. }
  353. i++;
  354. }
  355. if (first == 5)
  356. return second >= flushCards[0].Value;
  357. }
  358. if (first == 8) return true;
  359. if (highestQuantity == 4)
  360. {
  361. if (first == 7)
  362. {
  363. if (second > highestQuantityValue)
  364. return true;
  365. else if (second == highestQuantityValue)
  366. {
  367. int otherThird = ValueGroup[0].value == second ? ValueGroup[1].value : ValueGroup[0].value;
  368. return third >= otherThird;
  369. }
  370. return false;
  371. }
  372. else
  373. {
  374. if (highestQuantity == 3 && valueGroupByCount[1].count > 1)
  375. {
  376. if (first == 6)
  377. {
  378. if (second > highestQuantityValue)
  379. return true;
  380. else if (second == highestQuantityValue)
  381. {
  382. if (valueGroupByCount.Count > 2 && valueGroupByCount[2].count > 1)
  383. return third >= Math.Max(valueGroupByCount[1].value, valueGroupByCount[2].value);
  384. else
  385. return third >= valueGroupByCount[1].value;
  386. }
  387. }
  388. return false;
  389. }
  390. else
  391. {
  392. if (first > 4) return true;
  393. int i = 0;
  394. while (i + 4 < ValueGroup.Count)
  395. {
  396. if (ValueGroup[i].value == ValueGroup[i + 4].value + 4)
  397. {
  398. if (first == 4 && second >= ValueGroup[i].value) return true;
  399. return false;
  400. }
  401. i++;
  402. }
  403. if (first == 4) return true;
  404. if (highestQuantity == 3)
  405. {
  406. if (first == 3)
  407. {
  408. int tempSecond = highestQuantityValue;
  409. if (second > tempSecond) return true;
  410. if (second == tempSecond)
  411. {
  412. int tempThird = 0;
  413. if (ValueGroup[0].value == second)
  414. tempThird = ValueGroup[1].value;
  415. else
  416. tempThird = ValueGroup[0].value;
  417. if (third > tempThird) return true;
  418. if (third == tempThird)
  419. {
  420. if (ValueGroup[1].value == second || ValueGroup[1].value == third)
  421. return fourth >= ValueGroup[2].value;
  422. else
  423. return fourth >= ValueGroup[1].value;
  424. }
  425. }
  426. }
  427. return false;
  428. }
  429. if(first == 3) return true;
  430. if (highestQuantity == 2)
  431. {
  432. if (valueGroupByCount[1].count > 1)
  433. {
  434. if (first == 2)
  435. {
  436. if (second > highestQuantityValue) return true;
  437. if (second == highestQuantityValue)
  438. {
  439. int tempThird = 0;
  440. if (valueGroupByCount[2].count > 1)
  441. tempThird = Math.Max(valueGroupByCount[1].value, valueGroupByCount[2].value);
  442. else
  443. tempThird = valueGroupByCount[1].value;
  444. if (third > tempThird) return true;
  445. else if (third == tempThird && fourth >= ValueGroup.First(vc => vc.value != second && vc.value != third).value) return true;
  446. }
  447. }
  448. return false;
  449. }
  450. if (first == 2) return true;
  451. if(first == 1)
  452. {
  453. if (second > highestQuantityValue) return true;
  454. if (second == highestQuantityValue)
  455. {
  456. if (third > ValueGroup[1].value) return true;
  457. if (third == ValueGroup[1].value)
  458. {
  459. if (fourth > ValueGroup[2].value) return true;
  460. return fourth == ValueGroup[2].value && fift >= ValueGroup[3].value;
  461. }
  462. }
  463. }
  464. return false;
  465. }
  466. else
  467. {
  468. if (second > highestQuantityValue) return true;
  469. if (second == highestQuantityValue)
  470. {
  471. if (third > ValueGroup[1].value) return true;
  472. if (third == ValueGroup[1].value)
  473. {
  474. if (fourth > ValueGroup[2].value) return true;
  475. if(fourth == ValueGroup[2].value)
  476. {
  477. if (fift > ValueGroup[3].value) return true;
  478. return fift == ValueGroup[3].value && sixth >= ValueGroup[4].value;
  479. }
  480. }
  481. }
  482. }
  483. }
  484. }
  485. }
  486. return false;
  487. }
  488. /*
  489. private static int betterThanZero(List<Card> hand)
  490. {
  491. hand = hand.OrderByDescending(c => c.Value).ToList();
  492. var ValueGroup = hand.GroupBy(c => c.Value).Select(g => new { value = g.Key, count = g.Count(), cards = g }).ToList();
  493. if (ValueGroup.OrderByDescending(vc => vc.count).First().value > 1 || straightOrFlush(hand))
  494. return 1;
  495. return 0;
  496. }
  497. private static int betterThanOne(List<Card> hand)
  498. {
  499. hand = hand.OrderByDescending(c => c.Value).ToList();
  500. var ValueGroup = hand.GroupBy(c => c.Value).Select(g => new { value = g.Key, count = g.Count(), cards = g }).ToList();
  501. var valueGroupByCount = ValueGroup.OrderByDescending(vc => vc.count).ToList();
  502. if (valueGroupByCount[0].value > 2 || (valueGroupByCount[0].value == 2 && valueGroupByCount[1].count > 2) || straightOrFlush(hand))
  503. return 1;
  504. else if (valueGroupByCount[0].value == 1)
  505. return -1;
  506. return 0;
  507. }
  508. private static int betterThanTwo(List<Card> hand)
  509. {
  510. hand = hand.OrderByDescending(c => c.Value).ToList();
  511. var ValueGroup = hand.GroupBy(c => c.Value).Select(g => new { value = g.Key, count = g.Count(), cards = g }).ToList();
  512. var valueGroupByCount = ValueGroup.OrderByDescending(vc => vc.count).ToList();
  513. if (valueGroupByCount[0].value > 2 || straightOrFlush(hand))
  514. return 1;
  515. else if (valueGroupByCount[0].value < 2 || valueGroupByCount[1].count == 1)
  516. return -1;
  517. return 0;
  518. }
  519. private static int betterThanThree(List<Card> hand)
  520. {
  521. hand = hand.OrderByDescending(c => c.Value).ToList();
  522. var ValueGroup = hand.GroupBy(c => c.Value).Select(g => new { value = g.Key, count = g.Count(), cards = g }).ToList();
  523. var valueGroupByCount = ValueGroup.OrderByDescending(vc => vc.count).ToList();
  524. if (valueGroupByCount[0].value > 3 || (valueGroupByCount[0].value == 3 && valueGroupByCount[1].count > 1) || flushOrStraightFlush(hand) || straight(hand))
  525. return 1;
  526. else if (valueGroupByCount[0].value < 3)
  527. return -1;
  528. return 0;
  529. }
  530. private static int betterThanFour(List<Card> hand)
  531. {
  532. hand = hand.OrderByDescending(c => c.Value).ToList();
  533. if(flushOrStraightFlush(hand))
  534. return 1;
  535. var ValueGroup = hand.GroupBy(c => c.Value).Select(g => new { value = g.Key, count = g.Count(), cards = g }).ToList();
  536. var valueGroupByCount = ValueGroup.OrderByDescending(vc => vc.count).ToList();
  537. if (valueGroupByCount[0].value > 3 || (valueGroupByCount[0].value == 3 && valueGroupByCount[1].count > 1))
  538. return 1;
  539. else if (!straight(ValueGroup))
  540. return -1;
  541. return 0;
  542. }
  543. private static int betterThanFive(List<Card> hand)
  544. {
  545. hand = hand.OrderByDescending(c => c.Value).ToList();
  546. var ValueGroup = hand.GroupBy(c => c.Value).Select(g => new { value = g.Key, count = g.Count(), cards = g }).ToList();
  547. var valueGroupByCount = ValueGroup.OrderByDescending(vc => vc.count).ToList();
  548. if (valueGroupByCount[0].value > 3 || (valueGroupByCount[0].value == 3 && valueGroupByCount[1].count > 1) || straightFlush(hand))
  549. return 1;
  550. else if (!flush(hand))
  551. return -1;
  552. return 0;
  553. }
  554. private static int betterThanSix(List<Card> hand)
  555. {
  556. hand = hand.OrderByDescending(c => c.Value).ToList();
  557. var ValueGroup = hand.GroupBy(c => c.Value).Select(g => new { value = g.Key, count = g.Count(), cards = g }).ToList();
  558. var valueGroupByCount = ValueGroup.OrderByDescending(vc => vc.count).ToList();
  559. if (valueGroupByCount[0].value > 3 || straightFlush(hand))
  560. return 1;
  561. else if (!(valueGroupByCount[0].value == 3 && valueGroupByCount[1].count > 1))
  562. return -1;
  563. return 0;
  564. }
  565. private static int betterThanSeven(List<Card> hand)
  566. {
  567. hand = hand.OrderByDescending(c => c.Value).ToList();
  568. if (straightFlush(hand))
  569. return 1;
  570. else
  571. {
  572. var ValueGroup = hand.GroupBy(c => c.Value).Select(g => new { value = g.Key, count = g.Count(), cards = g }).ToList();
  573. var valueGroupByCount = ValueGroup.OrderByDescending(vc => vc.count).ToList();
  574. if (!(valueGroupByCount[0].value < 4))
  575. return -1;
  576. }
  577. return 0;
  578. }
  579. private static bool straight(List<Card> hand)
  580. {
  581. int i = 0;
  582. while (i + 4 < ValueGroup.Count)
  583. {
  584. if (ValueGroup[i].value == ValueGroup[i + 4].value + 4)
  585. return true;
  586. i++;
  587. }
  588. return false;
  589. }
  590. private static bool flush(List<Card> hand)
  591. {
  592. return false;
  593. }
  594. private static bool straightOrFlush(List<Card> hand)
  595. {
  596. return false;
  597. }
  598. private static bool flushOrStraightFlush(List<Card> hand)
  599. {
  600. return false;
  601. }
  602. private static bool straightFlush(List<Card> hand)
  603. {
  604. return false;
  605. }
  606. */
  607. }
  608. }