Как найти все последовательности из трех в массиве значений

первый вопрос здесь ... Я кодирую простой оценщик покерных рук с 3 картами, и у меня возникают проблемы с поиском / извлечением нескольких «стритов» (последовательных серий значений) из массива значений.

Мне нужно извлечь и вернуть КАЖДЫЙ прямой массив, который, возможно, имеет. Вот пример:

(предполагается, что массив сначала отсортирован по числовому приращению)

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

Возможные последовательности из трех значений: [1h,2h,3c] [1h,2h,3h] [2h,3c,4c] [2h,3h,4c]

Вот мой исходный код для поиска последовательностей из 3, где массив содержит объекты карт с .value и .suit. Для простоты в этом вопросе я просто поставил здесь «2h» и т. д.:

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;
}

но это, конечно, терпит неудачу, когда есть дубликаты значений (например, 3 выше). Я не могу отбрасывать дубликаты, потому что они могут быть разных мастей. Мне нужны все возможные прямые, как в примере выше. Это позволяет мне запускать стриты через функцию «Flush», чтобы найти «стрит-флеш».

Какой метод итерации массива мне не хватает?


person LilGames    schedule 19.03.2016    source источник
comment
Я думаю, что, возможно, нашел альтернативное решение. Сначала я должен проверить наличие стрит-флешей, отсортировав их по масти и отбросив дубликаты карт (временно). Если стрит-флеш не найден, я могу проверить наличие стритов, снова используя метод дублирующего сброса. Костюмы в данном случае не имеют значения.   -  person LilGames    schedule 20.03.2016


Ответы (1)


Это интересная проблема. Учитывая популярность покерных игр (и Flash), я уверен, что эта проблема уже решалась много раз, но я не смог найти пример в Интернете. Вот как бы я подошел к этому:

  • Посмотрите на это как на задачу поиска пути.
  • Начните с каждой карты в руке как начала возможного пути (стрита).
  • 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.
      • В противном случае добавьте возможный стрит со следующим шагом обратно в стек.

Кажется, это делает то, что вы хотите (Card объект имеет .value как 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;
}

Учитывая [1♥,2♥,3♣,3♥,4♣], вы получаете: [1♥,2♥,3♣], [1♥,2♥,3♥], [2♥,3♣,4♣], [2♥,3♥,4♣]

Становится действительно интересно, когда у вас много дубликатов, например [1♥,1♣,1♦,1♠,2♥,2♣,3♦,3♠,4♣,4♦,4♥]. Это дает вам:

[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♥]

Я не проверял это полностью, но на первый взгляд это выглядит правильно.

person Aaron Beall    schedule 21.03.2016
comment
Спасибо! Мне нужно проверить, но пока отмечу как правильное. - person LilGames; 23.03.2016