Большинство профессиональных игроков в азартные игры пользуются всем арсеналом комбинаторики, статистики и теории вероятностей. Чтобы показать, как это происходит в жизни, нам нужен пример, на котором мы сможем проверить все гипотезы и убедиться в их правильности (или опровергнуть их).
Для этого мы сегодня напишем игру на Python в блек-джек, или двадцать одно, — и на примере этой игры дальше будем показывать, как статистика работает в пользу игрока (или казино). Правила игры довольно просты:
- Есть колода из 54 карт, масти неважны. В казино используют сразу до 8 колод, перемешивая их друг с другом.
- Каждому игроку сдаётся в открытую по две карте, раздающему (крупье) — одна карта.
- Карты с цифрами от 2 до 10 дают номинальное число очков (от 2 до 10), картинка — 10 очков, туз — 11 очков (или одно, если на руке больше 11 очков).
- Цель игры — набрать как можно больше очков, но не больше 21. Если получается больше 21 — игрок автоматически проиграл.
- Игрок смотрит свою карту и принимает решение, взять ещё или ему хватит. После каждой взятой карты игрок смотрит на сумму очков и решает, будет брать ещё или нет.
- Когда игрок останавливается, крупье сдаёт себе карты по той же схеме.
- Если у игрока больше очков, чем у крупье, то он выиграл. Если очков больше у крупье — выиграл он.
Как это будет выглядеть:
Если вы ещё не писали программы на Python, начните с этого, дальше будет проще:
Что делаем
Для простоты наша игра будет устроена по таким правилам:
- Один игрок играет против раздающего.
- В начале игры раздающий сдаёт игроку две карты.
- Игрок может добрать дополнительную карту или остановиться на той комбинации, что у него уже есть.
- Когда игрок остановился, раздающий получает право хода и сдаёт себе две карты.
- Если раздающий набирает меньше 16 очков, он обязан взять ещё одну карту. Если 17 и больше — должен остановиться и подсчитать очки.
- Выигрывает тот, у кого больше очков, но не более 21.
В блек-джеке используют от одной до восьми колод карт. Чем больше колод, тем ниже вероятность набрать 21 очко, то есть блек-джек. Чтобы играть было интереснее, мы будем предлагать игроку выбрать, сколько колод будет участвовать в игре.
Считать очки будем так:
- масть не учитывается;
- карты от 2 до 10 считаются по своему номиналу: двойка даёт 2 очка, десятка — 10;
- валет, дама и король считаются за 10 очков;
- туз даёт 1 очко, если на руке больше 11 очков, и 11 — если меньше.
Что понадобится
Вся игра будет реализована встроенными средствами Python без внешних библиотек.
Модуль os добавляет возможности для работы с операционной системой. Нам он понадобится, чтобы задать оформление вывода программы в консоли.
Модуль random нужен для работы со случайными значениями. С его помощью мы будем перемешивать карты.
Списки — упорядоченные коллекции элементов, в которые мы будем складывать карты. У нас будет три списка: один для общей колоды и по одному для карт игрока и раздающего. Элементы списка пронумерованы, и их можно изменять — например, добавить карту на руку игроку. Списки обозначаются квадратными скобками:
deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Цикл — это инструкция, которая повторяет выполнение блока кода несколько раз для достижения задачи. В цикле for
перебираются элементы последовательности, а цикл while
выполняется до тех пор, пока указанное условие остаётся истинным. Мы будем использовать обе конструкции, например с помощью for
проходить по элементам списка в порядке их нумерации.
Проверка условий if, elif и else. Скрипт будет работать после проверки условий. Например, если у игрока на руке туз и валет, то у него блек-джек и он выиграл. Если комбинация карт не даёт блек-джек, то скрипт спросит, что игрок хочет делать дальше — добирать карту или передавать ход раздающему.
Управляющие последовательности ANSI — это специальные символы, с помощью которых можно настраивать внешний вид вывода в консоли: выделить текст другим цветом или жирным и выбрать фон для текста. Управляющие последовательности используются внутри строк кода, начинаются с обратной косой черты \
и составляются по таким правилам:
- Начинаются с символа ESC, который обозначается как
\x1b[
,\u001b[
или\033[
. - После этого идёт основная структура. Если параметров несколько, они указываются через точку с запятой.
- Последовательность заканчивается буквой
m
. Она указывает, что параметры применяются к тексту. - Чтобы вернуть остальному тексту стандартное форматирование, указывают последовательность сброса параметров
\033[0m
.
Например, последовательность \033[1;32;40mПОБЕДЫ
будет обрабатываться так, что слово «ПОБЕДЫ» отобразится жирным зелёным цветом на чёрном фоне.
Функции. Чтобы не запутаться и соблюдать правила хорошего тона в программировании, всю программу мы разделим на функции. Сначала соберём все вспомогательные функции, а потом напишем одну главную.
Импортируем модули и указываем тип терминала
Добавляем нужные модули командой import
:
# импортируем модуль os
import os
# импортируем модуль random
import random
Теперь нам нужно указать тип терминала, чтобы Python лучше понимал, как работать с последовательностями ANSI. Чтобы узнать тип терминала, используем команду echo $TERM
в командной строке или терминале IDE:
Нужно указать только первое слово, например xterm
, linux
, vt100
или screen
. У нас тип терминала xterm
, мы укажем в коде его. Если у вас другой тип терминала, замените xterm
на своё значение:
# устанавливаем переменную окружения, предварительно узнав
# свой тип консоли в терминале командой echo $TERM
os.environ['TERM'] = 'xterm'
Если не объявить эту переменную, скорее всего, всё будет работать и без неё. Но тогда в выводе каждый раз будет появляться служебное сообщение:
Создаём игровую колоду
Подготовимся к игре. Спросим у пользователя количество колод и создадим для каждой колоды 4 списка с полным набором карт — по одному для каждой масти. Масть для игры неважна, но важно указать количество карт в колоде.
# просим пользователя ввести количество колод
decks = input("Введите количество колод: ")
# умножаем список карт одной масти на 4 и на количество колод decks
deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] * (int(decks) * 4)
Из карт от 11 до 14 мы потом сделаем карты-картинки — от валета до туза.
Объявим два счётчика — побед и поражений.
# устанавливаем начальные значения счётчиков побед и поражений
wins = 0
losses = 0
Раздаём начальные карты
Создадим функцию, которая сдаёт по 2 карты. Для этого сначала передаём в функцию общий список со всеми картами, которые есть в игре:
# функция выдачи двух начальных карт
def deal(deck_func):
Создаём пустой список hand
— в него будем добавлять две карты с конца колоды.
# создаём список без карт
hand = []
Перемешиваем общую колоду:
# дважды запускаем цикл
# перемешиваем все карты в общей колоде
random.shuffle(deck_func)
Запускаем цикл и дважды достаём из колоды последнюю карту методом .pop()
. Тогда из списка извлекается последний элемент. В самом списке этот элемент удаляется:
for i in range(2):
# достаём последний элемент списка, «верхнюю карту»
card = deck_func.pop()
Проверим карты на обозначение: 11 станет валетом, 12 — дамой, 13 — королём, из 14 получится туз.
# присваиваем карте понятное обозначение, если карта — картинка
# валет
if card == 11:
card = "J"
# дама
if card == 12:
card = "Q"
# король
if card == 13:
card = "K"
# туз
if card == 14:
card = "A"
Добавляем эту карту на руку игроку или раздающему и возвращаем список hand
.
# добавляем карту на руку игроку
hand.append(card)
# возвращаем из функции список с двумя картами
return hand
Запускаем новый раунд
После каждого раунда будем спрашивать игрока, хочет ли он сыграть ещё. Для этого напишем функцию, которая выводит текст вопроса и принимает от пользователя строку-ответ.
Если игрок пишет «да», то независимо от регистра букв запускаем основную функцию игры. У нас её пока нет, но название уже можно указать. Назовём её game()
:
# функция запуска нового раунда игры после окончания предыдущего
def play_again():
# спрашиваем у пользователя, хочет ли он играть ещё
again = input("Хотите сыграть снова? (Да/Нет) : ").lower()
# если хочет, запускаем основную функцию игры
if again == "да":
game()
# если не хочет, показываем финальное сообщение и закрываем программу
else:
print("\033[0;35;40mКазино всегда выигрывает!\033[0m")
exit()
Если пользователь пишет любой другой ответ, завершаем работу программы командой exit()
. Она останавливает работу всего интерпретатора. Перед выходом показываем сообщение фиолетовым цветом на чёрном фоне.
Переводим карты в очки
Нам понадобится отдельная функция для перевода списка с картами в числовые значения. Для этого добавим в функцию переменную-счётчик, который каждый раз объявляется с нулевым значением.
Посмотрим на код функции, а потом разберём его работу:
# функция подсчёта очков по картам на руке
def total(hand):
# устанавливаем начальное нулевое значение
points = 0
# запускаем цикл, который проверит все карты в списке hand
for card in hand:
# если карта — картинка, то прибавляем 10
if card == "J" or card == "Q" or card == "K":
points += 10
# туз считается в зависимости от количества очков
elif card == "A":
if points >= 11:
points += 1
else:
points += 11
# все остальные карты считаются по своему номиналу
else:
points += card
# возвращаем количество очков
return points
Как происходит подсчёт очков:
- На каждую карту в списке мы запускаем по одной итерации цикла.
- Если элемент списка — карта-картинка, приравниваем её к 10 очкам.
- При этом помним, что ценность у туза считается с нюансами.
- Остальные карты считаем по своему номиналу-названию.
Производим добор карт
После раздачи игрок и раздающий смотрят на свои карты и решают — остановиться или взять ещё одну карту. Для добавления ещё одной карты на руку напишем функцию, которая берёт последний элемент из списка всех карт deck
и добавляет в список игроков hand
. Все карты с картинками становятся своими понятными буквенными аналогами:
# функция добавления новой карты
def hit(hand):
# берём карту с конца списка общей колоды — «снимаем карту сверху»
card = deck.pop()
# присваиваем карте понятное обозначение, если карта — картинка
# валет
if card == 11:
card = "J"
# дама
if card == 12:
card = "Q"
# король
if card == 13:
card = "K"
# туза
if card == 14:
card = "A"
# добавляем карту на руку
hand.append(card)
# возвращаем новый список
return hand
В конце возвращаем обновлённый список.
Выводим результаты
Функций по подсчёту очков у нас ещё нет, но для них понадобится ещё одна функция для вывода результатов раунда на экран. Поэтому сначала создадим её.
В функцию для вывода результатов мы передаём два списка: очки раздающего и игрока, — после чего выводим на экран заголовок и две строки с этими очками:
# функция вывода результатов
def print_results(dealer_hand, player_hand):
# выводим на экран результаты раунда
print("\n*** РЕЗУЛЬТАТЫ РАУНДА ***\n")
# выводим список карт на руке в формате строки и считаем сумму очков для раздающего и игрока
print("У раздающего на руке: " + str(dealer_hand) + ", в сумме: " + str(total(dealer_hand)))
print("У вас на руке: " + str(player_hand) + ", в сумме: " + str(total(player_hand)))
Чтобы вывести одной строкой список карт и очков, списки трансформируем в строки. В этой же строке считаем уже готовой функцией total
число очков и тоже переводим его в строковый формат. Теперь можно склеить все элементы вывода через знак +
.
Проверяем начальные карты
Если у кого-то на руках туз и карта в 10 очков, то набран блек-джек. В этом случае сразу заканчиваем игру, увеличиваем счётчик побед или поражений и предлагаем сыграть снова.Чтобы функция могла изменять счётчики побед и поражений, их нужно добавить в область видимости функции командой global
.
def blackjack(dealer_hand, player_hand):
# добавляем в область видимости счётчики побед и поражений
global wins
global losses
В теле функции будет три главных блока с проверками условий if
и elif
. Если блек-джек у игрока, то увеличиваем счётчик побед и выводим сообщение о выигрыше.
# проверяем очки игрока на 21
if total(player_hand) == 21:
# если у игрока 21, выводим результаты, пишем
# сообщение о выигрыше, увеличиваем счётчик побед
print_results(dealer_hand, player_hand)
print("Поздравляю! У вас блек-джек, вы выиграли!\n")
wins += 1
# предлагаем сыграть снова
play_again()
Если блек-джек у раздающего, то увеличиваем счётчик поражений и выводим сообщение о проигрыше.
# проверяем очки раздающего на 21
elif total(dealer_hand) == 21:
# если у раздающего 21, выводим результаты, пишем
# сообщение о проигрыше, увеличиваем счётчик поражений
print_results(dealer_hand, player_hand)
print("Простите, вы проиграли. У раздающего блек-джек.\n")
losses += 1
# предлагаем сыграть снова
play_again()
Если блек-джек у обоих, счётчики не меняются и программа предлагает сыграть снова.
elif total(dealer_hand) == total(player_hand):
# выводим результаты игрока и раздающего
print_results(dealer_hand, player_hand)
# выводим сообщение о победе и итоговом результате
print("У вас и у раздающего блек-джек. В этом раунде победителя нет.\n")
# предлагаем сыграть снова
play_again()
Считаем очки в конце раунда
Если никому не достался блек-джек, а игрок и раздающий не набрали больше 21 очка, нужно посчитать карты. Алгоритм такой же, как в функции blackjack()
:
- делаем счётчики побед и поражений видимыми с помощью команды
global
; - считаем очки при помощи функции
total
, которая переводит карты в очки; - добавляем по одному условию на каждый вариант подсчёта очков;
- увеличиваем счётчик побед или поражений или не меняем оба счётчика, если раунд закончился ничьей.
Объявляем функцию и добавляем счётчики в область видимости:
# функция подсчёта очков
def score(dealer_hand, player_hand):
# добавляем в область видимости счётчики побед и поражений
global wins
global losses
Проверяем очки. Прописываем логику для ситуации, когда игрок набрал 21:
# проверяем очки
# если у игрока 21:
if total(player_hand) == 21:
# выводим результаты игрока и раздающего
print_results(dealer_hand, player_hand)
# выводим сообщение о победе и итоговом результате
print("Поздравляю! У вас 21, вы выиграли!\n")
wins += 1
Раздающий набрал 21:
# если у раздающего 21
elif total(dealer_hand) == 21:
# выводим результаты игрока и раздающего
print_results(dealer_hand, player_hand)
# выводим сообщение о проигрыше и итоговом результате
print("Простите, вы проиграли. У раздающего 21.\n")
losses += 1
Никто не набрал 21, но у игрока меньше очков, чем у раздающего:
# если у раздающего больше очков
elif total(player_hand) < total(dealer_hand):
# выводим результаты игрока и раздающего
print_results(dealer_hand, player_hand)
# выводим сообщение о проигрыше и итоговом результате
print("У раздающего больше очков, чем у вас. Вы проиграли.\n")
losses += 1
Раздающий набрал меньше игрока:
# если у игрока больше очков
elif total(player_hand) > total(dealer_hand):
# выводим результаты игрока и раздающего
print_results(dealer_hand, player_hand)
# выводим сообщение о победе и итоговом результате
print("Поздравляю, у вас больше очков, чем у раздающего. Вы выиграли!\n")
wins += 1
Очков поровну:
elif total(player_hand) == total(dealer_hand):
# выводим результаты игрока и раздающего
print_results(dealer_hand, player_hand)
# выводим сообщение о победе и итоговом результате
print("Раздающий набрал столько же, сколько и вы. В этом раунде победителя нет.\n")
Обратите внимание, что в этой функции мы не вызываем функцию запуска нового раунда. Она будет вызываться в основной функции после подсчёта очков.
Выводим результаты
Объявляем функцию и делаем счётчики видимыми для неё:
# основная функция игры
def game():
# добавляем в область видимости счётчики побед и поражений
global wins
global losses
Используем управляющие последовательности для оформления. Слово «ПОБЕДЫ» выделяем зелёным текстом жирного начертания, «ПОРАЖЕНИЯ» — красным. Значения добавляем знаком % и в конце строки в скобках объясняем, что за переменные туда передавать:
# выводим оформление нового раунда
print("\n Новая игра!\n")
# выводим 30 коротких тире
print("-" * 30 + "\n")
# выводим слово ПОБЕДЫ жирным зелёным шрифтом, слово ПОРАЖЕНИЯ — жирным красным
# после каждого слова ставим корректные счётчики
print(" \033[1;32;40mПОБЕДЫ: \033[1;37;40m%s \033[1;31;40mПОРАЖЕНИЯ: \033[1;37;40m%s\n\033[0m" % (wins, losses))
# выводим 30 коротких тире
print("-" * 30 + "\n")
Дописываем игровую логику
Запускаем функцию раздачи начальных карт для игрока и раздающего:
# раздаём по две карты игроку и раздающему
dealer_hand = deal(deck)
player_hand = deal(deck)
Раздающий раскрывает одну карту и показывает, что у него:
# раздающий раскрывает одну карту
print("Раздающий показывает " + str(dealer_hand[0]))
Показываем игроку, какие карты выпали ему:
# говорим игроку, что за карты у него на руке и сколько очков
print("У вас на руке:" + str(player_hand) + ", в сумме количество очков равно " + str(total(player_hand)))
Проверяем игрока и раздающего на блек-джек:
# проверяем, есть ли у кого-то 21
blackjack(dealer_hand, player_hand)
Запускаем главную функцию с игрой:
# запускаем бесконечный цикл
while True:
Если игрок решил взять карту, запускаем функцию hit()
. После этого показываем новый список карт и считаем очки. Если получается больше 21, выводим сообщение о проигрыше и предлагаем сыграть ещё.
# при выборе добрать карту
if choice == 'д':
# запускаем функцию добавления карты
hit(player_hand)
# выводим новый список карт
print(player_hand)
# выводим на экран сумму очков
print("Сумма ваших очков: " + str(total(player_hand)))
# если у игрока больше 21 очка, выводим сообщение о проигрыше,
# увеличиваем счётчик поражений, предлагаем сыграть заново
if total(player_hand) > 21:
print('У вас перебор')
losses += 1
play_again()
Если пользователь больше не хочет брать карты, ход переходит раздающему. Напомним, что по правилам раздающий должен набрать на руке не меньше 17 очков.
Запускаем функцию hit()
и считаем очки после каждой новой карты. Если больше 17 — останавливаем игру и считаем очки. Если больше 21 — пишем игроку, что он победил, и увеличиваем счётчик побед на 1.
# при выборе остановиться ход переходит раздающему
elif choice == 'о':
# пока у дилера меньше 17 очков, он должен добирать карты
while total(dealer_hand) < 17:
hit(dealer_hand)
# после каждой новой карты выводим список карт раздающего
print('Раздающий взял новую карту. У него на руках: ', dealer_hand)
# если у раздающего больше 21 очка, выводим сообщение о выигрыше,
# увеличиваем счётчик побед, предлагаем сыграть заново
if total(dealer_hand) > 21:
print('У раздающего перебор, вы выиграли!')
wins += 1
play_again()
Если раздающий набрал между 17 и 21 очком, подсчитываем итоги у обоих:
# если раздающий набрал 17 очков и у него не перебор, подсчитываем очки обоих
else:
score(dealer_hand, player_hand)
play_again()
Если игрок хочет закончить игру, показываем финальное сообщение и останавливаем выполнение всей программы:
# если игрок решил завершить игру, выводим сообщение и завершаем программу
elif choice == "в":
print("Казино всегда выигрывает!")
exit()
Добавим проверку ввода. Если игрок ввёл какой-то другой символ вместо «д», «о» или «в», выводим сообщение, что нужно повторить ответ.
# если пользователь ввёл какое-то непредусмотренное значение, просим повторить ввод
else:
print("Неверный ввод. Пожалуйста, введите 'д', 'о' или 'в'.")
Запускаем основную функцию:
# запускаем основную функцию игры
game()
Играем:
Что дальше
Теперь у нас есть программа, на которой мы можем моделировать разные стратегии игры и проверять, как работает комбинаторика и теория вероятностей в жизни. Этим потихоньку и займёмся в следующий раз.
# импортируем модуль os
import os
# импортируем модуль random
import random
# устанавливаем переменную окружения, предварительно узнав
# свой тип консоли в терминале командой echo $TERM
os.environ['TERM'] = 'xterm'
# просим пользователя ввести количество колод
decks = input("Введите количество колод: ")
# умножаем список карт одной масти на 4 и на количество колод decks
deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] * (int(decks) * 4)
# устанавливаем начальные значения счётчиков побед и поражений
wins = 0
losses = 0
# функция выдачи двух начальных карт
def deal(deck_func):
# создаём список без карт
hand = []
# дважды запускаем цикл
# перемешиваем все карты в общей колоде
random.shuffle(deck_func)
for i in range(2):
# достаём последний элемент списка, «верхнюю карту»
card = deck_func.pop()
# присваиваем карте понятное обозначение, если карта — картинка
# валет
if card == 11:
card = "J"
# дама
if card == 12:
card = "Q"
# король
if card == 13:
card = "K"
# туз
if card == 14:
card = "A"
# добавляем карту на руку игроку
hand.append(card)
# возвращаем из функции список с двумя картами
return hand
# функция запуска нового раунда игры после окончания предыдущего
def play_again():
# спрашиваем у пользователя, хочет ли он играть ещё
again = input("Хотите сыграть снова? (Да/Нет) : ").lower()
# если хочет, запускаем основную функцию игры
if again == "да":
game()
# если не хочет, показываем финальное сообщение и закрываем программу
else:
print("\033[0;35;40mКазино всегда выигрывает!\033[0m")
exit()
# функция подсчёта очков по картам на руке
def total(hand):
# устанавливаем начальное нулевое значение
points = 0
# запускаем цикл, который проверит все карты в списке hand
for card in hand:
# если карта — картинка, то прибавляем 10
if card == "J" or card == "Q" or card == "K":
points += 10
# туз считается в зависимости от количества очков
elif card == "A":
if points >= 11:
points += 1
else:
points += 11
# все остальные карты считаются по своему номиналу
else:
points += card
# возвращаем количество очков
return points
# функция добавления новой карты
def hit(hand):
# берём карту с конца списка общей колоды — «снимаем карту сверху»
card = deck.pop()
# присваиваем карте понятное обозначение, если карта — картинка
# валет
if card == 11:
card = "J"
# дама
if card == 12:
card = "Q"
# король
if card == 13:
card = "K"
# туз
if card == 14:
card = "A"
# добавляем карту на руку
hand.append(card)
# возвращаем новый список
return hand
# функция вывода результатов
def print_results(dealer_hand, player_hand):
# выводим на экран результаты раунда
print("\n*** РЕЗУЛЬТАТЫ РАУНДА ***\n")
# выводим список карт на руке в формате строки и считаем сумму очков для раздающего и игрока
print("У раздающего на руке: " + str(dealer_hand) + ", в сумме: " + str(total(dealer_hand)))
print("У вас на руке: " + str(player_hand) + ", в сумме: " + str(total(player_hand)))
# функция проверки начальной раздачи на 21
def blackjack(dealer_hand, player_hand):
# добавляем в область видимости счётчики побед и поражений
global wins
global losses
# проверяем очки игрока на 21
if total(player_hand) == 21:
# если у игрока 21, выводим результаты, пишем
# сообщение о выигрыше, увеличиваем счётчик побед
print_results(dealer_hand, player_hand)
print("Поздравляю! У вас блек-джек, вы выиграли!\n")
wins += 1
# предлагаем сыграть снова
play_again()
# проверяем очки раздающего на 21
elif total(dealer_hand) == 21:
# если у раздающего 21, выводим результаты, пишем
# сообщение о проигрыше, увеличиваем счётчик поражений
print_results(dealer_hand, player_hand)
print("Простите, вы проиграли. У раздающего блек-джек.\n")
losses += 1
# предлагаем сыграть снова
play_again()
elif total(dealer_hand) == total(player_hand):
# выводим результаты игрока и раздающего
print_results(dealer_hand, player_hand)
# выводим сообщение о победе и итоговом результате
print("У вас и у раздающего блек-джек. В этом раунде победителя нет.\n")
# предлагаем сыграть снова
play_again()
# функция подсчёта очков
def score(dealer_hand, player_hand):
# добавляем в область видимости счётчики побед и поражений
global wins
global losses
# проверяем очки
# если у игрока 21:
if total(player_hand) == 21:
# выводим результаты игрока и раздающего
print_results(dealer_hand, player_hand)
# выводим сообщение о победе и итоговом результате
print("Поздравляю! У вас 21, вы выиграли!\n")
wins += 1
# если у раздающего 21
elif total(dealer_hand) == 21:
# выводим результаты игрока и раздающего
print_results(dealer_hand, player_hand)
# выводим сообщение о проигрыше и итоговом результате
print("Простите, вы проиграли. У раздающего 21.\n")
losses += 1
# если у раздающего больше очков
elif total(player_hand) < total(dealer_hand):
# выводим результаты игрока и раздающего
print_results(dealer_hand, player_hand)
# выводим сообщение о проигрыше и итоговом результате
print("У раздающего больше очков, чем у вас. Вы проиграли.\n")
losses += 1
# если у игрока больше очков
elif total(player_hand) > total(dealer_hand):
# выводим результаты игрока и раздающего
print_results(dealer_hand, player_hand)
# выводим сообщение о победе и итоговом результате
print("Поздравляю, у вас больше очков, чем у раздающего. Вы выиграли!\n")
wins += 1
elif total(player_hand) == total(dealer_hand):
# выводим результаты игрока и раздающего
print_results(dealer_hand, player_hand)
# выводим сообщение о победе и итоговом результате
print("Раздающий набрал столько же, сколько и вы. В этом раунде победителя нет.\n")
# основная функция игры
def game():
# добавляем в область видимости счётчики побед и поражений
global wins
global losses
# выводим оформление нового раунда
print("\n Новая игра!\n")
# выводим 30 коротких тире
print("-" * 30 + "\n")
# выводим слово ПОБЕДЫ жирным зелёным шрифтом, слово ПОРАЖЕНИЯ — жирным красным
# и после каждого слова ставим корректные счётчики
print(" \033[1;32;40mПОБЕДЫ: \033[1;37;40m%s \033[1;31;40mПОРАЖЕНИЯ: \033[1;37;40m%s\n\033[0m" % (wins, losses))
# выводим 30 коротких тире
print("-" * 30 + "\n")
# раздаём по две карты игроку и раздающему
dealer_hand = deal(deck)
player_hand = deal(deck)
# раздающий раскрывает одну карту
print("Раздающий показывает " + str(dealer_hand[0]))
# говорим игроку, что за карты у него на руке и сколько очков
print("У вас на руке:" + str(player_hand) + ", в сумме количество очков равно " + str(total(player_hand)))
# проверяем, есть ли у кого-то 21
blackjack(dealer_hand, player_hand)
# запускаем бесконечный цикл
while True:
# спрашиваем у игрока, что он хочет сделать
choice = input("\033[1;33;40mВы хотите [д]обрать карту, [о]становиться или [в]ыйти из игры? \033[0m").lower()
# при выборе добрать карту
if choice == 'д':
# запускаем функцию добавления карты
hit(player_hand)
# выводим новый список карт
print(player_hand)
# выводим на экран сумму очков
print("Сумма ваших очков: " + str(total(player_hand)))
# если у игрока больше 21 очка, выводим сообщение о проигрыше,
# увеличиваем счётчик поражений, предлагаем сыграть заново
if total(player_hand) > 21:
print('У вас перебор')
losses += 1
play_again()
# при выборе остановиться ход переходит раздающему
elif choice == 'о':
# пока у дилера меньше 17 очков, он должен добирать карты
while total(dealer_hand) < 17:
hit(dealer_hand)
# после каждой новой карты выводим список карт раздающего
print('Раздающий взял новую карту. У него на руках: ', dealer_hand)
# если у раздающего больше 21 очка, выводим сообщение о выигрыше,
# увеличиваем счётчик побед, предлагаем сыграть заново
if total(dealer_hand) > 21:
print('У раздающего перебор, вы выиграли!')
wins += 1
play_again()
# если раздающий набрал 17 очков и у него не перебор, подсчитываем очки обоих
else:
score(dealer_hand, player_hand)
play_again()
# если игрок решил завершить игру, выводим сообщение и завершаем программу
elif choice == "в":
print("\033[0;35;40mКазино всегда выигрывает!\033[0m")
exit()
# если пользователь ввёл какое-то непредусмотренное значение, просим повторить ввод
else:
print("Неверный ввод. Пожалуйста, введите 'д', 'о' или 'в'.")
# запускаем основную функцию игры
game()