Sunday, August 07, 2005

poker

#include
#include
#include

#ifdef __TURBOC__
#include
#include
#else
#include
#endif

#include
#include
#include

void clrscr(void);


#define JOKERCARD 52 /* joker */
typedef enum { FALSE, TRUE } boolean;

typedef enum { NO_PATTERN, PAIR, FLUSH, STRAIGHT, PAIR_FLUSH, STRAIGHT_FLUSH, TRIO } rank;
char *rank_rep[] = { "No Pattern", "Pair!", "Flush!", "Straight!", "Pair Flush!", "Straight Flush!", "Trio!"};
typedef enum { FLOWER, SPADE, HEART, DIAMOND, JOKER } suit;
#define SUIT_TYPES 5
/* char suit_ascii[] = { 5, 6, 3, 4 }; */

char suit_ascii[] = { 'f', 's', 'h', 'd' };

/* card value representation */
char *face_ascii[] = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "jack", "queen", "king"};


#define MAX_CARDS 53
/* last card(52) represents joker */
boolean cards_taken_A[MAX_CARDS];
boolean cards_taken_B[MAX_CARDS];
#define CARD_ON_HAND 3

#define CARD_GROUP 13
int c_A[CARD_ON_HAND]; /* value from 0 to 53 */
int c_B[CARD_ON_HAND];

/* oc original card layout */
int oc_A[CARD_ON_HAND]; /* value from 0 to 53 */
int oc_B[CARD_ON_HAND];
int b_A; /* bet */
int b_B;
rank r_A; /* rank */
rank r_B;

int m_A; /* money */
int m_B;

#ifndef __TURBOC__
void randomize()
{
srand((unsigned int)time(NULL));
}
#endif
#ifndef __TURBOC__
void clrscr(void)
{
printf("\033[2J"); /* Clear the entire screen. */
printf("\033[0;0f"); /* Move cursor to the top left hand corner */
}
#endif

int random_span(int span)
{
return rand() % span;
}

void card_initialize()
{
int i;
for( i = 0; i < MAX_CARDS; i++ )
{
cards_taken_A[i] = FALSE;
cards_taken_B[i] = FALSE;
}
}

int facesuit_to_card(int n, suit s)
{

/*
n - 1
note: C is zero based. Ace is zero, 2 is 1, 3 is 2, ...
*/

if ( n == -1 )
{
return JOKERCARD;
}
else
{
return (s * CARD_GROUP) + (n-1);
}
}

char *card_visualize(int card_index)
{
char *cvs; /* card visualize */
int card_number;
int card_suit;

/* 10 is ample enough for visualization of card */
cvs = (char *) malloc(50);


if( card_index == JOKERCARD )
{
strcpy(cvs,"joker");
return cvs;
}
else
{
card_suit = card_index / CARD_GROUP;
card_number = card_index % CARD_GROUP;
sprintf(cvs, "%s %c", face_ascii[card_number], suit_ascii[card_suit]);
return cvs;
}
}
int card_to_face(int c)
{
return c % CARD_GROUP;
}

int card_to_suit(int n)
{
return n / CARD_GROUP;
}

void card_visualize_first2()
{
printf("\n\nVisualize first 2 cards");
printf("\nPlayer A: %s %s", card_visualize(c_A[0]), card_visualize(c_A[1]));
printf("\nPlayer B: %s %s", card_visualize(c_B[0]), card_visualize(c_B[1]));
}

void card_visualize_last_card()
{
printf("\n\nVisualize unknown/surprise cards");
printf("\nPlayer A: %s ", card_visualize(c_A[2]));
printf("\nPlayer B: %s ", card_visualize(c_B[2]));
}

/*
player = { A, B }
with_joker = { FALSE, TRUE }
*/
int card_pick(char player, boolean with_joker)
{

boolean *card_is_taken;
int cp;

if ( player == 'A')
{
card_is_taken = cards_taken_A;
}
else if ( player == 'B' )
{
card_is_taken = cards_taken_B;
}


for(;;)
{
goPickAgain:
cp = random_span(MAX_CARDS);

if (!with_joker)
{
if ( cp == JOKERCARD )
{
goto goPickAgain;
}
}

/* skip jokers */
if ( card_is_taken[cp] )
{
continue;
}
else
{
card_is_taken[cp] = TRUE;
break;
}

}
return cp;
}

void player_promptbet()
{
printf("\n\nBet");
printf("\nPlayer A : ");
scanf("%d", &b_A);
printf("Player B : ");
scanf("%d", &b_B);
}

void card_visualize_all()
{

int sc_A; /* Player A current score */
int sc_B;
int difference;
char winner[80];

sc_A = m_A;
sc_B = m_B;
difference = abs(r_A - r_B);

if ( r_A == r_B )
{
strcpy(winner, "Tie");
}
else if ( r_A > r_B )
{
/* Player A wins */
m_A += b_A + (b_A * difference);
m_B -= b_B * difference;
strcpy(winner, "Player A wins");
}
else if ( r_B > r_A )
{
/* Player B wins */
m_B += b_B + (b_B * difference);
m_A -= b_A * difference;
strcpy(winner, "Player B wins");
}


printf("\n\nVisualize cards");
printf("\nPlayer A: %s %s %s", card_visualize(oc_A[0]), card_visualize(oc_A[1]), card_visualize(oc_A[2]) );

printf("\nRank: %d(%s); Current money: %d; Bet: %d; New Money: %d;", r_A, rank_rep[r_A], sc_A, b_A, m_A);

printf("\n");
printf("\nPlayer B: %s %s %s", card_visualize(oc_B[0]), card_visualize(oc_B[1]), card_visualize(oc_B[2]) );
printf("\nRank: %d(%s); Current money: %d; Bet: %d; New Money: %d;", r_B, rank_rep[r_B], sc_B, b_B, m_B);

printf("\n\nThis round: %s", winner);
}

int compare(const void *a, const void *b)
{
/* since card index is selection from index 1 to 54(52 + 2(joker)) */
/* we must convert the card index to card_number */

int a_n;
int b_n;
a_n = *((int *)a) % CARD_GROUP;
b_n = *((int *)b) % CARD_GROUP;
return ( a_n - b_n );
}

/*
input:
player = { A, B }
output:
rank of players:
r_A
r_A
*/
int card_on_hand_detect_rank(char player)
{

int suit_checker[CARD_GROUP];
int flush_checker[SUIT_TYPES];

boolean card_is_flush, card_is_straight, card_is_pair;
int rank;
int i;

int *card_to_detect;
if ( player == 'A' )
{
card_to_detect = c_A;
}
else if ( player == 'B' )
{
card_to_detect = c_B;
}

rank = 0;

card_is_flush = 0;
card_is_straight = 0;
card_is_pair = 0;
for (i = 0; i < CARD_GROUP; i++)
{
suit_checker[i] = 0;
}

for (i = 0; i < 6; i++)
{
flush_checker[i] = 0;
}


/* cards are already sorted, so we can immediately check straightness */
if (card_to_face(card_to_detect[0]) + 1 == card_to_face(card_to_detect[1]) &&
card_to_face(card_to_detect[1]) + 1 == card_to_face(card_to_detect[2]))
{
card_is_straight = TRUE;
rank = STRAIGHT;
}

/* suit checker... */
suit_checker[ card_to_face(card_to_detect[0]) ]++;
suit_checker[ card_to_face(card_to_detect[1]) ]++;
suit_checker[ card_to_face(card_to_detect[2]) ]++;

for(i = 0; i < CARD_GROUP; i++)
{
if (suit_checker[i] == 2)
{
card_is_pair = TRUE;
rank = PAIR;
break;
}
else if (suit_checker[i] == 3)
{
rank = TRIO;
break;
}
}

/* ...suit checker */

/* flush checker... */

flush_checker[ card_to_suit(card_to_detect[0]) ]++;
flush_checker[ card_to_suit(card_to_detect[1]) ]++;
flush_checker[ card_to_suit(card_to_detect[2]) ]++;

for (i = 0; i < SUIT_TYPES; i++ )
{
if (flush_checker[ i ] == 3)
{
rank = FLUSH;
card_is_flush = TRUE;
break;
}
}

/* ...flush checker */

if (card_is_pair && card_is_flush)
{
rank = PAIR_FLUSH;
}
if (card_is_straight && card_is_flush)
{
rank = STRAIGHT_FLUSH;
}

return rank;
}

void showchecker()
{
printf("\n\nRank: %d, combination type: %s", r_A, rank_rep[r_A]);
}

suit char_to_suit(char s)
{
switch(s)
{
case 'f':
return FLOWER;
case 's':
return SPADE;
case 'd':
return DIAMOND;
case 'h':
return HEART;
case 'j':
return JOKER;
}
}

/*
Input:
player = { A, B }
Output:
rank of first 2 cards of player:
r_A_first2
r_B_first2
*/
boolean face_is_consecutive(int f1, int f2)
{
int distance;
distance = abs(f1 - f2);
if ( distance == 1 || distance == 2 )
{
return TRUE;
}
else
{
return FALSE;
}
}

int detect_rank_first_2_cards(char player)
{
int rank;
int f1, f2;
suit s1, s2;
int *card_to_detect;
if ( player == 'A' )
{
card_to_detect = c_A;
}
else if ( player == 'B' )
{
card_to_detect = c_B;
}

f1 = card_to_face( card_to_detect[0] );
f2 = card_to_face( card_to_detect[1] );
s1 = card_to_suit( card_to_detect[0] );
s2 = card_to_suit( card_to_detect[1] );

if ( f1 == f2 )
{
rank = TRIO;
}
else if ( face_is_consecutive(f1,f2) && s1 == s2 )
{
rank = STRAIGHT_FLUSH;
}
else if ( f1 != f2 && s1 == s2 )
{
rank = PAIR_FLUSH;
}
else if ( face_is_consecutive(f1,f2) && s1 != s2 )
{
rank = STRAIGHT;
}
else if ( !face_is_consecutive(f1,f2) && s1 == s2 )
{
rank = FLUSH;
printf("*impossible*");
}
else if ( !face_is_consecutive(f1,f2) && s1 != s2 )
{
rank = PAIR;
}
else
{
/* not possible */
rank = NO_PATTERN;
printf("*impossible*");
}

return rank;
}

void card_distribute()
{
char ans;
char ch;
int c1n, c2n, c3n;
char c1s, c2s, c3s;
suit s1, s2, s3;
m_A = 50;
m_B = 50;

printf("\n\nWelcome poker\n");
printf("r)andom or c)hecker ? ");
ch = toupper(getchar());

if (ch == 'R')
{
m_A = 50;
m_B = 50;

do
{
clrscr();
card_initialize();

printf("\n\nPoker--------------------\n\n");



/* Player A first 2 cards */
c_A[0] = card_pick('A', FALSE);
c_A[1] = card_pick('A', FALSE);

/* Player B first 2 cards */
c_B[0] = card_pick('B', FALSE);
c_B[1] = card_pick('B', FALSE);
card_visualize_first2();

player_promptbet();

c_A[2] = card_pick('A', TRUE);
c_B[2] = card_pick('B', TRUE);


card_visualize_last_card();

memcpy(oc_A, c_A, sizeof(int) * 3);
memcpy(oc_B, c_B, sizeof(int) * 3);

/* player A detect */
if ( c_A[2] == JOKERCARD )
{
r_A = detect_rank_first_2_cards('A');
}
else
{
qsort (c_A, 3, sizeof(int), compare);
r_A = card_on_hand_detect_rank('A');
}

/* player B detect */
if ( c_B[2] == JOKERCARD )
{
r_B = detect_rank_first_2_cards('B');

}
else
{
qsort (c_B, 3, sizeof(int), compare);
r_B = card_on_hand_detect_rank('B');
}


card_visualize_all();
if ( m_A < 2 || m_B < 2 )
{
printf("\n\nGame over");
if ( m_A > m_B )
{
printf("\nPlayer A wins");
}
else if ( m_B > m_A )
{
printf("\nPlayer B wins");
}
else
{
printf("\nTie");
}
break;
}

printf("\n\nPlay Again?[Y/N] ");
/* flush the enter character from bet input */
/* or alternative use getchar() instead of flush */
/* fflush(stdin); */
getchar();
ans = toupper(getchar());

}
while(! ( ans == 'N' ) );

}
else
{
clrscr();

do
{
printf("\n\nEnter cards: ");

scanf("%d %c %d %c %d %c", &c1n, &c1s, &c2n, &c2s, &c3n, &c3s);

s1 = char_to_suit(c1s);
s2 = char_to_suit(c2s);
s3 = char_to_suit(c3s);
c_A[0] = facesuit_to_card(c1n, s1); /* card_pick(); */
c_A[1] = facesuit_to_card(c2n, s2); /* card_pick(); */
c_A[2] = facesuit_to_card(c3n, s3); /* card_pick(); */

if ( c_A[2] == JOKERCARD )
{
r_A = detect_rank_first_2_cards('A');
}
else
{
qsort (c_A, 3, sizeof(int), compare);
r_A = card_on_hand_detect_rank('A');
}


showchecker();
printf("\nAgain Y/N? ");

/* fflush(stdin); */
getchar();
ans = toupper(getchar());
}
while (! (ans == 'N') );
}
}


int main()
{
randomize();

clrscr();
card_initialize();
card_distribute();

}

0 Comments:

Post a Comment

<< Home