-1

I've programatically determined hand rankings as added below. However, the issue is - if per say, two players end up with a pair.. How do I determine the winner?

To each card object I've added a prime number value. Ace being 41 and deuce being 3 and the in betweens. I'm thinking of multiplying these values when the hand is determined and whoever has the highest is winning. I need help determining whether this is the correct approach.

+(BOOL)isFull:(NSArray*)cards {
    Cards *card1 = [cards objectAtIndex:0];
    Cards *card2 = [cards objectAtIndex:1];
    Cards *card3 = [cards objectAtIndex:2];
    Cards *card4 = [cards objectAtIndex:3];
    Cards *card5 = [cards objectAtIndex:4];

    if (([card1.face isEqualToString:card3.face] && [card4.face isEqualToString:card5.face]) || ([card1.face isEqualToString:card2.face] && [card3.face isEqualToString:card5.face])) {
        return true;
    }
    return false;
}
+(BOOL)isFlush:(NSArray*)cards {
    NSMutableArray *organizedBySuit = [self organizeCardsSuitOrder:cards];

    Cards *card1 = [organizedBySuit objectAtIndex:0];
    Cards *card2 = [organizedBySuit objectAtIndex:4];

    if ([card1.suit isEqualToString:card2.suit]) {  return true; } else { return false; } // cards are organized by suit, so if the first equals the last..
}
+(BOOL)isStraight:(NSArray*)cards {
    Cards *card1 = [cards objectAtIndex:0];
    Cards *card2 = [cards objectAtIndex:1];
    Cards *card3 = [cards objectAtIndex:2];
    Cards *card4 = [cards objectAtIndex:3];
    Cards *card5 = [cards objectAtIndex:4];

    if ((card1.rankByInt) == 0 && (card2.rankByInt) == 9 && (card3.rankByInt) == 10 && (card4.rankByInt) == 11 && (card5.rankByInt) == 12) {
        return true;
    }
    else if ((card1.rankByInt) < 9) {
        if ((card2.rankByInt) == (card1.rankByInt) + 1) {
            if ((card3.rankByInt) == (card1.rankByInt) + 2) {
                if ((card4.rankByInt) == (card1.rankByInt) + 3) {
                    if ((card5.rankByInt) == (card1.rankByInt) + 4) {
                        return true;
                    }
                }
            }
        }
    }

    return false;
}
+(BOOL)isTrip:(NSArray*)cards {
    NSArray *faces = [self returnArrayOfFaces];

    __block int pairCounter = 0;
    for (int i = 0; i < [faces count]; i++) {
        for (int t = 0; t < [cards count]; t++) {
            Cards *card = [cards objectAtIndex:t];
            if ([card.face isEqualToString:faces[i]]) {
                pairCounter++;
            }
        }
        if (pairCounter > 2) {
            return true;
        }
        pairCounter = 0;
    }
    return false;
}
+(BOOL)isTwoPair:(NSArray*)cards {
    NSArray *faces = [self returnArrayOfFaces];

    __block int pairCount = 0;
    __block int doublePairCount = 0;

    for (int i = 0; i < [faces count]; i++) {
        for (int t = 0; t < [cards count]; t++) {
            Cards *card = [cards objectAtIndex:t];
            if ([card.face isEqualToString:faces[i]]) {
                pairCount++;
            }
        }
        if (pairCount > 1) {
            doublePairCount++;
        }
        pairCount = 0;
    }
    if (doublePairCount > 1) {
        return true;
    }

    return false;
}
+(BOOL)isPair:(NSArray*)cards {
    NSArray *faces = [self returnArrayOfFaces];

    __block int pairCounter = 0;
    for (int i = 0; i < [faces count]; i++) {
        for (int t = 0; t < [cards count]; t++) {
            Cards *card = [cards objectAtIndex:t];
            if ([card.face isEqualToString:faces[i]]) {
                pairCounter++;
            }
        }
        if (pairCounter > 1) {
            return true;
        }
        pairCounter = 0;
    }

    return false;
}

And the cards are generated to include their primes here.

+(NSMutableArray*)createDeck:(id)sender {
    [sender removeAllObjects];
    NSArray *faces = [[NSArray alloc] initWithObjects:@"A",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"J",@"Q",@"K", nil];
    NSArray *suits = [[NSArray alloc] initWithObjects:@"h",@"d",@"c",@"s", nil];
    NSArray *primes = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:41],[NSNumber numberWithInt:2],[NSNumber numberWithInt:3],[NSNumber numberWithInt:5],[NSNumber numberWithInt:7],[NSNumber numberWithInt:11],[NSNumber numberWithInt:13],[NSNumber numberWithInt:17],[NSNumber numberWithInt:19],[NSNumber numberWithInt:23],[NSNumber numberWithInt:29],[NSNumber numberWithInt:31],[NSNumber numberWithInt:37], nil];
    for (int i = 0; i < 52; i++) {
        Cards *card = [[Cards alloc]init];
        card.face = [NSString stringWithFormat:@"%@", faces[i % 13]];
        card.suit = [NSString stringWithFormat:@"%@", suits[i / 13]];
        card.rankByInt = i % 13;
        card.symbol = [Cards symbolForSuit:card.suit];
        card.prime = [[primes objectAtIndex:(i % 13)] intValue];

        [sender addObject:card];
    }
    [sender shuffle];

    return sender;
}

So if possible can you provide me with the way to go forward to essentially 'rank' each hand by the cards values after I have retrieved their rank such as flush, straight etc..

Also, if you see any ways to improve the efficiency of my checks for hand ranks, please share.

Daniel
  • 31
  • 4
  • I think what you need is a website that describes poker rules. This is primarily not a programming problem but a problem of your (or the players) expectations. Generally, if two people have a similar hand, the one with the higher valued cards wins. – PMF Feb 08 '18 at 16:14
  • @PMF I understand what you are saying. However, where the programming comes from is more structure. Where to determine the more dominant hand using prime numbers as well as how to approach it. I get what you're saying, it's more a mathematical problem. – Daniel Feb 08 '18 at 16:16
  • I don't know what you need the prime numbers for. Just assign every card a value (2-10, B, Q, K, Ace gets 14). In some variants, ace may also be counted as 1. – PMF Feb 08 '18 at 16:23
  • @PMF The issue comes when say, one player has A9 and the other player has 2 10, if they both have one pair 10 and 9 , if you added the cards values the incorrect winner would be determined. So I need a way to combat that. Primes may not be the best way, that is why I am asking. – Daniel Feb 08 '18 at 16:27
  • Ok, I think I got it. You need to evaluate the "hand type" first, that's the rules. So _only if_ the two players have the same type of hand (i.e 2 pairs) the value of the cards matters. – PMF Feb 08 '18 at 16:32
  • @PMF Basically yes, it's more efficient to determine a winner by "Hand Type" than it is to essentially "Calculate" their hand as well. Only when two or more players have the same hand I need an efficient way to determine the winner. I don't want to go down an avenue of `if pair of twos` `if two par with twos and threes` it would just be a mess. – Daniel Feb 08 '18 at 16:35
  • You don't need to do that, of course. Just assign the hands values as well. And I think your code could already use some improved design. That's way to many nested ifs. – PMF Feb 08 '18 at 16:43
  • Seems like a simple problem, am I missing something? If two players both have a pair, and the cards are ranked with prime numbers in ascending order, than it's as simple as comparing the sum of the pairs and awarding the higher sum. – inorganik Feb 08 '18 at 17:00
  • @inorganik Essentially yes; it's not that great of a problem. I just want to know if the way I'm approaching it will account for every scenario. Before I waste my time programming it only to realise in the very odd eventuality it does not add up. For instance when the kicker comes into play or when you have a flush of A2 and they have KQ their primes will be higher than the A2. There's a lot of eventualities where it can mess up based on math and I want a simple approach if there is one. – Daniel Feb 08 '18 at 17:17
  • 1
    Google "poker hand evaluator". You prime-number technique is similar to one called the "Cactus Kev" algorithm. – Lee Daniel Crocker Feb 08 '18 at 18:45

1 Answers1

1

First evaluate the hand type. If those are equal, compare the highest card that makes up the hand (unless it's a full house, then compare the set). If all cards in the hand type are equal, and the hand type is less than 5 cards, compare the next highest card in the 5 card hand. Only if the best combination of 5 cards are equal between two hands do the hands tie.

I wrote a poker hand generator and strength comparer in python that may be of some interest to you: https://github.com/Alec-ala/poker-stud-showdown

Alec
  • 8,529
  • 8
  • 37
  • 63