#include #include "poker2.h" #define ANDEQ(f, v) ((f & v) == v) #define SETHAND(playerhand, hand) { playerhand |= (hand << 26); } #define GETHAND(playerhand) ((playerhand >> 26) & 0xF) #define GETACTIVECARDS(playerhand) ((playerhand >> 13) & 0x1FFF) #define MAXDIFFERENTHOLECARDS (52*51)/2 #define SWAP(f, y) { int q = f; f = y; y = q; } #define DEBUG struct PokerHole possibleHoleCards[MAXDIFFERENTHOLECARDS]; unsigned char pokerDeck[52]; char *suitNames[4] = { "Diamonds", "Hearts", "Clubs", "Spades" }; //printable versions char *numberNames[13] = { "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace" }; char *rankNames[9] = {"Highcard", "Pair", "Two Pair", "Trips", "Straight", "Flush", "Full House", "Quads", "Straight Flush" }; char suitNamesShort[4] = { 'd', 'h', 'c', 's' }; char numberNamesShort[13] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A', }; char filename[50]; FILE *output; int main() { printf(" Poker deck %d Hole cards %d \n ", sizeof(pokerDeck), sizeof(possibleHoleCards) ); initializePokerDeck(pokerDeck); #ifdef DEBUG #include "bigswap" #endif printf("Successfully constructed deck:\n"); visualizeDeck(pokerDeck); /* Initalize Hole Cards */ int i,j,q =0; //cnters for( i=0;i<52;i++) { for(j=(i+1);j<52;j++, q++) { possibleHoleCards[q].card1 = pokerDeck[i]; possibleHoleCards[q].card2 = pokerDeck[j]; visualizeCardShort(&possibleHoleCards[q].card1); visualizeCardShort(&possibleHoleCards[q].card2); printf(" "); possibleHoleCards[q].win = 0; possibleHoleCards[q].lose = 0; } } printf("Succesfully initialised all different possible hole cards (%d) actaul: %d\n\n", MAXDIFFERENTHOLECARDS, q); printf("Starting calculation of 333,999,737,011,200 hands.\n\n"); fflush(stdout); writeFile(0); printf("Written test file at point 0 \n\n"); fflush(stdout); //flop cards cnts, c0..c4 int c0, c1, c2, c3, c4; int h1, h2; //hands respectivly //Extra variables to help when deducing hand int flushPossible = 1; int flushPossibleAfterRiver; // int stepCounter = 0; //counts steps from 1->140608 int suitCounter[4]; //counts the ints int suitBuffer; int suitCounter1[4]; //a copy of suit counter made for player 1 (and card 5) to modify int suitCounter2[4]; //a copy of suit counter made for player 2 to modify with their own 2 cards unsigned int s,t,u,v,w; //temporary values for cards and other stuff unsigned int flushBoard; //tempoary board used to calculate the players flush value/straight unsigned char board1[13]; unsigned char board2[13]; //unsigned int board1int; //unsigned int board2int; //an int, where bit on means card exists; for calculating straight unsigned int player1hand; unsigned int player2hand; for(c0 = 0;c0<52;c0++) { for(c1=c0+1;c1<52;c1++) { for(c2=c1+1;c2<52;c2++) { for(c3=c2+1;c3<52;c3++) { //After 4th card, unless 2 of the cards have the same suit, we can assume that there is no flush, if there is one //possible, we set bits 2,3 to the suit in flushPossible and the trailing bit to 1 suitCounter[SPADES] = 0; suitCounter[CLUBS] = 0; suitCounter[DIAMONDS] = 0; suitCounter[HEARTS] = 0; flushPossible = 0; //// [??xxyyyy] where y is the number, 1-13 and x is the suit, 1-4, and ? is the flag bits suitBuffer = ((pokerDeck[c0] >> 4) & 0x03); if( suitBuffer == SPADES ) suitCounter[SPADES]++; else if ( suitBuffer == DIAMONDS ) suitCounter[DIAMONDS]++; else if ( suitBuffer == CLUBS ) suitCounter[CLUBS]++; else if ( suitBuffer == HEARTS ) suitCounter[HEARTS]++; suitBuffer = ((pokerDeck[c1] >> 4) & 0x03); if( suitBuffer == SPADES ) suitCounter[SPADES]++; else if ( suitBuffer == DIAMONDS ) suitCounter[DIAMONDS]++; else if ( suitBuffer == CLUBS ) suitCounter[CLUBS]++; else if ( suitBuffer == HEARTS ) suitCounter[HEARTS]++; suitBuffer = ((pokerDeck[c2] >> 4) & 0x03); if( suitBuffer == SPADES ) suitCounter[SPADES]++; else if ( suitBuffer == DIAMONDS ) suitCounter[DIAMONDS]++; else if ( suitBuffer == CLUBS ) suitCounter[CLUBS]++; else if ( suitBuffer == HEARTS ) suitCounter[HEARTS]++; suitBuffer = ((pokerDeck[c3] >> 4) & 0x03); if( suitBuffer == SPADES ) suitCounter[SPADES]++; else if ( suitBuffer == DIAMONDS ) suitCounter[DIAMONDS]++; else if ( suitBuffer == CLUBS ) suitCounter[CLUBS]++; else if ( suitBuffer == HEARTS ) suitCounter[HEARTS]++; if(suitCounter[SPADES] >1 || suitCounter[HEARTS] >1 || suitCounter[CLUBS] > 1 || suitCounter[DIAMONDS] > 1) flushPossible = 1; for(c4=c3+1;c4<52;c4++) { //Board setup here now into c0, c1, c2, c3, c4 //Must compare each hand for(h1=0;h1 < MAXDIFFERENTHOLECARDS; h1++) { //check none of h1's cards are on the board if(possibleHoleCards[h1].card1 == pokerDeck[c4] || possibleHoleCards[h1].card1 == pokerDeck[c3] || possibleHoleCards[h1].card1 == pokerDeck[c2] || possibleHoleCards[h1].card1 == pokerDeck[c1] || possibleHoleCards[h1].card1==pokerDeck[c0] || possibleHoleCards[h1].card2 == pokerDeck[c4] || possibleHoleCards[h1].card2 == pokerDeck[c3] || possibleHoleCards[h1].card2 == pokerDeck[c2] || possibleHoleCards[h1].card2 == pokerDeck[c1] || possibleHoleCards[h1].card2==pokerDeck[c0] ) { continue; } for(h2 = h1+1; h2< MAXDIFFERENTHOLECARDS; h2++) { if(possibleHoleCards[h2].card1 == pokerDeck[c4] || possibleHoleCards[h2].card1 == pokerDeck[c3] || possibleHoleCards[h2].card1 == pokerDeck[c2] || possibleHoleCards[h2].card1 == pokerDeck[c1] || possibleHoleCards[h2].card1==pokerDeck[c0] || possibleHoleCards[h2].card2 == pokerDeck[c4] || possibleHoleCards[h2].card2 == pokerDeck[c3] || possibleHoleCards[h2].card2 == pokerDeck[c2] || possibleHoleCards[h2].card2 == pokerDeck[c1] || possibleHoleCards[h2].card2==pokerDeck[c0] || possibleHoleCards[h2].card1 == possibleHoleCards[h1].card1 || possibleHoleCards[h2].card1 == possibleHoleCards[h1].card2 || possibleHoleCards[h2].card2 == possibleHoleCards[h1].card1 || possibleHoleCards[h2].card2 == possibleHoleCards[h1].card2) { continue; } //reset flush poss flushPossibleAfterRiver = 0; //reset integer representations of board player1hand = 0; player2hand = 0; //reset board variables board1[CARDACE]=0, board1[CARDTWO]=0, board1[CARDTHREE]=0, board1[CARDFOUR]=0, board1[CARDFIVE]=0, board1[CARDSIX]=0, board1[CARDSEVEN]=0, board1[CARDEIGHT]=0, board1[CARDNINE]=0, board1[CARDTEN]=0, board1[CARDJACK]=0, board1[CARDQUEEN]=0, board1[CARDKING] =0; board2[CARDACE]=0, board2[CARDTWO]=0, board2[CARDTHREE]=0, board2[CARDFOUR]=0, board2[CARDFIVE]=0, board2[CARDSIX]=0, board2[CARDSEVEN]=0, board2[CARDEIGHT]=0, board2[CARDNINE]=0, board2[CARDTEN]=0, board2[CARDJACK]=0, board2[CARDQUEEN]=0, board2[CARDKING] =0; //hand int have 13 bits used for cards on board //setup players 1 cards t = pokerDeck[c0] & 0x0F; board1[t]++; player1hand |= (1 << t); t = pokerDeck[c1] & 0x0F; board1[t]++; player1hand |= (1 << t); t = pokerDeck[c2] & 0x0F; board1[t]++; player1hand |= (1 << t); t = pokerDeck[c3] & 0x0F; board1[t]++; player1hand |= (1 << t); t = pokerDeck[c4] & 0x0F; board1[t]++; player1hand |= (1 << t); t = possibleHoleCards[h1].card1 & 0x0F; board1[t]++; player1hand |= (1 << t); t = possibleHoleCards[h1].card2 & 0x0F; board1[t]++; player1hand |= (1 << t); //setup players 2 cards t = pokerDeck[c0] & 0x0F; board2[t]++; player2hand |= (1 << t); t = pokerDeck[c1] & 0x0F; board2[t]++; player2hand |= (1 << t); t = pokerDeck[c2] & 0x0F; board2[t]++; player2hand |= (1 << t); t = pokerDeck[c3] & 0x0F; board2[t]++; player2hand |= (1 << t); t = pokerDeck[c4] & 0x0F; board2[t]++; player2hand |= (1 << t); t = possibleHoleCards[h2].card1 & 0x0F; board2[t]++; player2hand |= (1 << t); t = possibleHoleCards[h2].card2 & 0x0F; board2[t]++; player2hand |= (1 << t); //Add 5th card into suit Buffer (if a flush is possbible) //player 1 calculations if(flushPossible == 1) { flushPossibleAfterRiver = 1; for(t=0;t<4;t++) suitCounter1[t] = suitCounter[t]; //copy suitCounter to suitCounter1 - our local version suitBuffer = ((pokerDeck[c4] >> 4) & 0x03); if( suitBuffer == SPADES ) suitCounter1[SPADES]++; else if ( suitBuffer == DIAMONDS ) suitCounter1[DIAMONDS]++; else if ( suitBuffer == CLUBS ) suitCounter1[CLUBS]++; else if ( suitBuffer == HEARTS ) suitCounter1[HEARTS]++; if ( suitCounter[HEARTS] >= 0x03 || suitCounter1[SPADES] >= 0x03 || suitCounter[DIAMONDS] >= 0x03 || suitCounter1[CLUBS] >= 0x03 ) { //if it's true, we copy into suitCounter for player 2 to add to their own hands later on for(t=0;t<4;t++) suitCounter2[t] = suitCounter1[t]; } else { flushPossibleAfterRiver = 0; } } //Player 1's hand calculate //Check for straights // //p1: //Firstly check if there's a flush possible and if so hand that flush, we can use //t to hold the suit value of the flush if(flushPossibleAfterRiver == 1) { //if the flush is still possible, we set up player1's full flush counter (suitCounter) suitBuffer = ((possibleHoleCards[h1].card1 >> 4) & 0x03); if( suitBuffer == SPADES ) suitCounter1[SPADES]++; else if ( suitBuffer == DIAMONDS ) suitCounter1[DIAMONDS]++; else if ( suitBuffer == CLUBS ) suitCounter1[CLUBS]++; else if ( suitBuffer == HEARTS ) suitCounter1[HEARTS]++; suitBuffer = ((possibleHoleCards[h1].card2 >> 4) & 0x03); if( suitBuffer == SPADES ) suitCounter1[SPADES]++; else if ( suitBuffer == DIAMONDS ) suitCounter1[DIAMONDS]++; else if ( suitBuffer == CLUBS ) suitCounter1[CLUBS]++; else if ( suitBuffer == HEARTS ) suitCounter1[HEARTS]++; //Check now with final cards, if a flush is possible; aka one is 5 if(suitCounter1[SPADES] >= 5) { player1hand |= ( SPADES << 30 ); suitBuffer = SPADES; //user buffer for type of suit goto p1flushsuitset; } if(suitCounter1[HEARTS] >= 5) { player1hand |= ( HEARTS << 30 ); suitBuffer = HEARTS; goto p1flushsuitset; } if(suitCounter1[DIAMONDS] >= 5) { player1hand |= ( DIAMONDS << 30 ); suitBuffer = DIAMONDS; goto p1flushsuitset; } if(suitCounter1[CLUBS] >= 5) { player1hand |= ( CLUBS << 30 ); suitBuffer = CLUBS; goto p1flushsuitset; } flushPossibleAfterRiver = 0; //no flush is possible goto p1noflush; p1flushsuitset: //use flushboard value flushBoard = 0; if( ((pokerDeck[c0] >> 4) & 0x03) == suitBuffer ) { t = pokerDeck[c0] & 0x0F; flushBoard |= (1 << t); } if( ((pokerDeck[c1] >> 4) & 0x03) == suitBuffer ) { t = pokerDeck[c1] & 0x0F; flushBoard |= (1 << t); } if( ((pokerDeck[c2] >> 4) & 0x03) == suitBuffer ) { t = pokerDeck[c2] & 0x0F; //printf(" flushBoard is %d after %d\n ", flushBoard, (pokerDeck[c2] >> 4) & 0x03 ); flushBoard |= (1 << t); } if( ((pokerDeck[c3] >> 4) & 0x03) == suitBuffer ) { t = pokerDeck[c3] & 0x0F; //printf(" flushBoard is %d after %d\n ", flushBoard, (pokerDeck[c3] >> 4) & 0x03 ); flushBoard |= (1 << t); } if( ((pokerDeck[c4] >> 4) & 0x03) == suitBuffer ) { t = pokerDeck[c4] & 0x0F; flushBoard |= (1 << t); } if( ((possibleHoleCards[h1].card1 >> 4) & 0x03) == suitBuffer ) { t = possibleHoleCards[h1].card1 & 0x0F; flushBoard |= (1 << t); } if( ((possibleHoleCards[h1].card2 >> 4) & 0x03) == suitBuffer ) { t = possibleHoleCards[h1].card2 & 0x0F; flushBoard |= (1 << t); } //printf("flushBoard is %d \n ", flushBoard); //fflush(stdout); //Check for straights t=0; //lets use t again for(;t<9;t++) { if( ANDEQ((flushBoard << t), 0x1F00) ) { SETHAND(player1hand, STRAIGHTFLUSH); player1hand |= ((0x1F00 >> t) << 13); goto p2; }//right bits } //check for A...........5432 if(ANDEQ(flushBoard, 0x100F)) { SETHAND(player1hand, STRAIGHTFLUSH); player1hand |= (0x100F << 13); //set board values goto p2; //no need to check rest } //no straight flush, so take top 5 of the suit //must continue processing after, as FH > flush u=12; //shift right max to get highest on bit (excl ace) suitBuffer = 0; //reuse suitBuffer t = 0; while(t<5) { if (ANDEQ( ( flushBoard >> u), 0x01 ) ) { suitBuffer |= (1 << u); t++; } u--; } player1hand |= (suitBuffer << 13); //setup hand SETHAND(player1hand, FLUSH); } p1noflush: //check for quads; quite a simple one t = 0; u = 0; for(t=0;t<13 && u<4;t++) { if(board1[t] == 4) { SETHAND(player1hand, QUADS); player1hand |= (1 << (13 + t)); goto p2; } else { u += board1[t]; } } //next check if for full houses; to do this we use board1 array t = 0; u = 0; // 01b is found 2 of kind, 10b is found 3 of kind for(t=0;t<13;t++) { //if we come accross a 1 we can bail if(ANDEQ(~u, 0x1) && (board1[t] == 2) || (ANDEQ(u, 0x3) && board1[t] > 2) ){ u |= 0x1; if(ANDEQ(u, 0x3)) break; } else if(ANDEQ(~u, 0x2) && (board1[t] == 3)) { u |= 0x2; player1hand |= (1 << (13 + t)); if(ANDEQ(u, 0x3)) break; } } if(ANDEQ(u, 0x3)) { SETHAND(player1hand, FULLHOUSE); goto p2; //full house beats all below } if(GETHAND(player1hand) == FLUSH) { goto p2; //nothing left can beat our flush } //check for straights t=0; //lets use t again for(;t<9;t++) { if( ANDEQ((player1hand << t), 0x1F00) ) { SETHAND(player1hand, STRAIGHT); player1hand |= ((0x1F00 >> t) << 13); goto p2; } } if(ANDEQ(player1hand, 0x100F)) { //ace to 5 SETHAND(player1hand, STRAIGHT); player1hand |= (0x100F << 13); //set board values goto p2; //no need to check rest } //Next thing is trips; very similar to quads t = 0; u = 0; for(t=0;t<13 && u<5;t++) { if(board1[t] == 3) { SETHAND(player1hand, TRIPS); player1hand |= (1 << (13 + t)); //only set trip, so can > comp on hand later goto p2; } else { u += board1[t]; } } //And to 2 pair, this time, the bit left on in the hand is the //Highest of the 2 pair, will help separting out 2 people both with //2 pair; for this we use flush buffer (suitBuffer) to help us, and thus //carry out a lot of the 1 pair analysis at the same time suitBuffer = 0; t = 0; u = 0; for(t=0;t<13 && u<6;t++) { //Firsly copy 2 pairs into suitBuffer if(board1[t] == 2) { suitBuffer |= (1<> t), 0x1 )){ player1hand |= (1 << (13 + t)); u++; if(u == 2) { //found 2 pair SETHAND(player1hand, TWOPAIR); goto p2; } } } if(u == 1) { SETHAND(player1hand, PAIR); goto p2; } else { u = 12; //make sure shit to right max to get highest on bits suitBuffer = 0; //reuse suitBuffer 1 more time //high card, copy over highest 5 cards, as still can be >'ed t=0; while(t<5) { if (ANDEQ( ( player1hand >> u), 0x01 ) ) { suitBuffer |= (1 << u); t++; } u--; } player1hand |= (suitBuffer << 13); //combine with the hand SETHAND(player1hand, HIGHCARD); } p2: //Firstly check if there's a flush possible and if so hand that flush, we can use //t to hold the suit value of the flush if(flushPossibleAfterRiver == 1) { //if the flush is still possible, we set up player1's full flush counter (suitCounter) suitBuffer = ((possibleHoleCards[h2].card1 >> 4) & 0x03); if( suitBuffer == SPADES ) suitCounter2[SPADES]++; else if ( suitBuffer == DIAMONDS ) suitCounter2[DIAMONDS]++; else if ( suitBuffer == CLUBS ) suitCounter2[CLUBS]++; else if ( suitBuffer == HEARTS ) suitCounter2[HEARTS]++; suitBuffer = ((possibleHoleCards[h2].card2 >> 4) & 0x03); if( suitBuffer == SPADES ) suitCounter2[SPADES]++; else if ( suitBuffer == DIAMONDS ) suitCounter2[DIAMONDS]++; else if ( suitBuffer == CLUBS ) suitCounter2[CLUBS]++; else if ( suitBuffer == HEARTS ) suitCounter2[HEARTS]++; //Check now with final cards, if a flush is possible; aka one is 5 if(suitCounter2[SPADES] >= 5) { player2hand |= ( SPADES << 30 ); suitBuffer = SPADES; //user buffer for type of suit goto p2flushsuitset; } if(suitCounter2[HEARTS] >= 5) { player2hand |= ( HEARTS << 30 ); suitBuffer = HEARTS; goto p2flushsuitset; } if(suitCounter2[DIAMONDS] >= 5) { player2hand |= ( DIAMONDS << 30 ); suitBuffer = DIAMONDS; goto p2flushsuitset; } if(suitCounter2[CLUBS] >= 5) { player2hand |= ( CLUBS << 30 ); suitBuffer = CLUBS; goto p2flushsuitset; } flushPossibleAfterRiver = 0; //no flush is possible goto p2noflush; p2flushsuitset: //use flushboard value flushBoard = 0; if( ((pokerDeck[c0] >> 4) & 0x03) == suitBuffer ) { t = pokerDeck[c0] & 0x0F; flushBoard |= (1 << t); } if( ((pokerDeck[c1] >> 4) & 0x03) == suitBuffer ) { t = pokerDeck[c1] & 0x0F; flushBoard |= (1 << t); } if( ((pokerDeck[c2] >> 4) & 0x03) == suitBuffer ) { t = pokerDeck[c2] & 0x0F; //printf(" flushBoard is %d after %d\n ", flushBoard, (pokerDeck[c2] >> 4) & 0x03 ); flushBoard |= (1 << t); } if( ((pokerDeck[c3] >> 4) & 0x03) == suitBuffer ) { t = pokerDeck[c3] & 0x0F; //printf(" flushBoard is %d after %d\n ", flushBoard, (pokerDeck[c3] >> 4) & 0x03 ); flushBoard |= (1 << t); } if( ((pokerDeck[c4] >> 4) & 0x03) == suitBuffer ) { t = pokerDeck[c4] & 0x0F; flushBoard |= (1 << t); } if( ((possibleHoleCards[h2].card1 >> 4) & 0x03) == suitBuffer ) { t = possibleHoleCards[h2].card1 & 0x0F; flushBoard |= (1 << t); } if( ((possibleHoleCards[h2].card2 >> 4) & 0x03) == suitBuffer ) { t = possibleHoleCards[h2].card2 & 0x0F; flushBoard |= (1 << t); } //Check for straights t=0; //lets use t again for(;t<9;t++) { if( ANDEQ((flushBoard << t), 0x1F00) ) { SETHAND(player2hand, STRAIGHTFLUSH); player2hand |= ((0x1F00 >> t) << 13); goto end; }//right bits } //check for A...........5432 if(ANDEQ(flushBoard, 0x100F)) { SETHAND(player2hand, STRAIGHTFLUSH); player2hand |= (0x100F << 13); //set board values goto end; //no need to check rest } //no straight flush, so take top 5 of the suit //must continue processing after, as FH > flush u=12; //shift right max to get highest on bit (excl ace) suitBuffer = 0; //reuse suitBuffer t = 0; while(t<5) { if (ANDEQ( ( flushBoard >> u), 0x01 ) ) { suitBuffer |= (1 << u); t++; } u--; } player2hand |= (suitBuffer << 13); //setup hand SETHAND(player2hand, FLUSH); } p2noflush: //check for quads; quite a simple one t = 0; u = 0; for(t=0;t<13 && u<4;t++) { if(board2[t] == 4) { SETHAND(player2hand, QUADS); player2hand |= (1 << (13 + t)); goto end; } else { u += board2[t]; } } //next check if for full houses; to do this we use board1 array t = 0; u = 0; // 01b is found 2 of kind, 10b is found 3 of kind for(t=0;t<13;t++) { //if we come accross a 1 we can bail if(ANDEQ(~u, 0x1) && (board2[t] == 2) || (ANDEQ(u, 0x3) && board2[t] > 2) ){ u |= 0x1; if(ANDEQ(u, 0x3)) break; } else if(ANDEQ(~u, 0x2) && (board2[t] == 3)) { u |= 0x2; player2hand |= (1 << (13 + t)); if(ANDEQ(u, 0x3)) break; } } if(ANDEQ(u, 0x3)) { SETHAND(player2hand, FULLHOUSE); goto end; //full house beats all below } if(GETHAND(player2hand) == FLUSH) { goto end; //nothing left can beat our flush } //check for straights t=0; //lets use t again for(;t<9;t++) { if( ANDEQ((player2hand << t), 0x1F00) ) { SETHAND(player2hand, STRAIGHT); player2hand |= ((0x1F00 >> t) << 13); goto end; } } if(ANDEQ(player2hand, 0x100F)) { //ace to 5 SETHAND(player2hand, STRAIGHT); player2hand |= (0x100F << 13); //set board values goto end; //no need to check rest } //Next thing is trips; very similar to quads t = 0; u = 0; for(t=0;t<13 && u<5;t++) { if(board2[t] == 3) { SETHAND(player2hand, TRIPS); player2hand |= (1 << (13 + t)); //only set trip, so can > comp on hand later goto end; } else { u += board2[t]; } } //And to 2 pair, this time, the bit left on in the hand is the //Highest of the 2 pair, will help separting out 2 people both with //2 pair; for this we use flush buffer (suitBuffer) to help us, and thus //carry out a lot of the 1 pair analysis at the same time suitBuffer = 0; t = 0; u = 0; for(t=0;t<13 && u<6;t++) { //Firsly copy 2 pairs into suitBuffer if(board2[t] == 2) { suitBuffer |= (1<> t), 0x1 )){ player2hand |= (1 << (13 + t)); u++; if(u == 2) { //found 2 pair SETHAND(player2hand, TWOPAIR); goto end; } } } if(u == 1) { SETHAND(player2hand, PAIR); goto end; } else { u = 12; //make sure shit to right max to get highest on bits suitBuffer = 0; //reuse suitBuffer 1 more time //high card, copy over highest 5 cards, as still can be >'ed t=0; while(t<5) { if (ANDEQ( ( player2hand >> u), 0x01 ) ) { suitBuffer |= (1 << u); t++; } u--; } player2hand |= (suitBuffer << 13); //combine with the hand SETHAND(player2hand, HIGHCARD); } end: //t and v are player 1's //u and w are player 2's s = 0; t = GETHAND(player1hand); u = GETHAND(player2hand); if(t > u) { s = 0x1; } else if(u > t ) { s = 0x2; } else { //They are equals; and now come forth the pain //Hands that we can deal with using simple v = GETACTIVECARDS(player1hand); w = GETACTIVECARDS(player2hand); //put aces up //suitBuffer = 0; //suitBuffer = (v & 0x1); //v >>= 1; //v |= (suitBuffer << 12); //put aces up //suitBuffer = 0; //suitBuffer = (w & 0x1); //w >>= 1; //w |= (suitBuffer << 12); if(v == w) { switch ( GETHAND(player1hand) ) { case TRIPS: //We must go and find first //2 cards from board which are //not trips and factor in //we use u,t,v,w again u =CARDACE; //v and w represent count of //cards found, v is player 1's //w is player 2's v = 0; w = 0; t = 0; for(;u>CARDTWO && v < 2 && w < 2;u--) { if(board1[u] != 3 || t == 1) { v += board1[u]; } else if(board2[u] != 3 || t == 1) { w += board2[u]; } else { t = 1; } } break; case PAIR: u =CARDACE; v = 0; w = 0; t = 0; for(;u>CARDTWO && v < 3 && w < 3;u--) { if(board1[u] != 2) { //know both got same pair so only need to check 1 board v += board1[u]; //add cards } if(board2[u] != 2) { w += board2[u]; } } break; case TWOPAIR: u =CARDACE; v = 0; w = 0; for(;u>CARDTWO && v < 1 && w < 1;u--) { if(board1[u] != 2) { v += board1[u]; //add cards } if(board2[u] != 2) { w += board2[u]; } } break; case FULLHOUSE: //msut find first pair u =CARDACE; v = 0; w = 0; for(;u>CARDTWO && v < 5 && w < 5;u--) { if(board1[u] >= 2 && v != 2) { //know both got same pair so only need to check 1 board v += board1[u]; //add cards } if (board2[u] >= 2 && w != 2) { w += board2[u]; } } break; case QUADS: u =CARDACE; v = 0; w = 0; for(;u>CARDTWO && v < 1 && w < 2;u--) { if(board1[u] < 4 ) { //know both got same pair so only need to check 1 board v += board1[u]; //add cards } if(board2[u] < 4 ) { w += board2[u]; } } break; } } //if(v > w) s = 0x1; if(v>w) //player 1 wins { possibleHoleCards[h1].win ++; possibleHoleCards[h2].lose ++; } else if (w > v ) { possibleHoleCards[h2].win ++; possibleHoleCards[h1].lose ++; } else { possibleHoleCards[h1].split ++; possibleHoleCards[h2].split ++; } //else if (w > v) s = 0x2; //else { s = 0x3; } } //visualizeFullHand(&player1hand, &player2hand, &pokerDeck[c0], // &pokerDeck[c1], &pokerDeck[c2], &pokerDeck[c3], &pokerDeck[c4], // &possibleHoleCards[h1], &possibleHoleCards[h2], s); //visualizeHand(&player1hand, board1); //visualizeHand(&player2hand, board2); //fflush(stdout); //player2: //2 hands now stored in h1 and h2 //tmp = tmp * possibleHoleCards[h1].card1; //tmp = tmp / possibleHoleCards[h1].card2; // } } //END Board //printf("Progressing"); } stepCounter++; printf("Done %d of 7311616 sets of 45680700 calculations (%3.5f)\n", stepCounter, stepCounter * 0.0000136768670564756f); fflush(stdout); writeFile(stepCounter); } } } } //For Every board //Look at all 2 sets of hold cards //If one on board; skip //else set which wins exit(0); } void initializePokerDeck(unsigned char *deck) { //initializes a 52 card desk at pointer deck int i, j, p; //p holds the position for(i=0,p=0;i<4;i++) { //I dictates the suit for(j=0;j<13;j++,p++) { //J Dictatates the card deck[p] = i; deck[p] <<= 4; deck[p] |= j; // [??xxyyyy] where y is the number, 1-13 and x is the suit, 1-4, and ? is the flag bits } } } //Outputs a whole deck void visualizeDeck(unsigned char *deck) { int k=0; for(k=0;k<52;k++) visualizeCard(&deck[k]); } // Outputs a single card void visualizeCard(unsigned char *card) { printf("%s of %s flag bits %d\n", numberNames[ (*card & 0x0F) ], suitNames[ ( (*card >> 4) & 0x03 ) ],(int) *card >> 6 ); } void visualizeCardShort(unsigned char *card) { printf("%c%c ", numberNamesShort[ (*card & 0x0F) ], suitNamesShort[ ( (*card >> 4) & 0x03 ) ] ); } int c[32]; int y; unsigned int z; void visualizeHand(unsigned int *hand, unsigned char *board) { //if(((*hand >> 26) & 0xF) == FLUSH || ((*hand >> 26) & 0xF) == STRAIGHTFLUSH) return; z = (*hand >> 13) & 0x1FFF; //just last 13 bits printf("Hand: "); for(y =12;y>=0;y--) { printf("%d", (z>>y) & 0x1 ); } z = (*hand & 0x1FFF); printf(" Availble Cards: "); for(y =12;y>=0;y--) { printf("%d", (z>>y) & 0x1 ); } printf(" "); for(y=0;y<13;y++) { if(board[y] > 0) { z = board[y]; for(;z > 0;z--) printf("%c, ", numberNamesShort[y]); } } printf(" Rank: %s\n", rankNames[ ((*hand >> 26) & 0xF)] ); } void writeFile(unsigned int pointFilename) { //int sprintf ( char * str, const char * format, ... ); sprintf(filename, "point.%d", pointFilename); if ((output = fopen(filename, "w")) == NULL) fprintf(stderr, "Cannot open %s\n", filename); int i = 0; for(;i> 4) & 0x03 ) ], numberNamesShort[ (possibleHoleCards[i].card2 & 0x0F) ], suitNamesShort[ ( (possibleHoleCards[i].card1 >> 4) & 0x03 ) ], possibleHoleCards[i].win, possibleHoleCards[i].lose, possibleHoleCards[i].split); } fclose(output); } void visualizeFullHand(unsigned int *player1hand, unsigned int *player2hand, unsigned char *c0, unsigned char *c1,unsigned char *c2,unsigned char *c3,unsigned char *c4, struct PokerHole *hole1, struct PokerHole *hole2, unsigned int winner) { //if(winner != 3) return; /*A very slow method; should be used for debugging, outputs the full information of the hand*/ printf("BOARD: "); visualizeCardShort(c0); visualizeCardShort(c1); visualizeCardShort(c2); visualizeCardShort(c3); visualizeCardShort(c4); printf("\n Player 1 Hole Cards: "); visualizeCardShort(&(*hole1).card1); visualizeCardShort(&(*hole1).card2); printf("\n Player 2 Hole Cards: "); visualizeCardShort(&(*hole2).card1); visualizeCardShort(&(*hole2).card2); printf("\n The winner was player %d", winner); printf("\n Player 1 has a %s using cards bit ", rankNames[ ((*player1hand >> 26) & 0xF)]); z = (*player1hand >> 13) & 0x1FFF; //just last 13 bits for(y =12;y>=0;y--) { printf("%d", (z>>y) & 0x1 ); } printf("\n Player 2 has a %s using cards bit ", rankNames[ ((*player2hand >> 26) & 0xF)]); z = (*player2hand >> 13) & 0x1FFF; //just last 13 bits for(y =12;y>=0;y--) { printf("%d", (z>>y) & 0x1 ); } printf("\n\n"); }