![]() |
|
#1
|
|||
|
|||
![]()
I was just wondering if anyone could point me in the right direction to an algorithm that figures out your best 5-card hand at the end of the hand.
Also, do any of you have any good ideas for expressing different hand values? I was thinking of making a few enumerated values for each of the main "types" of hands, then doing card-by-card comparisons if any two players' hands match. For instance, something like this: enum HANDRANK { NOPAIR = 0, ONEPAIR = 1, TWOPAIR = 2, THREEKIND = 3, STRAIGHT = 4, FLUSH = 5, FULLHOUSE = 6, FOURKIND = 7, STRAIGHTFLUSH = 8}; And then comparing the values to see who won. Any better ways to do this? Thanks. |
#2
|
|||
|
|||
![]()
trying to code up a bot?
|
#3
|
|||
|
|||
![]()
[ QUOTE ]
trying to code up a bot? [/ QUOTE ] sorta, but I'd call it a simulation more than a bot. right now i've got 9 opponents who randomly decide whether to bet raise or fold [img]/images/graemlins/smile.gif[/img] |
#4
|
|||
|
|||
![]()
There is some open source code that will do exactly what you're looking for. Just look around on Sourceforge.
To the bot accuser. Anyone capable of writing a bot that is worth worrying about wouldn't need to ask how to write code to determine what kind of hand he has. StumpyJoe |
#5
|
|||
|
|||
![]()
I might be interested in some sort of code to work out how strong a hand is with less than 7 cards. So say after turn, it could classify the hands as 'two pair' or 'two pair with flush draw' or 'flush draw' etc.
|
#6
|
|||
|
|||
![]()
[ QUOTE ]
I might be interested in some sort of code to work out how strong a hand is with less than 7 cards. So say after turn, it could classify the hands as 'two pair' or 'two pair with flush draw' or 'flush draw' etc. [/ QUOTE ] I've written this type of code. It's more tedious and more open for interpretation than you'd think. The problem is how to label the various straight draws and gutshots mixed in with overcards. |
#7
|
|||
|
|||
![]()
Also, I just want an algorithm, not actual code. I'm really just trying to keep my programing skills sharpened during the summer.
|
#8
|
|||
|
|||
![]()
[ QUOTE ]
Also, I just want an algorithm, not actual code. I'm really just trying to keep my programing skills sharpened during the summer. [/ QUOTE ] step 1 create a table of all valid hands starting with lowest (2,3,4,5,7) so it returns 1 and ending with highest (royal flush) so it returns 7462 step 2 if the score is 1-1277 its a highcard hand (no pair) if the score is 1278 - 4137 its a one pair hand etc.. if the score is 7452 - 7462 it is a straight flush You can get more detailed if you want like 1124-1277 is an Ace high hand. and look here http://forumserver.twoplustwo.com/showfl...e=0#Post6652490 |
#9
|
|||
|
|||
![]()
In case anyone was wondering... here is the code I came up with. I still have to find a way to check for A2345 straights and straightflushes, since I made the Ace count as high when I coded it.
<font class="small">Code:</font><hr /><pre> HAND evalHand(Player * thePlayer, Board * theBoard) { //stores the player's hole cards vector<Card> holeCards; holeCards.push_back(thePlayer->getHoleCard(0)); holeCards.push_back(thePlayer->getHoleCard(1)); //stores the board cards vector<Card> boardCards; for(int i = 0; i < 5; ++i){ boardCards.push_back(theBoard->at(i)); } sort(boardCards.begin(), boardCards.end()); //add holecards to form a "total" hand, they are left seperate for "incomplete" hand evaluation //later on in a different function vector<Card> allCards; allCards.push_back(holeCards[0]); allCards.push_back(holeCards[1]); for(int i = 0; i < 5; ++i){ allCards.push_back(boardCards[i]); } sort(allCards.begin(), allCards.end(), sortBySuit()); //first sort by suit to check for straightflush //------begin checking hands-------------------- //************check for flush or straightflush********************* bool flush = false; Card c = allCards[6]; int flushCount = 1, straightFlushCount = 1; int flushIndex= 6, straightFlushIndex = 6; for(int i = 5; i >= 0; --i){ //loop through the array backwards, checking the highest card first if(c.getSuit() == allCards[i].getSuit()){ //next in flush if(c.getRank() - allCards[i].getRank() == 1){ //straight-flush count straightFlushCount++; //begin building straightflush flushCount++; } else { //no straight-flush, but still could be flush straightFlushCount = 1; straightFlushIndex = i; flushCount++; } } else { //no flush or straightflush straightFlushCount = 1; straightFlushIndex = i; if(!flush){ //don't reset flush counts if we already have one flushCount = 1; flushIndex = i; } } if(flushCount >= 5){ //flush! if(straightFlushCount == 5) { //could be a straight-flush return STRAIGHTFLUSH; } else { flush = true; //can't return yet since we have to check for rest of straightflush, //quads or fullhouse } } c = allCards[i]; } //*********check for four of a kind, trips, two pair, one pair****************** int threeKind = 0, pair = 0; int pairCount[7] = {1,1,1,1,1,1,1}; for(int j = 0; j < 7; ++j){ for(int i = 0; i < 7; ++i){ if(i != j){ if(allCards[j].getRank() == allCards[i].getRank()){ pairCount[j]++; } } } if(pairCount[j] == 4){ return FOURKIND; } else if(pairCount[j] == 3){ threeKind++; } else if(pairCount[j] == 2){ pair++; } } //*************check for full house********************** if((threeKind == 3 && (pair == 2 || pair == 4)) || threeKind == 6){ return FULLHOUSE; } //*************check for flush*************************** if(flush){ return FLUSH; } //**************check for straight******************* sort(allCards.begin(), allCards.end()); //now sort by rank to check for straight int straightCount = 1, straightIndex = 6; c = allCards[6]; for(int i = 5; i >= 0; --i){ //loop through the array backwards, checking the highest card first if(c.getRank() - allCards[i].getRank() == 1){ //next in the straight straightCount++; //if there is not a pair, reset straight counts and straightflush counts } else if(c.getRank() != allCards[i].getRank()){ straightCount = 1; straightIndex = i; } if(straightCount >= 5){ //straight! return STRAIGHT; } c = allCards[i]; } //*************check for trips********************** if(threeKind == 3){ return THREEKIND; } //************check for two pair******************** if(pair == 4 || pair == 6){ return TWOPAIR; } //***********check for one pair********************* if(pair == 2){ return ONEPAIR; } //***************HIGH CARD*************** return HIGHCARD; } </pre><hr /> |
#10
|
|||
|
|||
![]()
If you're going to do this for a living, the most important lesson you can learn is that no one will EVER through your code. This is important for email communications. Reading someone else's code is actually harder in some sense than writing your own.
I am not trying to be cute -- I made this mistake as an intern. Also, an important skill is to able to write adequate tests for your code and debug it. Bad engineers skip this part too often. Poker code is good practice for this. [ QUOTE ] In case anyone was wondering... here is the code I came up with. I still have to find a way to check for A2345 straights and straightflushes, since I made the Ace count as high when I coded it. <font class="small">Code:</font><hr /><pre> HAND evalHand(Player * thePlayer, Board * theBoard) { //stores the player's hole cards vector<Card> holeCards; holeCards.push_back(thePlayer->getHoleCard(0)); holeCards.push_back(thePlayer->getHoleCard(1)); //stores the board cards vector<Card> boardCards; for(int i = 0; i < 5; ++i){ boardCards.push_back(theBoard->at(i)); } sort(boardCards.begin(), boardCards.end()); //add holecards to form a "total" hand, they are left seperate for "incomplete" hand evaluation //later on in a different function vector<Card> allCards; allCards.push_back(holeCards[0]); allCards.push_back(holeCards[1]); for(int i = 0; i < 5; ++i){ allCards.push_back(boardCards[i]); } sort(allCards.begin(), allCards.end(), sortBySuit()); //first sort by suit to check for straightflush //------begin checking hands-------------------- //************check for flush or straightflush********************* bool flush = false; Card c = allCards[6]; int flushCount = 1, straightFlushCount = 1; int flushIndex= 6, straightFlushIndex = 6; for(int i = 5; i >= 0; --i){ //loop through the array backwards, checking the highest card first if(c.getSuit() == allCards[i].getSuit()){ //next in flush if(c.getRank() - allCards[i].getRank() == 1){ //straight-flush count straightFlushCount++; //begin building straightflush flushCount++; } else { //no straight-flush, but still could be flush straightFlushCount = 1; straightFlushIndex = i; flushCount++; } } else { //no flush or straightflush straightFlushCount = 1; straightFlushIndex = i; if(!flush){ //don't reset flush counts if we already have one flushCount = 1; flushIndex = i; } } if(flushCount >= 5){ //flush! if(straightFlushCount == 5) { //could be a straight-flush return STRAIGHTFLUSH; } else { flush = true; //can't return yet since we have to check for rest of straightflush, //quads or fullhouse } } c = allCards[i]; } //*********check for four of a kind, trips, two pair, one pair****************** int threeKind = 0, pair = 0; int pairCount[7] = {1,1,1,1,1,1,1}; for(int j = 0; j < 7; ++j){ for(int i = 0; i < 7; ++i){ if(i != j){ if(allCards[j].getRank() == allCards[i].getRank()){ pairCount[j]++; } } } if(pairCount[j] == 4){ return FOURKIND; } else if(pairCount[j] == 3){ threeKind++; } else if(pairCount[j] == 2){ pair++; } } //*************check for full house********************** if((threeKind == 3 && (pair == 2 || pair == 4)) || threeKind == 6){ return FULLHOUSE; } //*************check for flush*************************** if(flush){ return FLUSH; } //**************check for straight******************* sort(allCards.begin(), allCards.end()); //now sort by rank to check for straight int straightCount = 1, straightIndex = 6; c = allCards[6]; for(int i = 5; i >= 0; --i){ //loop through the array backwards, checking the highest card first if(c.getRank() - allCards[i].getRank() == 1){ //next in the straight straightCount++; //if there is not a pair, reset straight counts and straightflush counts } else if(c.getRank() != allCards[i].getRank()){ straightCount = 1; straightIndex = i; } if(straightCount >= 5){ //straight! return STRAIGHT; } c = allCards[i]; } //*************check for trips********************** if(threeKind == 3){ return THREEKIND; } //************check for two pair******************** if(pair == 4 || pair == 6){ return TWOPAIR; } //***********check for one pair********************* if(pair == 2){ return ONEPAIR; } //***************HIGH CARD*************** return HIGHCARD; } </pre><hr /> [/ QUOTE ] |
![]() |
|
|