From 37cb960484c26f47f9ed9e7ee56fe5a97cadaa1d Mon Sep 17 00:00:00 2001
From: Dominic Masters <dominic@domsplace.com>
Date: Wed, 6 Oct 2021 09:56:27 -0700
Subject: [PATCH] Writing more tests.

---
 src/poker2/poker.c  | 138 +++++++++++++++++++++++++++++++++++++++++++-
 src/poker2/poker.h  |   6 +-
 test/poker2/poker.c |  57 ++++++++++++++++++
 3 files changed, 199 insertions(+), 2 deletions(-)

diff --git a/src/poker2/poker.c b/src/poker2/poker.c
index 1047afc3..890b9f62 100644
--- a/src/poker2/poker.c
+++ b/src/poker2/poker.c
@@ -484,4 +484,140 @@ void pokerWinnerGetForPlayer(
   winning->type = POKER_WINNING_TYPE_HIGH_CARD;
 
   return;
-}
\ No newline at end of file
+}
+
+card_t debug_pokerWinnerCompare(poker2playerwinning_t *left, poker2playerwinning_t *right) {
+  uint8_t i, number;
+  card_t card;
+  int32_t index;
+  uint8_t countCardsSame;
+
+  card_t highCardLeft, highCardRight;
+  uint8_t highNumberLeft, highNumberRight;
+
+  highNumberLeft = 0xFF;
+  highNumberRight = 0xFF;
+  countCardsSame = 0;
+
+
+  for(i = 0; i < left->setSize; i++) {
+    card = left->set[i];
+    number = cardGetNumber(card);
+    if(highNumberLeft != 0xFF && number < highNumberLeft) continue;// Quick check
+
+    // Check if this number is within the other hand or not
+    index = cardContainsNumber(right->set, right->setSize, number);
+    if(index != -1) {
+      // This number IS within the other hand, let's check that the EXACT card
+      // is a match/isn't a match.
+      index = cardContains(right->set, right->setSize, card);
+
+      // Exact card match
+      if(index != -1) {
+        countCardsSame++;
+        continue;
+      }
+      // Not exact card match.. ?
+    }
+
+    if(highNumberLeft == 0xFF||number == CARD_ACE||highNumberLeft < number) {
+      highNumberLeft = number;
+      highCardLeft = card;
+    }
+  }
+  
+  for(i = 0; i < right->setSize; i++) {
+    card = right->set[i];
+    number = cardGetNumber(card);
+    if(highNumberRight != 0xFF && number < highNumberRight) continue;
+    
+    index = cardContainsNumber(left->set, left->setSize, number);
+    if(index != -1) {
+      index = cardContains(left->set, left->setSize, card);
+      if(index != -1) continue;
+    }
+
+    if(highNumberRight == 0xFF||number == CARD_ACE||highNumberRight < number) {
+      highNumberRight = number;
+      highCardRight = card;
+    }
+  }
+
+
+  if(countCardsSame == left->setSize) {
+    for(i = 0; i < left->setSize; i++) {
+      card = left->set[i];
+      number = cardGetNumber(card);
+      if(highNumberLeft == 0xFF||number == CARD_ACE||highNumberLeft < number) {
+        highNumberLeft = number;
+        highCardLeft = card;
+      }
+    }
+    return highCardLeft;
+  }
+
+  if(highCardLeft == 0xFF) return 0xFF;
+  if(highNumberLeft < highNumberRight) return 0xFF;
+  return highCardLeft;//Greater or Equal to.
+}
+
+void pokerWinnerDetermine(poker2_t *poker) {
+  uint8_t i, j, number, highNumber;
+  poker2playerwinning_t *left, *right;
+  poker2player_t *player;
+  card_t card, highCard;
+  bool isWinner;
+
+  poker->winnerCount = 0;
+  highCard = 0xFF;
+
+  // Get winning sets
+  for(i = 0; i < poker->playerCount; i++) {
+    left = poker->winners + i;
+    left->type = POKER_WINNING_TYPE_NULL;
+    player = poker->players + i;
+    if(!pokerPlayerIsInRound(player)) continue;
+
+    // Get the players' winning state.
+    pokerWinnerGetForPlayer(poker, player, left);
+  }
+
+  // Compare against each player
+  for(i = 0; i < poker->playerCount; i++) {
+    left = poker->winners + i;
+    if(left->type == POKER_WINNING_TYPE_NULL) continue;
+
+    isWinner = true;
+    highNumber = 0xFF;
+
+    for(j = 0; j < poker->playerCount; j++) {
+      if(i == j) continue;
+      right = poker->winners + j;
+      if(right->type == POKER_WINNING_TYPE_NULL) continue;
+
+      // Am I the better hand / Is it the better hand?
+      if(left->type < right->type) continue;
+      if(left->type > right->type) {
+        isWinner = false;
+        break;
+      }
+
+      // Equal, compare hands.
+      card = pokerWinnerCompare(left, right);
+      if(card == 0xFF) {
+        isWinner = false;
+        break;
+      }
+
+      // Determine high card.
+      number = cardGetNumber(card);
+      if(highNumber == 0xFF || number == CARD_ACE || number > highNumber) {
+        highCard = card;
+        highNumber = number;
+      }
+    }
+
+    if(!isWinner) continue;
+    left->kicker = highCard;
+  }
+}
diff --git a/src/poker2/poker.h b/src/poker2/poker.h
index c8466f91..45d5526e 100644
--- a/src/poker2/poker.h
+++ b/src/poker2/poker.h
@@ -117,6 +117,9 @@ typedef struct {
   uint8_t playerDealer;
   uint8_t playerSmallBlind;
   uint8_t playerBigBlind;
+
+  poker2playerwinning_t winners[POKER_PLAYER_COUNT_MAX];
+  uint8_t winnerCount;
 } poker2_t;
 
 
@@ -158,4 +161,5 @@ void pokerHandGetFull(
 void debug_WinnerFillRemaining(poker2playerwinning_t *winning);
 void pokerWinnerGetForPlayer(
   poker2_t *poker, poker2player_t *player, poker2playerwinning_t *winning
-);
\ No newline at end of file
+);
+card_t debug_pokerWinnerCompare(poker2playerwinning_t *left, poker2playerwinning_t *right);
\ No newline at end of file
diff --git a/test/poker2/poker.c b/test/poker2/poker.c
index 208e0586..4082fa10 100644
--- a/test/poker2/poker.c
+++ b/test/poker2/poker.c
@@ -1239,6 +1239,62 @@ void test_pokerWinnerGetForPlayer_should_CalculateRoyalFlush(void) {
   TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_TEN, winning.set[4]);
 }
 
+void test_pokerWinnerCompare_should_CompareWinningHands(void) {
+  poker2_t poker;
+  uint8_t p0i, p1i;
+  poker2player_t *p0;
+  poker2player_t *p1;
+  poker2playerwinning_t w0, w1;
+  card_t kicker;
+
+  // Construct two hands of the same type (pairs of eights)
+  pokerInit(&poker);
+  p0i = pokerPlayerAdd(&poker);
+  p1i = pokerPlayerAdd(&poker);
+  p0 = poker.players + p0i;
+  p1 = poker.players + p1i;
+
+  poker.communitySize = 5;
+  poker.community[0] = CARD_HEARTS_TWO;
+  poker.community[1] = CARD_DIAMONDS_NINE;
+  poker.community[2] = CARD_DIAMONDS_FOUR;
+  poker.community[3] = CARD_CLUBS_SIX;
+  poker.community[4] = CARD_HEARTS_EIGHT;
+
+  p0->cardCount = 2;
+  p0->cards[0] = CARD_CLUBS_EIGHT;
+  p0->cards[1] = CARD_CLUBS_KING;//Higher, Kicker
+
+  p1->cardCount = 2;
+  p1->cards[0] = CARD_SPADES_EIGHT;
+  p1->cards[1] = CARD_CLUBS_QUEEN;//Low, not
+
+  // Confirm both hands are pairs.
+  pokerWinnerGetForPlayer(&poker, p0, &w0);
+  pokerWinnerGetForPlayer(&poker, p1, &w1);
+  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_PAIR, w0.type);
+  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_PAIR, w1.type);
+  TEST_ASSERT_EQUAL_UINT8(w0.type, w1.type);
+
+  // Get the kicker, should be the king.
+  kicker = debug_pokerWinnerCompare(&w0, &w1);
+  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_KING, kicker);
+
+  // Change the kickers
+  p0->cards[1] = CARD_HEARTS_ACE;
+  p1->cards[1] = CARD_CLUBS_KING;
+  pokerWinnerGetForPlayer(&poker, p0, &w0);
+  pokerWinnerGetForPlayer(&poker, p1, &w1);
+  kicker = debug_pokerWinnerCompare(&w0, &w1);
+  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_ACE, kicker);
+
+  // Low left weight
+  p0->cards[1] = CARD_HEARTS_JACK;
+  pokerWinnerGetForPlayer(&poker, p0, &w0);
+  kicker = debug_pokerWinnerCompare(&w0, &w1);
+  TEST_ASSERT_EQUAL_UINT8(0xFF, kicker);
+}
+
 int test_poker2() {
   UNITY_BEGIN();
 
@@ -1289,6 +1345,7 @@ int test_poker2() {
   RUN_TEST(test_pokerWinnerGetForPlayer_should_CalculateFourOfAKind);
   RUN_TEST(test_pokerWinnerGetForPlayer_should_CalculateStraightFlush);
   RUN_TEST(test_pokerWinnerGetForPlayer_should_CalculateRoyalFlush);
+  RUN_TEST(test_pokerWinnerCompare_should_CompareWinningHands);
 
   return UNITY_END();
 }
\ No newline at end of file