0

first question ever here... I am coding a simple 3-card poker hand evaluator and am having problems finding/extracting multiple "straights" (sequential series of values) from an array of values.

I need to extract and return EVERY straight the array possibly has. Here's an example:

(assume array is first sorted numerically incrementing)

myArray = [1h,2h,3c,3h,4c]

Possible three-value sequences are: [1h,2h,3c] [1h,2h,3h] [2h,3c,4c] [2h,3h,4c]

Here is my original code to find sequences of 3, where the array contains card objects with .value and .suit. For simplicity in this question I just put "2h" etc here:

private var _pokerHand = [1h,2h,3c,3h,4c];
private function getAllStraights(): Array 
{
    var foundStraights:Array = new Array();
    for (var i: int = 0; i < (_handLength - 2); i++) 
    {
        if ((_pokerHand[i].value - _pokerHand[i + 1].value) == 1 && (_pokerHand[i + 1].value - _pokerHand[i + 2].value) == 1) 
        {
            trace("found a straight!");
            foundStraights.push(new Array(_pokerHand[i], _pokerHand[i + 1], _pokerHand[i + 2]));
        }
    }
    return foundStraights;
}

but it of course fails when there are value duplicates (like the 3's above). I cannot discard duplicates because they could be of different suits. I need every possible straight as in the example above. This allows me to run the straights through a "Flush" function to find "straight flush".

What array iteration technique am I missing?

LilGames
  • 89
  • 1
  • 10
  • I think I may have found an alternate solution. I should first be checking for Straight Flushes by sorting by Suit and discarding duplicate cards (temporarily). If a Straight Flush is not found, then I can check for Straights, again using the duplicate discard method. Suits don't matter at this point. – LilGames Mar 20 '16 at 15:21

1 Answers1

1

This is an interesting problem. Given the popularity of poker games (and Flash) I'm sure this has been solved many times before, but I couldn't find an example online. Here's how I would approach it:

  • Look at it like a path finding problem.
  • Begin with every card in the hand as the start of a possible path (straight).
  • While there are possible straights:
    • Remove one from the list.
    • Find all the next valid steps, (could be none, or up to 4 following cards with the same value), and for each next valid step:
      • If it reaches the goal (completes a straight) add it to a list of found straights.
      • Otherwise add the possible straight with the next step back to the stack.

This seems to do what you want (Card object has .value as int):

private function getAllStraights(cards:Vector.<Card>, straightLength:uint = 3):Vector.<Vector.<Card>> {
    var foundStraights:Vector.<Vector.<Card>> = new <Vector.<Card>>[];

    var possibleStraights:Vector.<Vector.<Card>> = new <Vector.<Card>>[];
    for each (var startingCard:Card in cards) {
        possibleStraights.push(new <Card>[startingCard]);
    }

    while (possibleStraights.length) {
        var possibleStraight:Vector.<Card> = possibleStraights.shift();
        var lastCard:Card = possibleStraight[possibleStraight.length - 1];
        var possibleNextCards:Vector.<Card> = new <Card>[];
        for (var i:int = cards.indexOf(lastCard) + 1; i < cards.length; i++) {
            var nextCard:Card = cards[i];
            if (nextCard.value == lastCard.value)
                continue;
            if (nextCard.value == lastCard.value + 1)
                possibleNextCards.push(nextCard);
            else
                break;
        }
        for each (var possibleNextCard:Card in possibleNextCards) {
            var possibleNextStraight:Vector.<Card> = possibleStraight.slice().concat(new <Card>[possibleNextCard]);
            if (possibleNextStraight.length == straightLength)
                foundStraights.push(possibleNextStraight);
            else
                possibleStraights.push(possibleNextStraight);
        }
    }

    return foundStraights;
}

Given [1♥,2♥,3♣,3♥,4♣] you get: [1♥,2♥,3♣], [1♥,2♥,3♥], [2♥,3♣,4♣], [2♥,3♥,4♣]

It gets really interesting when you have a lot of duplicates, like [1♥,1♣,1♦,1♠,2♥,2♣,3♦,3♠,4♣,4♦,4♥]. This gives you:

[1♥,2♥,3♦], [1♥,2♥,3♠], [1♥,2♣,3♦], [1♥,2♣,3♠], [1♣,2♥,3♦], [1♣,2♥,3♠], [1♣,2♣,3♦], [1♣,2♣,3♠], [1♦,2♥,3♦], [1♦,2♥,3♠], [1♦,2♣,3♦], [1♦,2♣,3♠], [1♠,2♥,3♦], [1♠,2♥,3♠], [1♠,2♣,3♦], [1♠,2♣,3♠], [2♥,3♦,4♣], [2♥,3♦,4♦], [2♥,3♦,4♥], [2♥,3♠,4♣], [2♥,3♠,4♦], [2♥,3♠,4♥], [2♣,3♦,4♣], [2♣,3♦,4♦], [2♣,3♦,4♥], [2♣,3♠,4♣], [2♣,3♠,4♦], [2♣,3♠,4♥]

I haven't checked this thoroughly but it looks right at a glance.

Aaron Beall
  • 49,769
  • 26
  • 85
  • 103