tags:

views:

871

answers:

8

This is just part of the code, so never mind if you can't see the arrays or anything else. The idea is that I have 5 cards and I want to determine which ones are pairs. Does anyone understand what I mean?

boolean IsOnePair=true;

int [] cont = new int [6];

for (int i=0;i<Game.length;i++)
{
    cont[Game[i].getValue()] ++;
}

for (int i=0;i<cont.length;i++)
{
    if (cont[Game[i].getValue()]==2)
    {
        IsOnePair=false;
        System.out.println(Game+" : "+cont[i]+" times");
    }
}
+4  A: 

Well for one, your array should probably only have 5 elements, not 6 if you want it to be a true poker hand.

As for determining if there is a pair or not, I would simply check each card against every other card to its right. This will run in O(n^2), but this is acceptable as long as the hand size stays at around 5.

Here is some code to do that:

for(i=0; i<5; i++)
{
  for(j=i+1; j<5; j++)
  {
    if(hand[i] == hand[j])
      return true;
  }
 }

Also, the reason your code is not working is because you're trying to access an index equal to the cards value, not what number the card is. You might be able to use a dictionary to do this, but the code above is a lot simpler to program and for such a small problem size, it is acceptable.

samoz
Oh, good call. I'll edit.
samoz
Beat me too it :-D
overstood
However, this doesn't take into account threes and four-of-a-kinds, as well as multiple pairs.
Smashery
Well he only asked about one pair.
samoz
I'm just guessing that when El Toro says "pair" he means in the poker sense rather than in the programming sense - in poker, three-of-a-kind is not considered a pair.
Smashery
Sorting the hand by rank descending helps with finding pairs, trips etc in one pass. The same pass could also then find straights and flushes. Looping through the hand once for each kind of hand is more prone to error.
jmucchiello
+1  A: 

I assume that you're looking for a pair as distinct from a three or four-of-a-kind. In that case, your best bet for that is to go through each of the cards, and store how many Aces, how many 2s, how many 3s, etc. there are. This solution will give you the number of pairs, as well as whether there's a three/four-of-a-kind or a full house. You would of course have to do different checking when looking for a flush or a straight.

Card[] hand = new Card[numberOfCards];
int[] frequencies = new int[13]; // there are 13 card values
...
for (int i = 0; i < hand.Count; i++)
{
    frequencies[hand[i].CardNumber] += 1; // assume Ace = 0, King = 12
}
// Now look through the frequencies:
int numberOfPairs = 0;
bool hasTriple = false;
bool hasFour = false;
for (int f = 0; j < frequencies.Count; j++)
{
    switch (frequencies[f])
    {
         case 2:
             numberOfPairs++;
             break;
         case 3:
             hasTriple = true;
             break;
         case 4:
             hasFour = true;
             break;
         default:
             break;
    }
}
// Now you know how many pairs you have, and whether you have a triple or four-of-a-kind
if (numberOfPairs == 1 && hasTriple)
{
    // It's a full house
}

EDIT: It would also be trivial to modify this to keep a record of what numbers constituted the pairs (pair of Aces or of Queens etc.)

Smashery
You would need to add in some checking to remove a pair if three of a kind is present, or remove three of a kind if four of a kind is present.
samoz
No, that's taken into account by design - you build up the frequencies first, and then check. So when you go through looking for pairs, you already know whether there are 0, 1, 2, 3 or 4 of them. There is then no confusion about whether it's a pair, three-of-a-kind, or four-of-a-kind.
Smashery
I think you left on the increment on the statement in your first for loop: `frequencies[hand[i].CardNumber]; // Has no effect`
Leonard
Cheers, Leonard. Fixed.
Smashery
+4  A: 

If you need this to be fast, you might want to consider re-evaluating your approach. Or, consider using an existing poker hand detection library, or at least studying the source to at least one of them for some 'inspiration'. Cactus Kev has a good writeup of his rather good 5 card hand detection algorithm:

You may also want to read http://www.codingthewheel.com/archives/how-i-built-a-working-online-poker-bot-8

Chris Lawlor
Wow that is a good link. He determines the hand rank in about 20 lines of code. amazing!
dotjoe
+1  A: 

How are you handling the suits of the deck? If you're representing the cards as simple ints, then I assume that the valid values of the cards are 0 - 51. If that's the case, then I guess cards 0 - 12 are all one suit, 13 - 25 are another, etc. Assignment of the suits can be arbitrary until you need to score hands that take it into account.

With this arrangement you can detect a pair just as samoz wrote, with a modification to your comparison operation. You'll need to make sure the cards are congruent modulo 13. Just change the line

if(hand[i] == hand[j])

to

if( (hand[i] % 13) == (hand[j] % 13) )

The modulus operator (%) returns the remainder after division, so

 0 % 13 = 0
 1 % 13 = 1
 2 % 13 = 2
    ...
12 % 13 = 12
13 % 13 = 0
14 % 14 = 1

and so on... It allows you to tell when a sequence wraps around a certain value, the modulus, in this case 13, since there are 13 different cards in each of four suits.

Let's say, for example, that in your deck of 52 cards numbered 0 - 51 that the cards 0 - 12 represent the Ace through King of clubs, cards 13 - 25 represent the hearts, 26 - 38 represent spades, and 39 - 51 represent diamonds.

Now you're dealt the hand: 0, 12, 32, 21, 47

By taking the remainder modulus 13 of each card you're left with 0, 12, 6, 8, 8

You can see that the last two cards are a pair, the 9 of hearts and the 9 of diamonds (remember the numbering starts at 0, so it's off by one).

Bill the Lizard
A: 

If you sort the hand then read it left to right it should be relatively easy to compute the hand strength.

If you are aiming for simplicity, you can try something like this (pseudocode):

def handStrength(hand):
    sort(hand) //sorts hand in ascending order
    if hasPair(hand):
        if isTwoPair(hand):
            return "two pair"
        else if isTrips(hand):
            return "three of a kind"
        else if isBoat(hand):
            return "full house"
        else if isQuads(hand):
            return "four of a kind"
        else:
            return "pair"
    else:
        straightFlag = isStraight(hand)
        flushFlag = isFlush(hand)
        if straightFlag:
            if flushFlag:
                return "straight flush"
            else:
                return "straight"
        else if flushFlag:
            return "flush"
        else:
            return "high card"

def hasPair(hand): //requires sorted hand
    for i = 1 to 4:
        if hand[i].rank == hand[i-1].rank:
            return True
    return False

def isTwoPair(hand): //requires sorted hand
    return (hand[0].rank == hand[1].rank and hand[2].rank == hand[3].rank and hand[0].rank != hand[2].rank) or
           (hand[1].rank == hand[2].rank and hand[3].rank == hand[4].rank and hand[1].rank != hand[3].rank)

def isTrips(hand): //requires sorted hand
    return (hand[0].rank == hand[2].rank and hand[0].rank != hand[3].rank and hand[3].rank != hand[4].rank) or
           (hand[1].rank == hand[3].rank and hand[0].rank != hand[1].rank and hand[0].rank != hand[4]) or
           (hand[2].rank == hand[4].rank and hand[1].rank != hand[2].rank and hand[1].rank != hand[0].rank)

def isBoat(hand): //requires sorted hand
    return (hand[0].rank == hand[1].rank and hand[2].rank == hand[3].rank == hand[4].rank) or
           (hand[0].rank == hand[1].rank == hand[2].rank and hand[3].rank == hand[4].rank)

def isQuads(hand): //requires sorted hand
    return hand[1].rank == hand[2].rank == hand[3].rank and (hand[0].rank == hand[1].rank or hand[4].rank == hand[1].rank)

def isStraight(hand): //requires sorted hand with no pair
    return (hand[0].rank == hand[4].rank - 4) or (isAce(hand[0]) and hand[4].rank == 5)

def isFlush(hand):
    return hand[0].suit == hand[1].suit == hand[2].suit == hand[3].suit == hand[4].suit
Imran
A: 

Checking for a pair and returning a boolean is pretty much useless. You need to check for the hands starting from the highest to lowest (straight flush, 4 kind, full house, flush, straight, etc...) and create a way to rank your hands so you can determine the winner. It is not trivial in my opinion.

dotjoe
A: 

Unconventional, but terse:

import fj.P;
import fj.data.Stream;
import static fj.P2.untuple;
import static fj.pre.Equal.intEqual;

public Stream<Integer> pairs(Stream<Integer> hand) {
  return hand.apply(hand.map(P.<Integer, Integer>p2()))
             .filter(untuple(intEqual.eq()))
             .map(P1.<Integer>__1());
}

Get the imported libraries here

Apocalisp
A: 

Complete source code for Texas hold'em poker game evaluator can be found here:

http://www.advancedmcode.org/poker-predictor.html

It is built for matlab, the GUI id m-coded but the computational engine is c++.

It allows for odds and probability calculation. It can deal, on my 2.4Ghz laptop, with a 100000 10 players game computation in 0,3 seconds.

An accurate real time computer:-)

Luigi Giaccari