From a74712b7714b3400067f9789c1371875a77eee6b Mon Sep 17 00:00:00 2001
From: Dominic Masters <dominic@domsplace.com>
Date: Sun, 3 Oct 2021 21:43:40 -0700
Subject: [PATCH] Added more poker tests.

---
 src/poker/bet.c     |   6 +++
 src/poker/dealer.c  |   5 ++
 src/poker2/poker.c  |  23 ++++++++-
 src/poker2/poker.h  |   4 +-
 test/poker2/poker.c | 121 +++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 155 insertions(+), 4 deletions(-)

diff --git a/src/poker/bet.c b/src/poker/bet.c
index 94f35417..d820b407 100644
--- a/src/poker/bet.c
+++ b/src/poker/bet.c
@@ -7,20 +7,24 @@
 
 #include "bet.h"
 
+// Done
 void pokerBetInit(pokerbet_t *bet) {
   bet->blindBig = POKER_BET_BLIND_BIG_DEFAULT;
   bet->blindSmall = POKER_BET_BLIND_SMALL_DEFAULT;
 }
 
+// Done
 void pokerBetReset(pokerbet_t *bet) {
   bet->pot = 0;
   bet->currentBet = 0;
 }
 
+// Not needed
 uint8_t pokerBetGetRoundPlayerDefault(uint8_t roundSmallBlind) {
   return (roundSmallBlind + 1) % POKER_PLAYER_COUNT;
 }
 
+// Done
 void pokerBetPlayer(pokerbet_t *bet, pokerplayer_t *player, int32_t chips) {
   bet->pot += chips;
   player->chips -= chips;
@@ -28,6 +32,7 @@ void pokerBetPlayer(pokerbet_t *bet, pokerplayer_t *player, int32_t chips) {
   bet->currentBet = mathMax(bet->currentBet, player->currentBet);
 }
 
+// Doneish
 void pokerBetResetBetter(
   pokerbet_t *bet, pokerplayer_t *players, uint8_t roundSmallBlind
 ) {
@@ -50,6 +55,7 @@ void pokerBetResetBetter(
   bet->better = pokerBetGetRemainingPlayer(bet, players, roundSmallBlind);
 }
 
+// Doneish
 bool pokerBetPlayerCanBet(pokerbet_t *bet, pokerplayer_t *player) {
   // Is the player out?
   if(!pokerPlayerIsInRound(player)) return false;
diff --git a/src/poker/dealer.c b/src/poker/dealer.c
index 29c5e0ac..7bb24c0c 100644
--- a/src/poker/dealer.c
+++ b/src/poker/dealer.c
@@ -6,6 +6,7 @@
  */
 #include "dealer.h"
 
+//Not needed
 void pokerDealerInit(pokerdealer_t *dealer) {
   uint8_t i;
 
@@ -15,6 +16,7 @@ void pokerDealerInit(pokerdealer_t *dealer) {
   for(i = 0; i < CARD_DECK_SIZE; i++) dealer->deck[i] = i;
 }
 
+// Done
 void pokerDealerTurn(pokerdealer_t *dealer, uint8_t count) {
   uint8_t i;
   for(i = 0; i < count; i++) {
@@ -25,6 +27,7 @@ void pokerDealerTurn(pokerdealer_t *dealer, uint8_t count) {
   }
 }
 
+// Done
 void pokerDealerBurn(pokerdealer_t *dealer, uint8_t count) {
   uint8_t i;
   for(i = 0; i < count; i++) {
@@ -35,10 +38,12 @@ void pokerDealerBurn(pokerdealer_t *dealer, uint8_t count) {
   }
 }
 
+// Done
 void pokerDealerDeal(pokerdealer_t *dealer, pokerplayer_t *player) {
   cardDeal(dealer->deck, &dealer->deckSize, player->cards, &player->cardCount);
 }
 
+// Done
 void pokerDealerDealAll(
   pokerdealer_t *dealer, pokerplayer_t *players, uint8_t count
 ) {
diff --git a/src/poker2/poker.c b/src/poker2/poker.c
index 1fd08baa..608e0a28 100644
--- a/src/poker2/poker.c
+++ b/src/poker2/poker.c
@@ -9,7 +9,6 @@
 
 void pokerInit(poker2_t *poker) {
   poker->playerCount = 0;
-  poker->state = 0;
   poker->playerDealer = 0;
   poker->playerSmallBlind = 0;
   poker->playerBigBlind = 0;
@@ -168,6 +167,28 @@ bool pokerPlayerDoesNeedToBetThisRound(poker2_t *poker, uint8_t playerIndex) {
   return false;
 }
 
+uint8_t pokerPlayerGetRemainingBetter(poker2_t *poker) {
+  uint8_t i, j;
+  poker2player_t *player;
+
+  for(i = 0; i < poker->playerCount; i++) {
+    j = (i + poker->playerBigBlind + 1) % poker->playerCount;
+    if(pokerPlayerDoesNeedToBetThisRound(poker, j)) return j;
+  }
+  return 0xFF;
+}
+
+uint8_t pokerPlayerGetNextBetter(poker2_t *poker, uint8_t current) {
+  uint8_t i, j;
+  poker2player_t *player;
+
+  for(i = 0; i < poker->playerCount; i++) {
+    j = (i + current + 1) % poker->playerCount;
+    if(pokerPlayerDoesNeedToBetThisRound(poker, j)) return j;
+  }
+  return 0xFF;
+}
+
 // Betting
 void pokerPlayerBetPot(
   poker2_t *poker, poker2pot_t *pot, uint8_t playerIndex, int32_t chips
diff --git a/src/poker2/poker.h b/src/poker2/poker.h
index 8314e6d4..60537f82 100644
--- a/src/poker2/poker.h
+++ b/src/poker2/poker.h
@@ -56,8 +56,6 @@ typedef struct {
   uint8_t playerDealer;
   uint8_t playerSmallBlind;
   uint8_t playerBigBlind;
-
-  uint8_t state;
 } poker2_t;
 
 
@@ -83,6 +81,8 @@ void pokerPlayerDeal(poker2_t *poker, poker2player_t *player, uint8_t count);
 void pokerPlayerChipsAdd(poker2player_t *player, int32_t chips);
 void pokerPlayerDealAll(poker2_t *poker, uint8_t count);
 bool pokerPlayerDoesNeedToBetThisRound(poker2_t *poker, uint8_t playerIndex);
+uint8_t pokerPlayerGetRemainingBetter(poker2_t *poker);
+uint8_t pokerPlayerGetNextBetter(poker2_t *poker, uint8_t current);
 void pokerPlayerBetPot(
   poker2_t *poker, poker2pot_t *pot, uint8_t playerIndex, int32_t chips
 );
diff --git a/test/poker2/poker.c b/test/poker2/poker.c
index 33c73fca..36e26879 100644
--- a/test/poker2/poker.c
+++ b/test/poker2/poker.c
@@ -11,7 +11,6 @@ void test_pokerInit_should_InitializePokerGame(void) {
   poker2_t poker;
   pokerInit(&poker);
   TEST_ASSERT_EQUAL_UINT8(0, poker.playerCount);
-  TEST_ASSERT_EQUAL_UINT8(0, poker.state);
   TEST_ASSERT_EQUAL_UINT8(0, poker.playerDealer);
   TEST_ASSERT_EQUAL_UINT8(0, poker.playerSmallBlind);
   TEST_ASSERT_EQUAL_UINT8(0, poker.playerBigBlind);
@@ -532,6 +531,124 @@ void test_pokerPlayerDoesNeedToBetThisRound_should_IgnoreFoldedPlayers(void) {
   TEST_ASSERT_EQUAL(false, pokerPlayerDoesNeedToBetThisRound(&poker, second));
 }
 
+void test_pokerPlayerGetRemainingBetter_should_ReturnRemainingBetters(void) {
+  poker2_t poker;
+  uint8_t p0, p1, p2, p3, p4;
+  pokerInit(&poker);
+
+
+  p0 = pokerPlayerAdd(&poker);
+  p1 = pokerPlayerAdd(&poker);
+  p2 = pokerPlayerAdd(&poker);
+  p3 = pokerPlayerAdd(&poker);
+  p4 = pokerPlayerAdd(&poker);
+
+  pokerPlayerChipsAdd(poker.players + p0, 10000);
+  pokerPlayerChipsAdd(poker.players + p1, 10000);
+  pokerPlayerChipsAdd(poker.players + p2, 10000);
+  pokerPlayerChipsAdd(poker.players + p3, 10000);
+  pokerPlayerChipsAdd(poker.players + p4, 10000);
+  pokerNewDealer(&poker);
+
+  // Blind + 1
+  TEST_ASSERT_EQUAL(0x04, pokerPlayerGetRemainingBetter(&poker));
+
+  // Blind + 2
+  pokerPlayerBet(&poker, 0x04, pokerGetCallValue(&poker));
+  TEST_ASSERT_EQUAL(0x00, pokerPlayerGetRemainingBetter(&poker));
+  
+  // Blind + 3
+  pokerPlayerBet(&poker, 0x00, pokerGetCallValue(&poker));
+  TEST_ASSERT_EQUAL(0x01, pokerPlayerGetRemainingBetter(&poker));
+
+  // Blind + 4 / Small Blind
+  pokerPlayerBet(&poker, 0x01, pokerGetCallValue(&poker));
+  TEST_ASSERT_EQUAL(0x02, pokerPlayerGetRemainingBetter(&poker));
+
+  // Blind + 5 / Big Blind
+  pokerPlayerBet(
+    &poker, 0x02, pokerGetCallValue(&poker) - poker.players[0x01].currentBet
+  );
+  TEST_ASSERT_EQUAL(0x03, pokerPlayerGetRemainingBetter(&poker));
+
+  // No remaining players.
+  pokerPlayerBet(&poker, 0x03, 0);
+  TEST_ASSERT_EQUAL(0xFF, pokerPlayerGetRemainingBetter(&poker));
+
+  // Raise
+  pokerPlayerBet(&poker, 0x03, 100);
+  TEST_ASSERT_EQUAL(0x04, pokerPlayerGetRemainingBetter(&poker));
+
+  // Raise
+  pokerPlayerBet(&poker, 0x04, 100);
+  TEST_ASSERT_EQUAL(0x00, pokerPlayerGetRemainingBetter(&poker));
+}
+
+void test_pokerPlayerGetNextBetter_should_GetTheNextBetter(void) {
+  poker2_t poker;
+  uint8_t p0, p1, p2, p3, p4;
+  uint8_t better;
+  pokerInit(&poker);
+
+  p0 = pokerPlayerAdd(&poker);
+  p1 = pokerPlayerAdd(&poker);
+  p2 = pokerPlayerAdd(&poker);
+  p3 = pokerPlayerAdd(&poker);
+  p4 = pokerPlayerAdd(&poker);
+
+  pokerPlayerChipsAdd(poker.players + p0, 10000);
+  pokerPlayerChipsAdd(poker.players + p1, 10000);
+  pokerPlayerChipsAdd(poker.players + p2, 10000);
+  pokerPlayerChipsAdd(poker.players + p3, 10000);
+  pokerPlayerChipsAdd(poker.players + p4, 10000);
+  pokerNewDealer(&poker);
+
+  // Start at blind+1
+  better = poker.playerBigBlind;
+  better = pokerPlayerGetNextBetter(&poker, better);
+  TEST_ASSERT_EQUAL_UINT8(0x04, better);
+
+  // Blind+2
+  pokerPlayerBet(&poker, better, pokerGetCallValue(&poker));
+  better = pokerPlayerGetNextBetter(&poker, better);
+  TEST_ASSERT_EQUAL_UINT8(0x00, better);
+
+  // BLind+3
+  pokerPlayerBet(&poker, better, pokerGetCallValue(&poker));
+  better = pokerPlayerGetNextBetter(&poker, better);
+  TEST_ASSERT_EQUAL_UINT8(0x01, better);
+
+  // Dealer
+  pokerPlayerBet(&poker, better, pokerGetCallValue(&poker));
+  better = pokerPlayerGetNextBetter(&poker, better);
+  TEST_ASSERT_EQUAL_UINT8(0x02, better);
+
+  // Small blind
+  pokerPlayerBet(
+    &poker, better, pokerGetCallValue(&poker) - poker.players[0x02].currentBet
+  );
+  better = pokerPlayerGetNextBetter(&poker, better);
+  TEST_ASSERT_EQUAL_UINT8(0x03, better);
+
+  // Big Blind
+  pokerPlayerBet(
+    &poker, better, pokerGetCallValue(&poker) - poker.players[0x03].currentBet
+  );
+  better = pokerPlayerGetNextBetter(&poker, better);
+  TEST_ASSERT_EQUAL_UINT8(0xFF, better);
+
+  // Raise
+  better = poker.playerBigBlind;
+  pokerPlayerBet(&poker, better, 100);
+  better = pokerPlayerGetNextBetter(&poker, better);
+  TEST_ASSERT_EQUAL_UINT8(0x04, better);
+
+  // Raise
+  pokerPlayerBet(&poker, better, 100);
+  better = pokerPlayerGetNextBetter(&poker, better);
+  TEST_ASSERT_EQUAL_UINT8(0x00, better);
+}
+
 void test_pokerPlayerBetPot_should_AddChipsToThePot(void) {
   poker2_t poker;
   poker2pot_t *pot;
@@ -620,6 +737,8 @@ int test_poker() {
   RUN_TEST(test_pokerPlayerDoesNeedToBetThisRound_should_CheckCallValue);
   RUN_TEST(test_pokerPlayerDoesNeedToBetThisRound_should_CheckWhetherHasBetYet);
   RUN_TEST(test_pokerPlayerDoesNeedToBetThisRound_should_IgnoreFoldedPlayers);
+  RUN_TEST(test_pokerPlayerGetRemainingBetter_should_ReturnRemainingBetters);
+  RUN_TEST(test_pokerPlayerGetNextBetter_should_GetTheNextBetter);
   RUN_TEST(test_pokerPlayerBetPot_should_AddChipsToThePot);
   RUN_TEST(test_pokerPlayerBetPot_should_UpdatePlayerState);
   RUN_TEST(test_pokerPlayerBet_should_BetToTheActivePot);