/**
 * Copyright (c) 2021 Dominic Masters
 * 
 * This software is released under the MIT License.
 * https://opensource.org/licenses/MIT
 */

#include "winner.h"

void test_pokerWinnerFillRemaining_should_FillTheRestOfTheArray(void) {
  pokerplayerwinning_t winning;
  winning.fullSize = 7;
  winning.full[0]  = CARD_CLUBS_ACE;
  winning.full[1]  = CARD_CLUBS_TWO;
  winning.full[2]  = CARD_CLUBS_THREE;
  winning.full[3]  = CARD_CLUBS_FOUR;
  winning.full[4]  = CARD_CLUBS_FIVE;
  winning.full[5]  = CARD_CLUBS_SIX;
  winning.full[6]  = CARD_CLUBS_SEVEN;

  cardHandSort(winning.full, 7);

  winning.setSize = 1;
  winning.set[0] = CARD_CLUBS_ACE;
  
  pokerWinnerFillRemaining(&winning);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_SET_SIZE, winning.setSize);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_ACE, winning.set[0]);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_SEVEN, winning.set[1]);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_SIX, winning.set[2]);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_FIVE, winning.set[3]);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_FOUR, winning.set[4]);
}

void test_pokerWinnerGetForPlayer_should_CalculateHighCard(void) {
  poker_t poker;
  uint8_t i;
  pokerplayer_t *player;
  pokerplayerwinning_t winning;

  pokerInit(&poker);
  i = pokerPlayerAdd(&poker);
  player = poker.players + i;

  poker.communitySize = 5;
  poker.community[0] = CARD_HEARTS_QUEEN;
  poker.community[1] = CARD_CLUBS_TWO;
  poker.community[2] = CARD_DIAMONDS_ACE;
  poker.community[3] = CARD_SPADES_NINE;
  poker.community[4] = CARD_HEARTS_SIX;

  player->cardCount = 2;
  player->cards[0] = CARD_CLUBS_FOUR;
  player->cards[1] = CARD_DIAMONDS_SEVEN;

  pokerWinnerGetForPlayer(&poker, player, &winning);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_FULL_SIZE, winning.fullSize);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_HIGH_CARD, winning.type);

  TEST_ASSERT_EQUAL_UINT8(0x05, winning.setSize);
  TEST_ASSERT_EQUAL_UINT8(CARD_DIAMONDS_ACE, winning.set[0]);
  TEST_ASSERT_EQUAL_UINT8(CARD_DIAMONDS_SEVEN, winning.set[1]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_QUEEN, winning.set[2]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_SIX, winning.set[3]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_NINE, winning.set[4]);
}

void test_pokerWinnerGetForPlayer_should_CalculatePair(void) {
  poker_t poker;
  uint8_t i;
  pokerplayer_t *player;
  pokerplayerwinning_t winning;

  pokerInit(&poker);
  i = pokerPlayerAdd(&poker);
  player = poker.players + i;

  poker.communitySize = 5;
  poker.community[0] = CARD_HEARTS_QUEEN;
  poker.community[1] = CARD_CLUBS_TWO;
  poker.community[2] = CARD_DIAMONDS_ACE;
  poker.community[3] = CARD_SPADES_QUEEN;
  poker.community[4] = CARD_HEARTS_SIX;

  player->cardCount = 2;
  player->cards[0] = CARD_CLUBS_FOUR;
  player->cards[1] = CARD_DIAMONDS_SEVEN;

  pokerWinnerGetForPlayer(&poker, player, &winning);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_FULL_SIZE, winning.fullSize);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_PAIR, winning.type);

  TEST_ASSERT_EQUAL_UINT8(0x05, winning.setSize);
  TEST_ASSERT_EQUAL_UINT8(CARD_DIAMONDS_ACE, winning.set[0]);
  TEST_ASSERT_EQUAL_UINT8(CARD_DIAMONDS_SEVEN, winning.set[1]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_QUEEN, winning.set[2]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_SIX, winning.set[3]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_QUEEN, winning.set[4]);

  poker.community[3] = CARD_SPADES_NINE;
  player->cards[0] = CARD_HEARTS_TWO;
  
  pokerWinnerGetForPlayer(&poker, player, &winning);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_PAIR, winning.type);
  TEST_ASSERT_EQUAL_UINT8(0x05, winning.setSize);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_TWO, winning.set[0]);
  TEST_ASSERT_EQUAL_UINT8(CARD_DIAMONDS_ACE, winning.set[1]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_QUEEN, winning.set[2]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_TWO, winning.set[3]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_NINE, winning.set[4]);
}

void test_pokerWinnerGetForPlayer_should_CalculateTwoPair(void) {
  poker_t poker;
  uint8_t i;
  pokerplayer_t *player;
  pokerplayerwinning_t winning;

  pokerInit(&poker);
  i = pokerPlayerAdd(&poker);
  player = poker.players + i;

  poker.communitySize = 5;
  poker.community[0] = CARD_HEARTS_ACE;
  poker.community[1] = CARD_CLUBS_THREE;
  poker.community[2] = CARD_SPADES_ACE;
  poker.community[3] = CARD_SPADES_QUEEN;
  poker.community[4] = CARD_HEARTS_SIX;
  player->cardCount = 2;
  player->cards[0] = CARD_CLUBS_TWO;
  player->cards[1] = CARD_DIAMONDS_TWO;

  pokerWinnerGetForPlayer(&poker, player, &winning);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_TWO_PAIR, winning.type);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_TWO, winning.set[0]);
  TEST_ASSERT_EQUAL_UINT8(CARD_DIAMONDS_TWO, winning.set[1]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_ACE, winning.set[2]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_ACE, winning.set[3]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_QUEEN, winning.set[4]);
}

void test_pokerWinnerGetForPlayer_should_CalculateThreeOfAKind(void) {
  poker_t poker;
  uint8_t i;
  pokerplayer_t *player;
  pokerplayerwinning_t winning;

  pokerInit(&poker);
  i = pokerPlayerAdd(&poker);
  player = poker.players + i;

  poker.communitySize = 5;
  poker.community[0] = CARD_HEARTS_ACE;
  poker.community[1] = CARD_CLUBS_THREE;
  poker.community[2] = CARD_SPADES_TWO;
  poker.community[3] = CARD_SPADES_QUEEN;
  poker.community[4] = CARD_HEARTS_SIX;
  player->cardCount = 2;
  player->cards[0] = CARD_CLUBS_TWO;
  player->cards[1] = CARD_DIAMONDS_TWO;

  pokerWinnerGetForPlayer(&poker, player, &winning);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_THREE_OF_A_KIND, winning.type);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_TWO, winning.set[0]);
  TEST_ASSERT_EQUAL_UINT8(CARD_DIAMONDS_TWO, winning.set[1]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_ACE, winning.set[2]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_QUEEN, winning.set[3]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_TWO, winning.set[4]);
}

void test_pokerWinnerGetForPlayer_should_CalculateAStraight(void) {
  poker_t poker;
  uint8_t i;
  pokerplayer_t *player;
  pokerplayerwinning_t winning;

  pokerInit(&poker);
  i = pokerPlayerAdd(&poker);
  player = poker.players + i;

  poker.communitySize = 5;
  poker.community[0] = CARD_HEARTS_ACE;//0 - 3
  poker.community[1] = CARD_CLUBS_THREE;//2 - 1
  poker.community[2] = CARD_SPADES_THREE;//Hmm?
  poker.community[3] = CARD_SPADES_QUEEN;
  poker.community[4] = CARD_HEARTS_FOUR;//3 - 4
  player->cardCount = 2;
  player->cards[0] = CARD_CLUBS_TWO;//1 - 0
  player->cards[1] = CARD_DIAMONDS_FIVE;//4 - 2

  pokerWinnerGetForPlayer(&poker, player, &winning);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_STRAIGHT, winning.type);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_THREE, winning.set[0]);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_TWO, winning.set[1]);
  TEST_ASSERT_EQUAL_UINT8(CARD_DIAMONDS_FIVE, winning.set[2]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_ACE, winning.set[3]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_FOUR, winning.set[4]);
}

void test_pokerWinnerGetForPlayer_should_CalculateAFlush(void) {
  poker_t poker;
  uint8_t i;
  pokerplayer_t *player;
  pokerplayerwinning_t winning;

  pokerInit(&poker);
  i = pokerPlayerAdd(&poker);
  player = poker.players + i;

  poker.communitySize = 5;
  poker.community[0] = CARD_HEARTS_ACE;
  poker.community[1] = CARD_SPADES_SIX;//+2
  poker.community[2] = CARD_SPADES_THREE;//+3
  poker.community[3] = CARD_SPADES_QUEEN;//+1
  poker.community[4] = CARD_HEARTS_NINE;
  player->cardCount = 2;
  player->cards[0] = CARD_SPADES_TWO;//+4
  player->cards[1] = CARD_SPADES_KING;//+0

  pokerWinnerGetForPlayer(&poker, player, &winning);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_FLUSH, winning.type);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_KING, winning.set[0]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_QUEEN, winning.set[1]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_SIX, winning.set[2]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_THREE, winning.set[3]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_TWO, winning.set[4]);
}

void test_pokerWinnerGet_should_CalculateFullHouse(void) {
  poker_t poker;
  uint8_t i;
  pokerplayer_t *player;
  pokerplayerwinning_t winning;

  pokerInit(&poker);
  i = pokerPlayerAdd(&poker);
  player = poker.players + i;

  poker.communitySize = 5;
  poker.community[0] = CARD_HEARTS_ACE;
  poker.community[1] = CARD_SPADES_SIX;
  poker.community[2] = CARD_SPADES_ACE;
  poker.community[3] = CARD_SPADES_QUEEN;
  poker.community[4] = CARD_DIAMONDS_TWO;
  player->cardCount = 2;
  player->cards[0] = CARD_SPADES_TWO;
  player->cards[1] = CARD_CLUBS_TWO;

  pokerWinnerGetForPlayer(&poker, player, &winning);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_FULL_HOUSE, winning.type);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_TWO, winning.set[0]);
  TEST_ASSERT_EQUAL_UINT8(CARD_DIAMONDS_TWO, winning.set[1]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_ACE, winning.set[2]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_ACE, winning.set[3]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_TWO, winning.set[4]);
}

void test_pokerWinnerGetForPlayer_should_CalculateFourOfAKind(void) {
  poker_t poker;
  uint8_t i;
  pokerplayer_t *player;
  pokerplayerwinning_t winning;

  pokerInit(&poker);
  i = pokerPlayerAdd(&poker);
  player = poker.players + i;

  poker.communitySize = 5;
  poker.community[0] = CARD_HEARTS_TWO;
  poker.community[1] = CARD_DIAMONDS_TWO;
  poker.community[2] = CARD_SPADES_TWO;
  poker.community[3] = CARD_SPADES_QUEEN;
  poker.community[4] = CARD_SPADES_ACE;
  player->cardCount = 2;
  player->cards[0] = CARD_CLUBS_TWO;
  player->cards[1] = CARD_SPADES_KING;

  pokerWinnerGetForPlayer(&poker, player, &winning);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_FOUR_OF_A_KIND, winning.type);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_TWO, winning.set[0]);
  TEST_ASSERT_EQUAL_UINT8(CARD_DIAMONDS_TWO, winning.set[1]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_TWO, winning.set[2]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_ACE, winning.set[3]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_TWO, winning.set[4]);
}

void test_pokerWinnerGetForPlayer_should_CalculateStraightFlush(void) {
  poker_t poker;
  uint8_t i;
  pokerplayer_t *player;
  pokerplayerwinning_t winning;

  pokerInit(&poker);
  i = pokerPlayerAdd(&poker);
  player = poker.players + i;

  poker.communitySize = 5;
  poker.community[0] = CARD_DIAMONDS_ACE;
  poker.community[1] = CARD_HEARTS_SIX;
  poker.community[2] = CARD_HEARTS_THREE;
  poker.community[3] = CARD_SPADES_QUEEN;
  poker.community[4] = CARD_HEARTS_FOUR;
  player->cardCount = 2;
  player->cards[0] = CARD_HEARTS_TWO;
  player->cards[1] = CARD_HEARTS_FIVE;

  pokerWinnerGetForPlayer(&poker, player, &winning);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_STRAIGHT_FLUSH, winning.type);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_SIX, winning.set[0]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_FIVE, winning.set[1]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_FOUR, winning.set[2]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_THREE, winning.set[3]);
  TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_TWO, winning.set[4]);
}

void test_pokerWinnerGetForPlayer_should_CalculateRoyalFlush(void) {
  poker_t poker;
  uint8_t i;
  pokerplayer_t *player;
  pokerplayerwinning_t winning;

  pokerInit(&poker);
  i = pokerPlayerAdd(&poker);
  player = poker.players + i;

  poker.communitySize = 5;
  poker.community[0] = CARD_DIAMONDS_ACE;
  poker.community[1] = CARD_HEARTS_SIX;
  poker.community[2] = CARD_SPADES_TEN;
  poker.community[3] = CARD_SPADES_QUEEN;
  poker.community[4] = CARD_SPADES_JACK;
  player->cardCount = 2;
  player->cards[0] = CARD_SPADES_KING;
  player->cards[1] = CARD_SPADES_ACE;

  pokerWinnerGetForPlayer(&poker, player, &winning);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_ROYAL_FLUSH, winning.type);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_ACE, winning.set[0]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_KING, winning.set[1]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_QUEEN, winning.set[2]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_JACK, winning.set[3]);
  TEST_ASSERT_EQUAL_UINT8(CARD_SPADES_TEN, winning.set[4]);
}

void test_pokerWinnerCompare_should_CompareWinningHands(void) {
  poker_t poker;
  uint8_t p0i, p1i;
  pokerplayer_t *p0;
  pokerplayer_t *p1;
  pokerplayerwinning_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 = 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 = 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 = pokerWinnerCompare(&w0, &w1);
  TEST_ASSERT_EQUAL_UINT8(0xFF, kicker);
}

void test_pokerWinnerDetermine_should_DecideTheWinnerCorrectly(void) {
  poker_t poker;
  uint8_t p0i, p1i, p2i;
  pokerplayer_t *p0;
  pokerplayer_t *p1;
  pokerplayer_t *p2;

  // Outputs
  uint8_t winnerCount, participantCount;
  uint8_t winnerPlayers[POKER_PLAYER_COUNT_MAX];
  uint8_t participants[POKER_PLAYER_COUNT_MAX];
  pokerplayerwinning_t winners[POKER_PLAYER_COUNT_MAX];

  // Set up the players
  pokerInit(&poker);
  p0i = pokerPlayerAdd(&poker);
  p1i = pokerPlayerAdd(&poker);
  p2i = pokerPlayerAdd(&poker);
  
  p0 = poker.players + p0i;
  p1 = poker.players + p1i;
  p2 = poker.players + p2i;
  
  pokerPotAddPlayer(poker.pots + 0, p0i);
  pokerPotAddPlayer(poker.pots + 0, p1i);
  pokerPotAddPlayer(poker.pots + 0, p2i);

  pokerPlayerChipsAdd(p0, 10000);
  pokerPlayerChipsAdd(p1, 10000);
  pokerPlayerChipsAdd(p2, 10000);

  // Set up the community
  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_DIAMONDS_SIX;
  poker.community[4] = CARD_HEARTS_EIGHT;

  // Set up the player hands
  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

  p2->state |= POKER_PLAYER_STATE_FOLDED;// Start folded
  p2->cardCount = 2;
  p2->cards[0] = CARD_DIAMONDS_TWO;
  p2->cards[1] = CARD_DIAMONDS_KING;

  // Run first test.
  pokerWinnerDetermineForPot(
    &poker, poker.pots + 0,
    winners, winnerPlayers, &winnerCount,
    participants, &participantCount
  );

  TEST_ASSERT_EQUAL_UINT8(1, winnerCount);
  TEST_ASSERT_EQUAL_UINT8(2, participantCount);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_PAIR, winners[0].type);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_PAIR, winners[1].type);
  TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_KING, winners[0].kicker);
  TEST_ASSERT_EQUAL_UINT8(0, winnerPlayers[0]);
  TEST_ASSERT_EQUAL_UINT8(0, participants[0]);
  TEST_ASSERT_EQUAL_UINT8(1, participants[1]);

  // ----- //
  // Test a difference in hands.
  p1->cards[1] = CARD_CLUBS_NINE;// Makes p1 have two pair.
  pokerWinnerDetermineForPot(
    &poker, poker.pots + 0,
    winners, winnerPlayers, &winnerCount,
    participants, &participantCount
  );
  TEST_ASSERT_EQUAL_UINT8(1, winnerCount);
  TEST_ASSERT_EQUAL_UINT8(2, participantCount);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_PAIR, winners[0].type);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_TWO_PAIR, winners[1].type);
  TEST_ASSERT_EQUAL_UINT8(1, winnerPlayers[0]);
  TEST_ASSERT_EQUAL_UINT8(0, participants[0]);
  TEST_ASSERT_EQUAL_UINT8(1, participants[1]);

  // Unfold p2
  p2->state = flagOff(p2->state, POKER_PLAYER_STATE_FOLDED);
  pokerWinnerDetermineForPot(
    &poker, poker.pots + 0,
    winners, winnerPlayers, &winnerCount,
    participants, &participantCount
  );
  TEST_ASSERT_EQUAL_UINT8(1, winnerCount);
  TEST_ASSERT_EQUAL_UINT8(3, participantCount);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_PAIR, winners[0].type);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_TWO_PAIR, winners[1].type);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_FLUSH, winners[2].type);
  TEST_ASSERT_EQUAL_UINT8(2, winnerPlayers[0]);
  TEST_ASSERT_EQUAL_UINT8(0, participants[0]);
  TEST_ASSERT_EQUAL_UINT8(1, participants[1]);
  TEST_ASSERT_EQUAL_UINT8(2, participants[2]);

  // Create a new pot that P2 isn't participating in.
  pokerPotAdd(&poker);
  pokerPotAddPlayer(poker.pots + 1, p0i);
  pokerPotAddPlayer(poker.pots + 1, p1i);
  pokerWinnerDetermineForPot(
    &poker, poker.pots + 1,
    winners, winnerPlayers, &winnerCount,
    participants, &participantCount
  );
  TEST_ASSERT_EQUAL_UINT8(1, winnerCount);
  TEST_ASSERT_EQUAL_UINT8(2, participantCount);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_PAIR, winners[0].type);
  TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_TWO_PAIR, winners[1].type);
  TEST_ASSERT_EQUAL_UINT8(1, winnerPlayers[0]);
  TEST_ASSERT_EQUAL_UINT8(0, participants[0]);
  TEST_ASSERT_EQUAL_UINT8(1, participants[1]);
}

int test_winner_h() {
  UNITY_BEGIN();
  
  RUN_TEST(test_pokerWinnerFillRemaining_should_FillTheRestOfTheArray);
  RUN_TEST(test_pokerWinnerGetForPlayer_should_CalculateHighCard);
  RUN_TEST(test_pokerWinnerGetForPlayer_should_CalculatePair);
  RUN_TEST(test_pokerWinnerGetForPlayer_should_CalculateTwoPair);
  RUN_TEST(test_pokerWinnerGetForPlayer_should_CalculateThreeOfAKind);
  RUN_TEST(test_pokerWinnerGetForPlayer_should_CalculateAStraight);
  RUN_TEST(test_pokerWinnerGetForPlayer_should_CalculateAFlush);
  RUN_TEST(test_pokerWinnerGet_should_CalculateFullHouse);
  RUN_TEST(test_pokerWinnerGetForPlayer_should_CalculateFourOfAKind);
  RUN_TEST(test_pokerWinnerGetForPlayer_should_CalculateStraightFlush);
  RUN_TEST(test_pokerWinnerGetForPlayer_should_CalculateRoyalFlush);
  RUN_TEST(test_pokerWinnerCompare_should_CompareWinningHands);
  RUN_TEST(test_pokerWinnerDetermine_should_DecideTheWinnerCorrectly);

  return UNITY_END();
}