Блэкджек
Или — Как программирование не сделало меня богатым
Я твердо верю в то, что нужно быть ленивым. Так было, когда я приступал к своему последнему проекту.
«Программирование — это погоня за ленью» — 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 долларов. Вот мои результаты по каждой стратегии за тысячу раздач:
- Всегда удваивать ставку на 11; Если у дилера 7 или выше, берите до тех пор, пока рука не станет 16 или выше; Если у дилера 6 или меньше, (Пусть дилер разорится) бить до тех пор, пока рука не станет больше 11.
Выиграл 43,92% рук, проиграл 125 долларов. - Всегда удваивайте ставку на 10, 11; Если у дилера 7 или выше, берите до тех пор, пока рука не станет 17 или выше; Если у дилера 6 или меньше, (Пусть дилер разорится) берите до тех пор, пока рука не превысит 11.
Выиграл 45,20% рук, проиграл 69 долларов. - Без удвоения. Дилер 7 или выше, берите до тех пор, пока рука не станет 16 или выше; Дилер 6 или ниже, играйте до тех пор, пока рука не станет 12 или лучше.
Выиграл 44,83% рук, проиграл 110 долларов - То же, что и №1, но не забирайте выигрыш, пока не выиграете 3 раздачи подряд.
Выиграл 45% раздач, проиграл 31 доллар - То же, что и № 2, но не забирайте выигрыш, пока не выиграете 3 раздачи подряд.
Выиграл 43,45% раздач, проиграл $293 - То же, что и №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 }
Не играйте на деньги, которые вы готовы проиграть!