Блэкджек

Или — Как программирование не сделало меня богатым

Я твердо верю в то, что нужно быть ленивым. Так было, когда я приступал к своему последнему проекту.

«Программирование — это погоня за ленью» — Some Wise Developer

Идея

Блэкджек — это веселое времяпрепровождение, которым я люблю заниматься в местах, которые позволяют мне это делать. Как и у большинства людей, которые играли в азартные игры, у меня была фантазия о том, что однажды ночью я действительно пойду ва-банк и уйду богатым человеком.

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

Выполнение

*** Примечание. Основные функции, которые я использовал для этого, включены в конец этой статьи ***

Я начал с создания эмулятора Блэк Джека, написав функции для: перетасовки колоды, раздачи карт, ударов, пребывания и требований дилера попасть/остаться. Это было довольно просто, так как я сохранил колоду и каждую из рук в массивах, а затем имел функцию для подсчета очков каждой руки.

Это был отличный первый шаг, но я хотел смоделировать 1000 раздач и протестировать различные методы раздачи игрока и стратегию ставок. Поэтому я придумал анализатор строк, чтобы легко написать каждую стратегию как одну строку. Я придумал это:

// Dealers top card > six? | Hit while your hand is under 17
d>6|hitunder17
// Dealers top card < 7 | Hit while your hand is under 12
d<7|hitunder12
// Dealer's top card > 6 | Double down if you have 11
d>6|double11

И так далее. Таким образом, я мог бы добавить эти строки в массив и перебрать их все, моделируя каждую стратегию столько раз, сколько мне нужно, и видеть результат каждой из них.

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

Результаты

Итак, с гипотетическим банкроллом в 500 долларов и гипотетической минимальной ставкой в ​​5 долларов. Вот мои результаты по каждой стратегии за тысячу раздач:

  1. Всегда удваивать ставку на 11; Если у дилера 7 или выше, берите до тех пор, пока рука не станет 16 или выше; Если у дилера 6 или меньше, (Пусть дилер разорится) бить до тех пор, пока рука не станет больше 11.
    Выиграл 43,92% рук, проиграл 125 долларов.
  2. Всегда удваивайте ставку на 10, 11; Если у дилера 7 или выше, берите до тех пор, пока рука не станет 17 или выше; Если у дилера 6 или меньше, (Пусть дилер разорится) берите до тех пор, пока рука не превысит 11.
    Выиграл 45,20% рук, проиграл 69 долларов.
  3. Без удвоения. Дилер 7 или выше, берите до тех пор, пока рука не станет 16 или выше; Дилер 6 или ниже, играйте до тех пор, пока рука не станет 12 или лучше.
    Выиграл 44,83% рук, проиграл 110 долларов
  4. То же, что и №1, но не забирайте выигрыш, пока не выиграете 3 раздачи подряд.
    Выиграл 45% раздач, проиграл 31 доллар
  5. То же, что и № 2, но не забирайте выигрыш, пока не выиграете 3 раздачи подряд.
    Выиграл 43,45% раздач, проиграл $293
  6. То же, что и №3, но не забирайте выигрыши, пока не выиграете 3 раздачи подряд.
    Выиграл 42,3% раздач, проиграл 307 долларов

Забрать

Вы не можете запрограммировать себя на то, чтобы стать очень успешным игроком в блэкджек. По крайней мере, я не могу. Однако написание кода для проверки этого сэкономило мне бессчетное количество часов и денег. Если бы я протестировал эти руки в казино, я бы потерял 935 долларов, бессчетное количество часов и свое достоинство.

Функции, используемые в этом проекте

shuffle(cards) {
    for(var i = 0; i < 30; i++) {
        var rndNo = this.getRandomInt(1, 52)
        var card = cards[i]
        cards[i] = cards[rndNo-1]
        cards[rndNo-1] = card
    }
    return cards
}
getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min
}
generateDeck() {
    let suits = ['Hearts', 'Spades', 'Clubs', 'Diamonds']
    let values = ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K']
    for (let suit in suits) {
        for (let value in values) {
            this.cards.push(values[value])
        }
    }
}
score(hand) {
    let score = 0
    if(hand.length >= 2){
        hand.forEach(v => {
            score += this.cardScore(v)
        })
    }
    if(score > 21) {
        let ace = hand.indexOf('A')
        if(ace > -1){
            hand[ace] = 1
            return this.score(hand)
        }
    }
    
    return score
}
cardScore(card) {
    if(card === 'A'){
        return 11
    }
    return ['J', 'Q', 'K'].indexOf(card) > -1) ? 10 : card
}

Не играйте на деньги, которые вы готовы проиграть!

Пока ты здесь. Подпишитесь на меня в твиттере!

https://twitter.com/andyhartnett12