Всем привет! Сегодня я начинаю новую серию статей, посвященную изучению Python на примере простых проектов. В качестве первого проекта, я решил сделать простую версию игры Блэкджек без графического интерфейса с использованием встроенных типов данных и библиотеки random. Устраивайтесь поудобнее, мы начинаем!
Правила игры
Для того, чтобы победить, необходимо набрать больше очков, чем у оппонента, но не более 21. Если же и у Вас и у оппонента набрано более 21 очков, побеждает тот, у кого меньше.
Каждая карта имеет свой номинал:
- карты от 2 до 10 имеют номинал как на карте;
- Валет, Дама и Король имеют номинал 10;
- Туз в зависимости от ситуации имеет номинал 1 или 11. В нашем случае, мы всегда будем принимать Туз за 11.
В оригинальной игре присутствуют сплит, страховка и удвоение, но в это мы вникать не будем, в противном случае код получился бы не совсем для начинающих. Остановимся на том, что описано выше.
Приступим к написанию кода!
Исходный код доступен на GitHub. Вы можете его свободно скачать, изменять и даже использовать в коммерческих проектах.
В данной статье я рассмотрю весь код по частям и постараюсь его доходчиво объяснить.
Для начала из стандартной библиотеки random импортируем метод choice. С помощью random.choice() можно получить один случайный элемент из непустой последовательности элементов. В качестве этой последовательности может выступать кортеж, список, строка, а также диапазон range().
Затем задается константа, которая хранит в себе словарь всех карт и их номинал.
Словарь (dictionary) — тип данных в Python, который хранит в себе пары "Ключ : Значение". Обозначается фигурными скобками {}. Ключ и значение разделяются двоеточием :. Между парами "Ключ : Значение" ставится запятая ,.
В Pyhton нет констант в чистом виде. Поэтому сообщество программистов условно договорилось называть неизменяемые переменные заглавными буквами.
Далее я определил две функции, реализующие две основные функции Блэкджека, а именно взять карту из колоды и просмотреть карты в руке.
Функция выбора карты pull_cart() принимает на вход список, в котором будут храниться выбранные карты. В нашем случае, у нас будет 2 таких списка: для хранения карт игрока и для хранения карт бота-оппонента.
К сожалению, использовать импортированный метод random.choice() по отношению к словарю с картами на прямую не получится. для этого, каждую пару "ключ : значение" необходимо преобразовать в кортеж, а затем сделать список из этих кортежей. Это наглядно показано ниже на рис. 3. Таким образом, random.choice() сможет выбрать случайный кортеж, то есть случайную карту с её номиналом.
По своей сути, кортеж представляет неизменяемый упорядоченный список
Функция просмотра карт в руке show_your_hand() таким же образом принимает на вход список, в котором хранятся карты. Затем она в цикле перебирает каждый кортеж, берет первый элемент кортежа, обозначающий значение карты, "рисует" обрамление карты и записывает в строку, которую уже увидит пользователь.
Следующим шагом рассмотрим функцию, которая сравнивает очки бота и игрока, чтобы определить победителя. Функция compare() принимает на вход два списка: карты игрока и карты бота.
В теле функции определены 2 переменные player_score и bot_score для записи посчитанных очков игрока и бота соответственно. Как и в предыдущей функции show_your_hand(), в цикле перебирается каждый кортеж из списка, только на сей раз из кортежа выбирается не первый элемент, а второй, который обозначает номинал карты.
Просуммировав все карты в руке игрока и бота, остается сравнить очки и определить победителя.
Последняя, но не менее важная функция ai_decide() определяет логику бота. Бот будет брать карты из колоды до тех пор, пока в его руке меньше 17 очков.
Затем объявляю два списка: player_hand и bot_hand, в которых будут храниться карты игрока и бота соответственно.
Для работы игры, необходим основной цикл. Он определяется переменной game, со значением True. То есть, пока эта переменная имеет значение True, игра будет продолжаться.
Остается вывести пару сообщений для пользователя и выдать по две карты игроку и боту.
В основном цикле игры находится импровизированный интерфейс, происходит обработка ввода с клавиатуры и дописана логика бота, благодаря которой, у него не будет больше 5 карт.
Как только игрок решит завершить игру, бот наберет карты в соответствии с условием, описанным в функции ai_decide(), но при этом не наберет больше 5 карт. После этого переменная цикла game выставляется в False и игра завершается.
Заключение
Напоминаю, что исходный код Вы можете найти на GitHub.
Оставляйте комментарии, если статья понравилась, ставьте лайки и подписывайтесь на IT Gosha сегодня!
Всем хорошего настроения и спасибо за внимание!