## 10315 - Poker Hands

Moderator: Board moderators

mohdali231993
New poster
Posts: 11
Joined: Sun Nov 09, 2014 6:46 pm

### Re: 10315 - Poker Hands

help me out guys
i've checked all samples but still wrong answer from the judge

brianfry713
Guru
Posts: 5947
Joined: Thu Sep 01, 2011 9:09 am
Location: San Jose, CA, USA

### Re: 10315 - Poker Hands

Try input:
3D 3H 4D 4H 2S 5C 5S AH KD QC

Output should be
Black wins.
Check input and AC output for thousands of problems on uDebug!

agrskk2
New poster
Posts: 2
Joined: Mon Apr 27, 2015 3:13 pm

### Re: 10315 - Poker Hands

Hello,

my solution is passing all the cases that ar posted in this thread and I checked with my own cases that were made for each cobination I could think of, but still getting WA.

Could somone provide some tricky test cases or any other clues?

Thanks.

agrskk2
New poster
Posts: 2
Joined: Mon Apr 27, 2015 3:13 pm

### Re: 10315 - Poker Hands

Here is the code.

Code: Select all

/*
* UVa Online Judge
* 10315 - Poker Hands
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

typedef enum {
BLACK = 0,
WHITE = 1,
PLAYER_COUNT,
TIE,
} player;

typedef enum {
HIGH_CARD, PAIR, TWO_PAIRS, THREE_OF_A_KIND,
STRAIGHT, FLUSH, FULL_HOUSE, FOUR_OF_A_KIND,
STRAIGHT_FLUSH,
} hand;

typedef enum {
CARD_2  = 2,  CARD_3 = 3,  CARD_4 = 4,  CARD_5 = 5,
CARD_6  = 6,  CARD_7 = 7,  CARD_8 = 8,  CARD_9 = 9,
CARD_10 = 10, CARD_J = 11, CARD_Q = 12, CARD_K = 13,
CARD_A  = 14
} card_value;

unsigned int sym_to_num[] = {
['2'] = CARD_2,  ['3'] = CARD_3, ['4'] = CARD_4, ['5'] = CARD_5,
['6'] = CARD_6,  ['7'] = CARD_7, ['8'] = CARD_8, ['9'] = CARD_9,
['T'] = CARD_10, ['J'] = CARD_J, ['Q'] = CARD_Q, ['K'] = CARD_K,
['A'] = CARD_A,
};

#define CARDS_PLAYER 5
#define SYM_PER_CARD 3

#define VALUE_NDX    0
#define SUIT_NDX     1

#define MAX_POSSIBLE_PAIRS 2

struct poker_hand {
char cards[CARDS_PLAYER * SYM_PER_CARD];
bool seen[CARDS_PLAYER];

size_t pairs;
char pair_values[MAX_POSSIBLE_PAIRS];

size_t same_cnt;
char same_value;
};

/* ----------- DEBUG -------------- */

void print_hand(struct poker_hand *h)
{
printf("Cards: ");
size_t i, j;
for (i = 0; i < CARDS_PLAYER; ++i) {
char *card = h->cards + (i * SYM_PER_CARD);
if (h->seen[i]) printf("[%s] ", card);
else printf("%s ", card);
}
printf("\n---\n");
printf("Pairs: %ld", h->pairs);
if (h->pairs > 0) {
printf("  ");
for (j = 0; j < h->pairs; ++j)
printf("[%c] ", h->pair_values[j]);
}
printf("\nSame: %ld", h->same_cnt);
if (h->same_cnt > 0) {
printf(" [%c]", h->same_value);
}
printf("\n");
}

void print_players(struct poker_hand *players)
{
printf("---------------------------------------\n");
printf("   -= BLACK =-   \n");
print_hand(&players[BLACK]);
printf("\n   -= WHITE =-  \n");
print_hand(&players[WHITE]);
printf("---------------------------------------\n");
}

void print_hands(char cards[2][5][3])
{
printf("--- Black ---     --- White ---\n");
size_t i, j;
for (i = 0; i < PLAYER_COUNT; ++i) {
for (j = 0; j < CARDS_PLAYER; ++j) {
printf("%s ", cards[i][j]);
}
printf("  ");
}
printf("\n");
}
/* ----------- END OF DEBUG -------------- */

int compare_ints(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}

bool get_is_straight(struct poker_hand *player_hand)
{
size_t matches = 0;
unsigned int next_card = sym_to_num[player_hand->cards[VALUE_NDX]];

size_t i;
for (i = 0; i < CARDS_PLAYER; ++i) {
if (next_card > CARD_A) break;
if (next_card++ !=
sym_to_num[(player_hand->cards + i * SYM_PER_CARD)[VALUE_NDX]]) break;
++matches;
}

return (matches == CARDS_PLAYER);
}

bool get_is_flush(struct poker_hand *player_hand)
{
size_t same_suit = 1;
char suit = player_hand->cards[SUIT_NDX];

size_t i;
for (i = 1; i < CARDS_PLAYER; ++i) {
if ((player_hand->cards + (i * SYM_PER_CARD))[SUIT_NDX] == suit) ++same_suit;
}

return (same_suit == CARDS_PLAYER);
}

int compare_cards(const void *a, const void *b)
{
char *card_a = (char *)a;
char *card_b = (char *)b;

return sym_to_num[card_a[0]] - sym_to_num[card_b[0]];
}

void count_same(struct poker_hand *player_hand)
{
bool same_locations[CARDS_PLAYER];

size_t i, j, k;
for (i = 0; i < CARDS_PLAYER; ++i) {
if (player_hand->seen[i]) continue;
memset(same_locations, 0, sizeof(bool) * CARDS_PLAYER);

char current_card = (player_hand->cards + i * SYM_PER_CARD)[VALUE_NDX];
same_locations[i] = true;
size_t same_cnt = 1;

/* the actual counting */
for (j = 0; j < CARDS_PLAYER; ++j) {
if (player_hand->seen[i] || i == j) continue;
if (current_card == (player_hand->cards + j * SYM_PER_CARD)[VALUE_NDX]) {
same_locations[j] = true;
++same_cnt;
}
}

/* assign counts */
if (same_cnt >= 2) {
for (k = 0; k < CARDS_PLAYER; ++k) {
if ( !player_hand->seen[k]) {
player_hand->seen[k] = same_locations[k];
}
}

if (same_cnt > 2 && same_cnt > player_hand->same_cnt) {
player_hand->same_cnt = same_cnt;
player_hand->same_value = current_card;
}
else if (same_cnt == 2) {
player_hand->pair_values[player_hand->pairs++] = current_card;
}
}
}
}

hand player_hand_rank(struct poker_hand *player_hand)
{
qsort(player_hand->cards, CARDS_PLAYER,
sizeof(char) * SYM_PER_CARD,
compare_cards);

count_same(player_hand);
bool is_straight = get_is_straight(player_hand);
bool is_flush    = get_is_flush(player_hand);

if (is_straight && is_flush)
return STRAIGHT_FLUSH;

if (player_hand->same_cnt == 4)
return FOUR_OF_A_KIND;

if (player_hand->same_cnt == 3 && player_hand->pairs == 1)
return FULL_HOUSE;

if (is_flush)
return FLUSH;

if (is_straight)
return STRAIGHT;

if (player_hand->same_cnt == 3 && player_hand->pairs == 0)
return THREE_OF_A_KIND;

if (player_hand->pairs == 2)
return TWO_PAIRS;

if (player_hand->pairs == 1)
return PAIR;

return HIGH_CARD;
}

player player_high_card(struct poker_hand *player_hands)
{
struct poker_hand *white = &player_hands[WHITE];
struct poker_hand *black = &player_hands[BLACK];

size_t white_ndx = CARDS_PLAYER - 1;
unsigned int white_card =
sym_to_num[(white->cards + (white_ndx-- * SYM_PER_CARD))[VALUE_NDX]];
player winner = TIE;

int i;
for (i = CARDS_PLAYER - 1; i >= 0; --i) {
unsigned int black_card =
sym_to_num[(black->cards + (i * SYM_PER_CARD))[VALUE_NDX]];

if (white_card != black_card) {
if      (white_card < black_card) winner = BLACK;
else if (white_card > black_card) winner = WHITE;
break;
}
else {
white_card =
sym_to_num[(white->cards + (white_ndx * SYM_PER_CARD))[VALUE_NDX]];
i = 1 + white_ndx--;
}
}

return winner;
}

unsigned int next_unseen(struct poker_hand *player_hand)
{
unsigned int next_card = 0;

int i;
for (i = CARDS_PLAYER - 1; i >= 0; --i) {
if ( !player_hand->seen[i]) {
next_card = sym_to_num[(player_hand->cards + (i * SYM_PER_CARD))[VALUE_NDX]];
player_hand->seen[i] = true;
break;
}
}

return next_card;
}

player player_pair(struct poker_hand *player_hands)
{
struct poker_hand *white = &player_hands[WHITE];
struct poker_hand *black = &player_hands[BLACK];

/* get value of pair symbol for the pair */
unsigned int white_card = sym_to_num[white->pair_values[0]];
unsigned int black_card = sym_to_num[black->pair_values[0]];

player winner = TIE;

if (black_card == white_card) {
int i;
for (i = CARDS_PLAYER - 1; i >= 0; --i) {
black_card = next_unseen(black);
white_card = next_unseen(white);

if (white_card != black_card) {
if      (white_card < black_card) winner = BLACK;
else if (white_card > black_card) winner = WHITE;
break;
}
}
}
else if (black_card > white_card) winner = BLACK;
else winner = WHITE;

return winner;
}

player _player_2pairs_2equal(struct poker_hand *white,
struct poker_hand *black)
{
unsigned int black_card = next_unseen(black);
unsigned int white_card = next_unseen(white);

if      (white_card < black_card) return BLACK;
else if (white_card > black_card) return WHITE;
else 							  return TIE;
}

player _player_2pairs_1equal(struct poker_hand *white,
unsigned int white_cards[],
struct poker_hand *black,
unsigned int black_cards[])
{
/* get the MAX indices */
size_t white_ndx = (white_cards[0] > white_cards[1]) ? 0 : 1;
size_t black_ndx = (black_cards[0] > black_cards[1]) ? 0 : 1;
player winner = TIE;

if (white_cards[white_ndx] > black_cards[black_ndx]) {
winner = WHITE;
}
else if (white_cards[white_ndx] < black_cards[black_ndx]) {
winner = BLACK;
}
else if (white_cards[white_ndx] == black_cards[black_ndx]) {
/* get the other pair (the MIN indices), by flipping MAX */
white_ndx = (white_ndx + 1) % 2;
black_ndx = (black_ndx + 1) % 2;
if (white_cards[white_ndx] == black_cards[black_ndx]) {
white_cards[0] = next_unseen(black);
black_cards[0] = next_unseen(white);

if (white_cards[0] != black_cards[0]) {
if      (white_cards[0] < black_cards[0]) winner = BLACK;
else if (white_cards[0] > black_cards[0]) winner = WHITE;
}
}
else if (white_cards[white_ndx] > black_cards[black_ndx])
winner = WHITE;
else if (white_cards[white_ndx] < black_cards[black_ndx])
winner = BLACK;
}

return winner;
}

player player_2pairs(struct poker_hand *player_hands)
{
struct poker_hand *white = &player_hands[WHITE];
struct poker_hand *black = &player_hands[BLACK];

/* get value of pair symbol for the pair */
unsigned int white_cards[] = {
sym_to_num[white->pair_values[0]],
sym_to_num[white->pair_values[1]],
};
unsigned int black_cards[] = {
sym_to_num[black->pair_values[0]],
sym_to_num[black->pair_values[1]],
};

player winner = TIE;

/* both pairs are equal, e.g. KK,QQ and QQ,KK, check the remaining
* card for high value */
if ((white_cards[0] == black_cards[0] && white_cards[1] == black_cards[1])
|| (white_cards[0] == black_cards[1] && white_cards[1] == black_cards[0])) {
/* check the remaining card */
winner = _player_2pairs_2equal(white, black);
}
/* one pair is equal and the other differs */
else if (   (white_cards[0] == black_cards[0] && white_cards[1] != black_cards[1])
|| (white_cards[0] == black_cards[1] && white_cards[1] != black_cards[0])
|| (white_cards[1] == black_cards[0] && white_cards[0] != black_cards[1])
|| (white_cards[1] == black_cards[1] && white_cards[0] != black_cards[0])) {
winner = _player_2pairs_1equal(white, white_cards, black, black_cards);
}
/* both have 2 pairs which are different from each other */
else {
size_t white_ndx = (white_cards[0] > white_cards[1]) ? 0 : 1;
size_t black_ndx = (black_cards[0] > black_cards[1]) ? 0 : 1;

/* compare the largest pairs from both */
if      (white_cards[white_ndx] < black_cards[black_ndx]) winner = BLACK;
else if (white_cards[white_ndx] > black_cards[black_ndx]) winner = WHITE;
}

return winner;
}

player player_3kind(struct poker_hand *player_hands)
{
struct poker_hand *white = &player_hands[WHITE];
struct poker_hand *black = &player_hands[BLACK];

unsigned int white_card = sym_to_num[white->same_value];
unsigned int black_card = sym_to_num[black->same_value];

if      (white_card < black_card) return BLACK;
else if (white_card > black_card) return WHITE;
else {
do {
black_card = next_unseen(black);
white_card = next_unseen(white);
} while (black_card == white_card && (black_card != 0 || white_card != 0));

if      (white_card < black_card) return BLACK;
else if (white_card > black_card) return WHITE;

return TIE;
}
}

player player_straight(struct poker_hand *player_hands)
{
struct poker_hand *white = &player_hands[WHITE];
struct poker_hand *black = &player_hands[BLACK];

unsigned int white_card = sym_to_num[
(white->cards + (CARDS_PLAYER - 1) * SYM_PER_CARD)[VALUE_NDX]];
unsigned int black_card = sym_to_num[
(black->cards + (CARDS_PLAYER - 1) * SYM_PER_CARD)[VALUE_NDX]];

if      (white_card < black_card) return BLACK;
else if (white_card > black_card) return WHITE;
else 							  return TIE;
}

player player_flush(struct poker_hand *player_hands)
{
return player_high_card(player_hands);
}

player player_full_house(struct poker_hand *player_hands)
{
struct poker_hand *white = &player_hands[WHITE];
struct poker_hand *black = &player_hands[BLACK];

player winner = player_3kind(player_hands);
if (winner == TIE) {
/* check for pair ranks if 3ees match */
unsigned int white_card = (white->pairs == 1) ?
sym_to_num[white->pair_values[0]] : 0;
unsigned int black_card = (black->pairs == 1) ?
sym_to_num[black->pair_values[0]] : 0;

if      (white_card < black_card) winner = BLACK;
else if (white_card > black_card) winner = WHITE;
}
return winner;
}

player player_4kind(struct poker_hand *player_hands)
{
return player_3kind(player_hands);
}

player player_straight_flush(struct poker_hand *player_hands)
{
return player_straight(player_hands);
}

void find_winner(struct poker_hand *player_hands)
{
hand black_hand = player_hand_rank(&player_hands[BLACK]);
hand white_hand = player_hand_rank(&player_hands[WHITE]);

player winner = TIE;
if (black_hand > white_hand)
winner = BLACK;
else if (black_hand < white_hand)
winner = WHITE;
else { /* black_hand == white_hand */
if (black_hand == STRAIGHT_FLUSH)
winner = player_straight_flush(player_hands);
else if (black_hand == FOUR_OF_A_KIND)
winner = player_4kind(player_hands);
else if (black_hand == FULL_HOUSE)
winner = player_full_house(player_hands);
else if (black_hand == FLUSH)
winner = player_flush(player_hands);
else if (black_hand == STRAIGHT)
winner = player_straight(player_hands);
else if (black_hand == THREE_OF_A_KIND)
winner = player_3kind(player_hands);
else if (black_hand == TWO_PAIRS)
winner = player_2pairs(player_hands);
else if	(black_hand == PAIR)
winner = player_pair(player_hands);
else if (black_hand == HIGH_CARD)
winner = player_high_card(player_hands);
}

if      (winner == BLACK) printf("Black wins.\n");
else if (winner == WHITE) printf("White wins.\n");
else if (winner == TIE)   printf("Tie.\n");
}

int main(int argc, const char **argv)
{
(void)argc;
(void)argv;
int status;
size_t i, j;

struct poker_hand player_hands[PLAYER_COUNT];

while ( !feof(stdin)) {
memset(player_hands, 0, sizeof(player_hands));
for (i = 0; i < PLAYER_COUNT; ++i) {
for (j = 0; j < CARDS_PLAYER; ++j) {
status = scanf(" %2s", player_hands[i].cards + (j * SYM_PER_CARD));
}
}
status = scanf("\n");
find_winner(player_hands);
}

exit(EXIT_SUCCESS);
}
Wher's the problem, why I can't get AC?

Thanks