Thread: tying myself into tighter and tighter knots

1. tying myself into tighter and tighter knots

i have the following functions
Code:
```int score_hands(int num_players, Hand players[])
{
int i, score[num_players], highest_score = 0, same_score = 0, winner_index;

for (i = 0; i < num_players; i++)
{
score[i] = score_hand(players[i].cards);
players[i].hand_score = score[i];
if (score[i] > highest_score)
{
highest_score = score[i];
winner_index = i;
}
}
same_score = duplicate_score(num_players, highest_score, score);
if (same_score > 1)
{
winner_index = evaluate_duplicate_hands(num_players, winner_index, same_score, highest_score, players);
}
return winner_index;
}

int score_hand(Card hand[])
{
/* score key
straight flush = 9
four of a kind = 8
full house = 7
flush = 6
straight = 5
three of a kind = 4
two pairs = 3
pair = 2
high card = 1
*/
int score;

if (same_suit(hand))
{
if (cards_assending_value(hand))
{
score = STRAIGHT_FLUSH;
}
else
{
score = FLUSH;
}
}
else if (cards_assending_value(hand))
{
score = STRAIGHT;
}
else
{
switch (check_groups(hand))
{
case FOUR_OF_A_KIND:
score = FOUR_OF_A_KIND;
break;
case FULL_HOUSE:
score = FULL_HOUSE;
break;
case THREE_OF_A_KIND:
score = THREE_OF_A_KIND;
break;
case TWO_PAIRS:
score = TWO_PAIRS;
break;
case PAIR:
score = PAIR;
break;
case HIGH_CARD:
score = HIGH_CARD;
break;
default:
printf("error occured scoring cards");
}
}
return score;
}

int same_suit(Card *p_cards)
{
int i;

for (i = 0; i < 4; i++)
{
if (p_cards[i].suit != p_cards[i + 1].suit)
{
return 0;
}
}
return 1;
}

int cards_assending_value(Card *p_cards)
{
int i;

for (i = 0; i < 4; i++)
{
if (p_cards[i].value + 1 != p_cards[i + 1].value)
{
return 0;
}
}
return 1;
}

int check_groups(Card *p_hand)
{
int i, j, largest_group, groups[15] = {0};

for (j = 0; j < 5; j++)
{
for (i = TWO; i < ACE + 1; i++)
{
if (i == p_hand[j].value)
{
groups[i] += 1;
}
}
}
largest_group = count_groups(groups);
if (largest_group == 4)
{
return FOUR_OF_A_KIND;//four of a kind
}
if (largest_group == 3)
{
if (check_for_pair(groups))
{
return FULL_HOUSE;//full house
}
else
{
return THREE_OF_A_KIND;//three of a kind
}
}
if (largest_group == 2)
{
if (check_for_pair(groups) == 2)
{
return TWO_PAIRS;// 2 pair
}
else
{
return PAIR;//single pair
}
}
return SINGLE_CARD;// high card
}

int count_groups(int groups[])
{
int i, largest = 0;

for (i = TWO; i < ACE + 1; i++)
{
if (largest < groups[i])
{
largest = groups[i];
}
}
return largest;
}

int check_for_pair(int groups[])
{
int i, pair_count = 0;

for (i = TWO; i < ACE; i++)
{
if (groups[i] == 2)
{
pair_count += 1;
}
}
return pair_count;
}

int check_highcard(int same_score, Hand temp_hands[])
{
int i, highest_card = 1, winners_index = 0, suit = 4;

for (i = 0; i < same_score; i++)
{
if (temp_hands[i].cards[4].value > highest_card)
{
highest_card = temp_hands[i].cards[4].value;
suit = temp_hands[i].cards[4].suit;
winners_index = i;

}
if ((temp_hands[i].cards[4].value == highest_card) && (temp_hands[i].cards[0].suit < suit))
{
suit = temp_hands[i].cards[0].suit;
winners_index = i;
}
}
return winners_index;
}
int check_fourkind(int same_score, Hand temp_hands[])
{
int i, highest_card_in_group = 1, highest_single_card = TWO, suit = 4, single_suit = 4, winner_index;

for (i = 0; i < same_score; i++)
{
if (temp_hands[i].cards[2].value > highest_card_in_group)
{
highest_card_in_group = temp_hands[i].cards[2].value;
suit = temp_hands[i].cards[2].suit;
winner_index = i;
}
if ((temp_hands[i].cards[2].value == highest_card_in_group) && (temp_hands[i].cards[2].suit < suit))
{
suit = temp_hands[i].cards[2].suit;
winner_index = i;
}
if (temp_hands[i].cards[2].value == highest_card_in_group && temp_hands[i].cards[2].suit == suit)
{
if (temp_hands[i].cards[2].value == temp_hands[i].cards[4].value)
{
if (temp_hands[i].cards[0].value > highest_single_card && temp_hands[i].cards[0].suit < single_suit)
{
highest_single_card = temp_hands[i].cards[0].value;
single_suit = temp_hands[i].cards[0].suit;
winner_index = i;
}
}
else
{
if (temp_hands[i].cards[4].value > highest_single_card && temp_hands[i].cards[4].suit < single_suit)
{
highest_single_card = temp_hands[i].cards[4].value;
single_suit = temp_hands[i].cards[4].suit;
winner_index = i;
}
}
}
}
return winner_index;
}
void swap_cards_in_hand(Hand temp_hand)
{
Card temp1, temp2;

temp1 = temp_hand.cards[0];
temp2 = temp_hand.cards[1];
temp_hand.cards[0] = temp_hand.cards[3];
temp_hand.cards[1] = temp_hand.cards[4];
temp_hand.cards[3] = temp1;
temp_hand.cards[4] = temp2;
}

int check_fullhouse(int same_score, Hand temp_hands[])
{
int i, highest_threekind = 1, highest_pair = 1, winner_index;

for (i = 0; i < same_score; i++)
{
if (temp_hands[i].cards[2].value == temp_hands[i].cards[4].value)
{
swap_cards_in_hand(temp_hands[i]);
}
if (temp_hands[i].cards[2].value > highest_threekind && temp_hands[i].cards[3].value > highest_pair)
{
highest_threekind = temp_hands[i].cards[2].value;
highest_pair = temp_hands[i].cards[3].value;
winner_index = i;
}
}
return winner_index;
}
int check_flush(int same_score, Hand temp_hands[])
{
return 0;
}
int check_straight(int same_score, Hand temp_hands[])
{
return 0;
}
int check_threekind(int same_score, Hand temp_hands[])
{
return 0;
}
int check_twopair(int same_score, Hand temp_hands[])
{
return 0;
}
int check_pair(int same_score, Hand temp_hands[])
{
return 0;
}

int duplicate_score(int num_players, int highest_score, int scores[])
{
int i, duplicate_found = 0;

for (i = 0; i < num_players; i++)
{
if (scores[i] == highest_score)
{
duplicate_found += 1;
}
}
return duplicate_found;
}

int evaluate_duplicate_hands(int num_players,int winner_index, int same_score, int highest_score, Hand players[])
{
int i, j, winner, duplicates = 0;
Hand temp_hands[same_score];

for (i = winner_index; i < num_players; i++)
{
if (players[i].hand_score == highest_score)
{
for (j = 0; j < FULL_HAND; j++)
{
temp_hands[duplicates].cards[j] = players[i].cards[j];
}
duplicates++;
}
}

winner = winner_index + duplicate_hands(same_score, highest_score, temp_hands, players);
return winner;
}

int duplicate_hands(int same_score, int highest_score, Hand temp_hands[], Hand players[])
{
int winner;

switch (highest_score)
{
case STRAIGHT_FLUSH: case SINGLE_CARD:
winner = check_highcard(same_score, temp_hands);
break;
case FOUR_OF_A_KIND:
winner = check_fourkind(same_score, temp_hands);
break;
case FULL_HOUSE:
winner = check_fullhouse(same_score, temp_hands);
break;
case FLUSH:
winner = check_flush(same_score, temp_hands);
break;
case STRAIGHT:
winner = check_straight(same_score, temp_hands);
break;
case THREE_OF_A_KIND:
winner = check_threekind(same_score, temp_hands);
break;
case TWO_PAIRS:
winner = check_twopair(same_score, temp_hands);
break;
case PAIR:
winner = check_pair(same_score, temp_hands);
break;
}
return winner;
}```
if there is a clear winner ie there is only one player with the highest score all is well . however if there isn't i seem to be tying myself into tighter and tighter knots trying to evaluate each hand.

any suggestions welcome
coop

2. extra notes.:
the reason four of a kind cares about suit is in case there is more than one deck needed.
alot of the function definitions have yet to be coded.
coop

Instead of accounting for each individual hand to see what beats what, try to implement a system wherein each card has a value. The strength of a hand could be the sum of the points of each card. Then a single generic function can determine the strength of any hand without having to write special cases for each one. Deciding the winner then becomes a problem of linear complexity, scaling according to the number of players alone, instead of the number of players and the multiple variety of hands each can have.

Note that I don’t know the slightest things about card games, and I barely took a half glance at your code, so take my \$0.02 with a grain of salt.

4. Originally Posted by Dren
Note that I don’t know the slightest things about card games
You should learn a few. They are fun.

5. i did try to score the cards with bonus's for each type of hand ie pair two pair straight etc etc, issue was that just to get from the best possible score of the hand rank below to the worst possible case of the rank above i ended up with numbers in the 10's of billions.

also the other issue i had was suppose a player had a pair of threes with a 2 4 and 5 as "junk" cards clearly this should beat a pair of 2's with j q k as "junk" cards. i did try to impliment this with such bonus's that were big enough to over come the issue but ran out of numbers by the time i got to a straight flush

hence i have gone down the route of trying to evaluate two hands if they score the same,

many thanks
coop