Есть ли более проще, чем это рассчитать прямую в покер?

StackOverflow https://stackoverflow.com/questions/4004856

  •  25-09-2019
  •  | 
  •  

Вопрос

У меня есть алгоритм для расчета того, держат руку игрока прямо в Техасском Холдеме. Работает нормально, но мне интересно, есть ли более простой способ сделать это, что не связано с преобразованиями массива / строки и т. Д.

Вот упрощенная версия того, что у меня есть. Скажем, игрок наносят руку, которая представляет собой 52-элементный массив значений карты:

var rawHand = [1,0,0,0,0,0,0,0,0,0,0,0,0, //clubs
               0,0,0,0,0,0,0,0,0,0,0,0,0, //diamonds
               0,1,1,0,1,0,0,0,0,0,0,0,0, //hearts
               0,0,0,1,0,0,0,0,1,0,0,0,0];//spades

A 1 представляет собой карту в этом слоте значения. Вышеуказанная рука имеет 2-х клуб, без бриллиантов, 3-х сердец, 4-х сердец и 6-сердец, 5-пики и 10-пики. Теперь я смотрю на это, чтобы найти прямо.

var suits = []; //array to hold representations of each suit

for (var i=0; i<4; i++) {
    var index = i*13;
    // commenting this line as I removed the rest of its use to simplifyy example
    //var hasAce = (rawHand[i+13]);

    //get a "suited" slice of the rawHand, convert it to a string representation
    //of a binary number, then parse the result as an integer and assign it to
    //an element of the "suits" array
    suits[i] = parseInt(rawHand.slice(index,index+13).join(""),2);
}

// OR the suits    
var result = suits[0] | suits[1] | suits[2] | suits[3];

// Store the result in a string for later iteration to determine
// whether straight exists and return the top value of that straight
// if it exists; we will need to determine if there is an ace in the hand
// for purposes of reporting a "low ace" straight (i.e., a "wheel"),
// but that is left out in this example
var resultString = result.toString(2);

//Show the result for the purposes of this example
alert("Result: " + resultString);

Хитрость здесь - это или различные костюмы, так что есть всего одна 2-азотная представление. Я ошибаюсь, думая, что должен быть более простой способ сделать это?

Это было полезно?

Решение

Почти все работы ваш код делает преобразование типа. Если бы у вас просто была рука, хранящаяся в битном формате, чтобы начать с (потребностей> 32 бита), вы можете сделать что-то вроде:

var mask = 2^13 - 1; // this will zero out all but the low 13 bits
var suits = (rawHand | rawHand>>13 | rawHand>>26 | rawHand>>39) & mask;

Эквивалент с использованием одной линии цикла будет:

var suits = [];
for(var i=0; i < 13; i++) {
   suits[i] = rawHand[i] || rawHand[i+13] || rawHand[i+26] || rawHand[i+39];
}

Это намного короче и легче понять.

Преобразование в и из немного мудрого представления требует большего количества кода и процессора, чем вы сохраняете, используя бидж или оператор или оператор.

Другие советы

Ну, прямой должен включать в себя 5 или 10, поэтому вы можете начать сбрасывать руку, если у него нет ни одного или другого:

if (rawHand[3] || rawHand[16] || rawHand[29] || rawHand[42] ||
    rawHand[8] || rawHand[21] || rawHand[34] || rawHand[47]) {
  // do some more checks
} else {
  // not a straight
}

Вы можете использовать целочисленное значение в качестве битового поля для значений карты, ACE получает два пятна низких и высоких пятен. Затем вы сравниваете с побитовым концом на десять возможных прямых.

Или используйте для петли и проверьте на пять последовательных чисел - эффективно это все равно.

Этот вопрос заинтересовал меня. Я закончил идти за бортом. И написал веб-страницу для расчета любой руки. Это, вероятно, не самый эффективный, но он работает. Я сделал это только с JavaScript (нет jQuery). Вот демонстрация http://jsbin.com/izuto4/2/

Ниже приведен код:

<html>
<head>
<script>
   // var myrawHand = [1,0,0,0,0,0,0,0,0,0,0,0,0, //clubs
   // 0,0,0,0,0,0,0,0,0,0,0,0,0, //diamonds
   // 0,1,1,0,1,0,0,0,0,0,0,0,0, //hearts
   // 0,0,0,1,0,0,0,0,0,0,0,0,0];//spades

    function getCardsInHand(rawHand) {
        var cardsInHand = new Array();
        var counter = 0;
        for (var i = 0; i < rawHand.length; i ++) {
            if (rawHand[i]) {
                cardsInHand[counter] = i;
                counter ++;
            }
        }
        return cardsInHand;
    }

    function cardsfiltered(rawHand) {
        var cards = getCardsInHand(rawHand)

        var cardsfiltered = new Array();
        for (var j = 0; j < cards.length; j ++){
            cardsfiltered[j] = cards[j] - (parseInt(cards[j] / 13) * 13);
        }
        cardsfiltered.sort();
        return {cards : cards, cardsfiltered : cardsfiltered};
    }

    function whatIsMyHand(rawHand) {
        var cardObject = cardsfiltered(rawHand);
        if (((cardObject.cards[0] == 0 && cardObject.cards[1] == 9)
                || (cardObject.cards[0] == 13 && cardObject.cards[1] == 22)
                || (cardObject.cards[0] == 26 && cardObject.cards[1] == 35)
                || (cardObject.cards[0] == 39 && cardObject.cards[1] == 48))
                && cardObject.cards[4] == cardObject.cards[3] + 1 &&
                cardObject.cards[3] == cardObject.cards[2] + 1 &&
                cardObject.cards[2] == cardObject.cards[1] + 1) {
            return "Royal Flush";
        }
        else if (cardObject.cards[4] == cardObject.cards[3] + 1 &&
                cardObject.cards[3] == cardObject.cards[2] + 1 &&
                cardObject.cards[2] == cardObject.cards[1] + 1 &&
                cardObject.cards[1] == cardObject.cards[0] + 1) {
            return "Straight Flush";
        }
        else if ((cardObject.cardsfiltered[1] == cardObject.cardsfiltered[2]
                && cardObject.cardsfiltered[2] == cardObject.cardsfiltered[3])
                && (cardObject.cardsfiltered[0] == cardObject.cardsfiltered[1]
                || cardObject.cardsfiltered[3] == cardObject.cardsfiltered[4])) {
            return "Four of a Kind";
        }
        else if ((cardObject.cardsfiltered[0] == cardObject.cardsfiltered[1]
                && cardObject.cardsfiltered[1] == cardObject.cardsfiltered[2]
                && cardObject.cardsfiltered[3] == cardObject.cardsfiltered[4])
                || (cardObject.cardsfiltered[0] == cardObject.cardsfiltered[1]
                && cardObject.cardsfiltered[2] == cardObject.cardsfiltered[3]
                && cardObject.cardsfiltered[3] == cardObject.cardsfiltered[4])) {
            return "Full House";
        }
        else if (parseInt(cardObject.cards[0] / 13) == parseInt(cardObject.cards[1] / 13)
                && parseInt(cardObject.cards[0] / 13) == parseInt(cardObject.cards[2] / 13)
                && parseInt(cardObject.cards[0] / 13) == parseInt(cardObject.cards[3] / 13)
                && parseInt(cardObject.cards[0] / 13) == parseInt(cardObject.cards[4] / 13)) {
            return "Flush";
        }
        else if ((cardObject.cardsfiltered[4] == cardObject.cardsfiltered[3] + 1
                && cardObject.cardsfiltered[3] == cardObject.cardsfiltered[2] + 1
                && cardObject.cardsfiltered[2] == cardObject.cardsfiltered[1] + 1
                && cardObject.cardsfiltered[1] == cardObject.cardsfiltered[0] + 1)
                || (cardObject.cardsfiltered[0] == 0
                && cardObject.cardsfiltered[1] == 10
                && cardObject.cardsfiltered[2] == 11
                && cardObject.cardsfiltered[3] == 12
                && cardObject.cardsfiltered[4] == 9)) {
            return "Straight";
        }
        else if ((cardObject.cardsfiltered[0] == cardObject.cardsfiltered[1]
                && cardObject.cardsfiltered[1] == cardObject.cardsfiltered[2])
                || (cardObject.cardsfiltered[1] == cardObject.cardsfiltered[2]
                && cardObject.cardsfiltered[2] == cardObject.cardsfiltered[3])
                || (cardObject.cardsfiltered[2] == cardObject.cardsfiltered[3]
                && cardObject.cardsfiltered[3] == cardObject.cardsfiltered[4])) {
            return "Three of a Kind";
        }
        else if ((cardObject.cardsfiltered[0] == cardObject.cardsfiltered[1]
                && (cardObject.cardsfiltered[2] == cardObject.cardsfiltered[3]
                || cardObject.cardsfiltered[3] == cardObject.cardsfiltered[4]))
                || (cardObject.cardsfiltered[1] == cardObject.cardsfiltered[2]
                && cardObject.cardsfiltered[3] == cardObject.cardsfiltered[4])) {
            return "Two Pair"
        }
        else if (cardObject.cardsfiltered[0] == cardObject.cardsfiltered[1]
                || cardObject.cardsfiltered[1] == cardObject.cardsfiltered[2]
                || cardObject.cardsfiltered[2] == cardObject.cardsfiltered[3]
                || cardObject.cardsfiltered[3] == cardObject.cardsfiltered[4]) {
            return "Pair";
        }
        else {
            return "High Card";
        }
    }
    var CardCheckCount = 0;
    function MaxCardCheck(element) {
        if (element.checked) {
            if (CardCheckCount < 5) {
                CardCheckCount++;
                return true;
            }
        }
        else {
            CardCheckCount--;
            return true;
        }
        element.checked = !element.checked;
        alert("You can only pick 5 cards.");
        return false;
    }

    function calculateHand() {
        var checkboxes = document.getElementsByTagName("input");
        var myrawHand = new Array();
        for (var i = 0, element; element = checkboxes[i]; i++) {
          myrawHand[parseInt(element.name)] = element.checked ? element.value : 0;
        }
        alert(whatIsMyHand(myrawHand));
    }
</script>
</head>
<body>
<table>
    <thead>
        <tr>
            <td>&nbsp;A</td>
            <td>&nbsp;2</td>
            <td>&nbsp;3</td>
            <td>&nbsp;4</td>
            <td>&nbsp;5</td>
            <td>&nbsp;6</td>
            <td>&nbsp;7</td>
            <td>&nbsp;8</td>
            <td>&nbsp;9</td>
            <td>10</td>
            <td>&nbsp;J</td>
            <td>&nbsp;Q</td>
            <td>&nbsp;K</td>
            <td>&nbsp;</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><input name="0" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="1" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="2" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="3" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="4" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="5" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="6" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="7" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="8" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="9" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="10" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="11" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="12" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td>Clubs</td>
        </tr>
        <tr>
            <td><input name="13" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="14" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="15" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="16" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="17" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="18" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="19" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="20" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="21" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="22" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="23" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="24" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="25" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td>Diamonds</td>
        </tr>
        <tr>
            <td><input name="26" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="27" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="28" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="29" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="30" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="31" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="32" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="33" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="34" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="35" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="36" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="37" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="38" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td>Hearts</td>
        </tr>
        <tr>
            <td><input name="39" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="40" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="41" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="42" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="43" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="44" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="45" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="46" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="47" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="48" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="49" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="50" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td><input name="51" type="checkbox" value="1" onclick="MaxCardCheck(this);"/></td>
            <td>Spades</td>
        </tr>
    </tbody>
</table>
<button onclick="calculateHand()">Calculate Hand</button>
</body>
</html>

Нет, это так просто, как он получает. Я посмотрел в покерную оценку рук некоторое время назад, и я думаю, что самый быстрый способ использует подход, как ваш. Увидеть первый результат в этот сайт. Отказ Он использует побитовые операции для вычисления рук.

Редактировать: По первому результату я имею в виду «Pokerource Poker-Eval Evailuator».

Почему бы не сортировать карты по рейтингу, а затем убедитесь, что каждый ранг - это еще один, чем предыдущий. «Ранги» - это массив длины 5 с ACE = 1, 2 = 2, ... j = 11, q = 12, k = 13. Я думаю, что это проще, чем другие методы, представленные здесь.

function isStraight( ranks) {
  ranks.sort();
  return (ranks[0] + 1 == ranks[1] || (ranks[0] == 1 && ranks[4] == 13)) &&
         (ranks[1] + 1 == ranks[2]) &&
         (ranks[2] + 1 == ranks[3]) &&
         (ranks[3] + 1 == ranks[4]);
}

Вы можете использовать 7-карту Sensek и 5-карточный оценщик здесь И попросите это ранжировать руки. Если ранг, который возвращается, составляет от 5854 до 5863 (как включено), либо между 7453 и 7462 (как включительно), то ваша рука, будь то 5 или 7 карт, соответственно или содержит прямую.

Обратите внимание, что туз пик обозначается на 0, туз сердца к 1, через два клуба, которые представлены 51. Алгоритм будет «добавить» свои карты и посмотреть ранг в небольшом столе, занимаясь 9 МБ ОЗУ. Это также сделает намного больше, но эй ...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top