#include #include #include #include "poker.h" /* converts a hand (of 5 cards) to a string representation, and stores it in the * provided buffer. The buffer is assumed to be large enough. */ void hand_to_string (hand_t hand, char *handstr) { char *p = handstr; int i; char *val, *suit; for (i=0; i<5; i++) { if (hand[i].value < 10) { *p++ = hand[i].value + '0'; } else { switch(hand[i].value) { case 10: *p++ = 'T'; break; case 11: *p++ = 'J'; break; case 12: *p++ = 'Q'; break; case 13: *p++ = 'K'; break; case 14: *p++ = 'A'; break; } } switch(hand[i].suit) { case DIAMOND: *p++ = 'D'; break; case CLUB: *p++ = 'C'; break; case HEART: *p++ = 'H'; break; case SPADE: *p++ = 'S'; break; } if (i<=3) *p++ = ' '; } *p = '\0'; } /* converts a string representation of a hand into 5 separate card structs. The * given array of cards is populated with the card values. */ void string_to_hand (const char *handstr, hand_t hand) { int i; for(i=0;i<5;++i){ int num = handstr[i*3]; if(num<='9') hand[i].value = num - 48; else{ if((char)num == 'T') num = 10; if((char)num == 'A') num = 14; if((char)num == 'K') num = 13; if((char)num == 'Q') num = 12; if((char)num == 'J') num = 11; hand[i].value = num; } char suit = handstr[i*3+1]; switch(suit){ case 'D': hand[i].suit=DIAMOND; break; case 'C': hand[i].suit= CLUB; break; case 'H': hand[i].suit=HEART; break; case 'S': hand[i].suit=SPADE; break; } } } /* sorts the hands so that the cards are in ascending order of value (two * lowest, ace highest */ void sort_hand (hand_t hand) { int curr = 0; int low_spot = 0; int low_value = 0; int j; for(curr = 0; curr<5;++curr){ low_spot=curr; low_value=hand[curr].value; for(j = low_spot;j<5;++j){ if(low_value > hand[j].value){ low_value=hand[j].value; low_spot=j; } } if(low_spot!=curr){ int val = hand[low_spot].value; suit_t s= hand[low_spot].suit; hand[low_spot].value=hand[curr].value; hand[low_spot].suit=hand[curr].suit; hand[curr].value=val; hand[curr].suit=s; } } } int count_pairs (hand_t hand) { int curr = 0; int pairs = 0; int j = 0; for(curr = 0; curr<5;++curr){ for(j = 1 +curr;j<5;++j){ if(hand[curr].value == hand[j].value) ++pairs; } } return pairs; } int count_three(hand_t hand){ int curr = 0; int pairs = 0; int j = 0; for(curr = 0; curr<5;++curr){ pairs = 0; for(j = 1 +curr;j<5;++j){ if(hand[curr].value == hand[j].value) ++pairs; } if(pairs>=2) return 1; } return 0; } int is_onepair (hand_t hand) { return (count_pairs(hand)>=1); } int is_twopairs (hand_t hand) { return (count_pairs(hand)>=2); } int is_threeofakind (hand_t hand) { return count_three(hand); } int is_straight (hand_t hand) { sort_hand(hand); if((hand[0].value==2)&&(hand[4].value==14)&&(rec_straight(hand,0)==3)) return 1; return (rec_straight(hand,0)==4); } int rec_straight(hand_t hand, int spot){ if(spot == 4) return 0; if(hand[spot].value+1==hand[spot+1].value) return 1+rec_straight(hand, ++spot); return 0; } int is_fullhouse (hand_t hand) { return ((count_pairs(hand)==4)&&is_threeofakind(hand)&&(!(is_fourofakind(hand)))); } int is_flush (hand_t hand) { int out = 0; int i = 0; for(i=0;i<4;++i){ if(!(out=(hand[i].suit==hand[i+1].suit))) break; } return out; } int is_straightflush (hand_t hand) { return ((is_straight(hand))&&(is_flush(hand))); } int is_fourofakind (hand_t hand) { int curr; int pairs = 0; int j; for(curr = 0; curr<5;++curr){ pairs = 0; for(j = 1 +curr;j<5;++j){ if(hand[curr].value == hand[j].value) ++pairs; } if(pairs==3) return 1; } return 0; } int is_royalflush (hand_t hand) { return is_straight(hand)&&is_flush(hand)&&(hand[4].value==14); } /* compares the hands based on rank -- if the ranks (and rank values) are * identical, compares the hands based on their highcards. * returns 0 if h1 > h2, 1 if h2 > h1. */ int compare_hands (hand_t h1, hand_t h2) { int h1_score =0; int h2_score =0; if(is_onepair(h1)) h1_score = 1; if(is_twopairs(h1)) h1_score = 2; if(is_threeofakind(h1)) h1_score = 3; if(is_straight(h1)) h1_score = 4; if(is_flush(h1)) h1_score = 5; if(is_fullhouse(h1)) h1_score = 6; if(is_fourofakind(h1)) h1_score = 7; if(is_straightflush(h1)) h1_score = 8; if(is_royalflush(h1)) h1_score = 9; if(is_onepair(h2)) h2_score = 1; if(is_twopairs(h2)) h2_score = 2; if(is_threeofakind(h2)) h2_score = 3; if(is_straight(h2)) h2_score = 4; if(is_flush(h2)) h2_score = 5; if(is_fullhouse(h2)) h2_score = 6; if(is_fourofakind(h2)) h2_score = 7; if(is_straightflush(h2)) h2_score = 8; if(is_royalflush(h2)) h2_score = 9; //printf("h1 %d h2 %d \n", h1_score, h2_score); if(h1_score==h2_score) return compare_highcards(h1,h2); if(h1_score>h2_score) return 0; if(h2_score>h1_score) return 1; printf("something is amiss"); } /* compares the hands based solely on their highcard values (ignoring rank). if * the highcards are a draw, compare the next set of highcards, and so forth. */ int compare_highcards (hand_t h1, hand_t h2) { sort_hand(h1); sort_hand(h2); int i; for(i =4; i>-1; --i){ int result = h2[i].value-h1[i].value; if(result==0) continue; if(result<0) return 0; return 1; } return -1; }