Автор оригинала: Pankaj Kumar.
Blackjack – это игра на основе карты, которую играют в казино. Участники этой игры не конкурируют друг с другом, но дилер, назначенный казино. В этой статье мы будем создавать блэкджек между игроком и дилером с нуля, которые можно играть на терминале.
Правила блэкджека
Мы предоставим краткий набор правил для читателей, которые никогда не играли в блэкджек. Magic Number для Blackjack 21. Значения для всех карт, которые имели возможность игрока, и если сумма превышает 21, проигрыватели и проигрывают и теряют мгновенно.
Если игрок получает точное 21, игрок побеждает против дилера. В противном случае, чтобы выиграть, сумма карт игрока должна быть больше, чем сумма карт дилера.
Каждая лицевая карта имеет определенное значение 10, в то время как туз может учитываться как 1 или 11 подходящей к шансам игрока на победу. Значение остальных карт определяется их числом.
Работа карт в игре в блэкджек выглядит следующим образом:
- Карта рассматривается для игрока, стоящего вверх (видимым всем).
- Дилер занимается картой для себя видимой для всех.
- Другая карта отдается игроку вверх.
- Дилер имеет дело с видом на вниз для себя.
- Игрок должен решить, стоит ли стоять с текущим набором карт или получить другую карту.
- Если игрок решает ударить, сдается другая карта.
- Если игрок решает стоять, то дилер раскрывает свою скрытую карту.
- У дилера нет полномочий решать, следует ли ударить или стенд. Общее правило заключается в том, что дилер должен продолжать ударить больше карт, если сумма дилерских карт составляет менее 17.
- Как только сумма карт дилера – это либо 17, так и более, дилер обязан стоять.
- Согласно окончательной сумме карт, победитель решается.
Программирование игры Blackjack становится простым, как только правила поняты. Создание терминальной игры с нуля требует трех основных компонентов: дизайн игры, игровой логику и управление взаимодействием игрока.
Блэкджек игра демонстрация
Разработка блэкджека в Python
Во-первых, мы будем работать над дизайном вашей игры. Наша работа состоит в том, чтобы эффективно отображать серию карт на терминале что-то вроде следующего рисунка.
Нам нужна функция, которая печатает последовательность карт и не зависит от количества карт. Более того, он должен предоставить функциональность для печати скрытой карты, если это необходимо.
Следующий код решает нашу проблему.
# Function to print the cards def print_cards(cards, hidden): s = "" for card in cards: s = s + "\t ________________" if hidden: s += "\t ________________" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| |" print(s) s = "" for card in cards: if card.value == '10': s = s + "\t| {} |".format(card.value) else: s = s + "\t| {} |".format(card.value) if hidden: s += "\t| |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| * * |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| * * |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| * * |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| * * |" print(s) s = "" for card in cards: s = s + "\t| {} |".format(card.suit) if hidden: s += "\t| * |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| * |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| * |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| |" print(s) s = "" for card in cards: if card.value == '10': s = s + "\t| {} |".format(card.value) else: s = s + "\t| {} |".format(card.value) if hidden: s += "\t| * |" print(s) s = "" for card in cards: s = s + "\t|________________|" if hidden: s += "\t|________________|" print(s) print()
Детали каждой карты хранятся как объект карты. Второй параметр print_cards ()
Функция – это логическое значение, которое указывает, отображается ли скрытая карта или нет.
Создание карты
С помощью классов и объектов мы можем создать ансамбль костюмов и значений для представления «игральной карты». В блэкджеке карта имеет три свойства, его костюм, его представляющее значение и его стоимость как оценка.
Все вышеуказанные свойства поддерживаются в следующем классе карта.
# The Card Class definition class Card: def __init__(self, suit, value, card_value): # Suit of the Card like Spades and Clubs self.suit = suit # Representing Value of the Card like A for Ace, K for King self.value = value # Score Value for the Card like 10 for King self.card_value = card_value
Используя вышеуказанный класс, мы можем создать правильную колоду карт, содержащую 52 объектов карты.
Некоторые фундаментальные значения
Каждая игра карт требует фундаментальных значений, таких как типы костюмов, типы карт и значений для каждой карты.
# The type of suit suits = ["Spades", "Hearts", "Clubs", "Diamonds"] # The suit value suits_values = {"Spades":"\u2664", "Hearts":"\u2661", "Clubs": "\u2667", "Diamonds": "\u2662"} # The type of card cards = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"] # The card value cards_values = {"A": 11, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "10":10, "J":10, "Q":10, "K":10}
Вот одно следует отметить, что туз изначально отмечен как 11 точечная карта. Идея этой стратегии состоит в том, что всякий раз, когда оценка игрока/дилера, похоже, пересекается 21, мы можем уменьшить счет ACE (если речь) до 1.
Мы увидим реализацию сокращения позже в этой статье.
Генерировать колоду игральных карт
Нормальная колода игральных карт состоит из 52 карт, каждый из которых несила другая комбинация костюма и значения. Используя вышеуказанные фундаментальные значения и класс карты, мы генерируем колоду карт.
# The deck of cards deck = [] # Loop for every type of suit for suit in suits: # Loop for every type of card in a suit for card in cards: # Adding card to the deck deck.append(Card(suits_values[suit], card, cards_values[card]))
На самом деле игра в блэкджек включает несколько колод, поэтому вышеуказанный набор петель можно повторно использовать для заполнения нескольких палуб.
Вновь созданная колода передается функции, которая выполняет игру.
blackjack_game(deck)
Давайте узнаем игровую логику за одной итерацией игры в блэкджеке между игроком и компьютерным дилером.
Объявление важных переменных игр
В любое мгновение времени нам требуется следующие переменные игры:
- Список карт занимал игрока и дилер.
- Сумма значений карты для каждой стороны.
# Function for a single game of blackjack def blackjack_game(deck): global cards_values # Cards for both dealer and player player_cards = [] dealer_cards = [] # Scores for both dealer and player player_score = 0 dealer_score = 0
Эти переменные игры вступают в игру, когда мы разработаем логику игры.
Python Blackjack Game Logic
Вся игровая логика вращается вокруг динамики карт и выборов игрока для удара или стоящего. Как только мы обрабатываем вышеупомянутые две вещи, мы сделаем на день.
Первая фаза справки: обязательные карты
Первоначальная работа включает в себя предоставление двух карт игроку и дилеру. Тем не менее, вторая карта для дилера должна оставаться неизвестной.
# Initial dealing for player and dealer while len(player_cards) < 2: # Randomly dealing a card player_card = random.choice(deck) player_cards.append(player_card) deck.remove(player_card) # Updating the player score player_score += player_card.card_value # In case both the cards are Ace, make the first ace value as 1 if len(player_cards) == 2: if player_cards[0].card_value == 11 and player_cards[1].card_value == 11: player_cards[0].card_value = 1 player_score -= 10 # Print player cards and score print("PLAYER CARDS: ") print_cards(player_cards, False) print("PLAYER SCORE = ", player_score) input() # Randomly dealing a card dealer_card = random.choice(deck) dealer_cards.append(dealer_card) deck.remove(dealer_card) # Updating the dealer score dealer_score += dealer_card.card_value # Print dealer cards and score, keeping in mind to hide the second card and score print("DEALER CARDS: ") if len(dealer_cards) == 1: print_cards(dealer_cards, False) print("DEALER SCORE = ", dealer_score) else: print_cards(dealer_cards[:-1], True) print("DEALER SCORE = ", dealer_score - dealer_cards[-1].card_value) # In case both the cards are Ace, make the second ace value as 1 if len(dealer_cards) == 2: if dealer_cards[0].card_value == 11 and dealer_cards[1].card_value == 11: dealer_cards[1].card_value = 1 dealer_score -= 10 input() # Player gets a blackjack if player_score == 21: print("PLAYER HAS A BLACKJACK!!!!") print("PLAYER WINS!!!!") quit()
Это может быть много, чтобы впитаться на, казалось бы, простое дело. Давайте понять процесс, вовлеченный в вышеуказанный код:
- Главный цикл работает до тех пор, пока игрок и дилер не получит две карты каждый.
- Карта случайно выбрана из колоды, а на следующем шаге, которую карта удаляется из колоды.
- Значение карты добавляется в счет игрока.
- Аналогично, карта случайно выбрана для дилера, и его стоимость добавляется к баллу дилера.
- Карты игрока отображаются на экране нормально.
- Карты дилера осторожно отображаются такими, что вторая карта и ее ценность не выявлены.
- В случае, если любой из участников получает двойные тузы, их оценки скорректированы такими, что ни один из них не преодолевает.
- После того, как все вышеперечисленные вещи происходят гладко, мы переходим на второй этап справки.
Примечание: Существует тонкая разница между корректировкой баллов для игрока и дилера. В первом случае значение первой карты регулируется, тогда как в последнем значении второй карты регулируется.
Причина регулировки значения второй карты заключается в том, что мы скорректировали первую, мы выявили личность скрытой карты как туз.
Одна последняя вещь, которая должна быть сделана здесь, проверяет, есть ли у игрока в блэкджеке. Если он делает, игрок выигрывает, и игра заканчивается.
Примечание: вход ()
Функция делает паузу программы, пока игрок не нажимает «Enter». Это предотвращает быстрое падение всех игровых событий.
Очистить ()
Функция отвечает за очистку терминала, давая чистую эстетику для игры.
Вторая фаза справки: выбор игрока
Второй этап борьбы с решением зависит от решения игрока либо желать другую карту для повышения оценки или стоять с текущим набором карт.
# Print dealer and player cards print("DEALER CARDS: ") print_cards(dealer_cards[:-1], True) print("DEALER SCORE = ", dealer_score - dealer_cards[-1].card_value) print() print("PLAYER CARDS: ") print_cards(player_cards, False) print("PLAYER SCORE = ", player_score) # Managing the player moves while player_score < 21: choice = input("Enter H to Hit or S to Stand : ") # Sanity checks for player's choice if len(choice) != 1 or (choice.upper() != 'H' and choice.upper() != 'S'): clear() print("Wrong choice!! Try Again") # If player decides to HIT if choice.upper() == 'H': # Dealing a new card player_card = random.choice(deck) player_cards.append(player_card) deck.remove(player_card) # Updating player score player_score += player_card.card_value # Updating player score in case player's card have ace in them c = 0 while player_score > 21 and c < len(player_cards): if player_cards[c].card_value == 11: player_cards[c].card_value = 1 player_score -= 10 c += 1 else: c += 1 clear() # Print player and dealer cards print("DEALER CARDS: ") print_cards(dealer_cards[:-1], True) print("DEALER SCORE = ", dealer_score - dealer_cards[-1].card_value) print() print("PLAYER CARDS: ") print_cards(player_cards, False) print("PLAYER SCORE = ", player_score) # If player decides to Stand if choice.upper() == 'S': break # Check if player has a Blackjack if player_score == 21: print("PLAYER HAS A BLACKJACK") quit() # Check if player busts if player_score > 21: print("PLAYER BUSTED!!! GAME OVER!!!") quit()
Игрок решает, ударить или поддерживаться до тех пор, пока счет не превысит 21 или игрок решает стоять. Нет ограничений на количество карт, имеющих дело с игроком, просто на счет.
Каждый раз, когда игрок решает поразить, новая карта рассматривается с колоды, и счет обновляется. Как уже упоминалось ранее, ACE может учитываться как 1 или 11. Специальный кусок кода преобразует значение ACE с 11 до 1, если оценка превышает 21.
Игрок стоит, когда он удовлетворен текущим баллом. Когда он делает, мы переходим к финальной стадии справки после того, как совершили некоторые обязательные проверки, такие как блэкджек или разрядный сценарий.
Заключительная фаза справки: карты дилеров
На заключительном этапе динамики обнаруживается скрытая карта дилера, и это оценка дилера. Согласно стандартным правилам блэкджека, дилер должен бороться с самим еще более картами, пока его счет не превышает или равно 17.
# Managing the dealer moves while dealer_score < 17: clear() print("DEALER DECIDES TO HIT.....") # Dealing card for dealer dealer_card = random.choice(deck) dealer_cards.append(dealer_card) deck.remove(dealer_card) # Updating the dealer's score dealer_score += dealer_card.card_value # Updating player score in case player's card have ace in them c = 0 while dealer_score > 21 and c < len(dealer_cards): if dealer_cards[c].card_value == 11: dealer_cards[c].card_value = 1 dealer_score -= 10 c += 1 else: c += 1 # print player and dealer cards print("PLAYER CARDS: ") print_cards(player_cards, False) print("PLAYER SCORE = ", player_score) print() print("DEALER CARDS: ") print_cards(dealer_cards, False) print("DEALER SCORE = ", dealer_score) input()
Дилер продолжает ударить до тех пор, пока счет не пересекает 17 отметку. У нас есть аналогичная реализация значений преобразования карт тузов от 11 до 1, если необходимо.
Конечная игра
Когда счет дилера – это либо 17, так и более, мы перемещаемся на конечную игру, которая включает в себя сравнение ценностей и выдвижение победителя игры. Может быть возможно несколько сценариев:
- Дилер бюст – счет дилера превышает 21.
- Дилер имеет блэкджек – дилер имеет точную оценку 21.
- Игра галстука – и игрок, и дилер имеет равный счет.
- Игрок выигрывает – счет игрока – это больше, чем у дилера.
- Дилер выигрывает – счет дилера – это больше, чем у игрока.
Мы проверяем для каждой из вышеперечисленных возможностей и объявляем победителя.
# Dealer busts if dealer_score > 21: print("DEALER BUSTED!!! YOU WIN!!!") quit() # Dealer gets a blackjack if dealer_score == 21: print("DEALER HAS A BLACKJACK!!! PLAYER LOSES") quit() # TIE Game if dealer_score == player_score: print("TIE GAME!!!!") # Player Wins elif player_score > dealer_score: print("PLAYER WINS!!!") # Dealer Wins else: print("DEALER WINS!!!")
Это завершает единую итерацию игры в блэкджек между игроком и дилером.
Полный код Python для игры в блэкджек
import random import os import time # The Card class definition class Card: def __init__(self, suit, value, card_value): # Suit of the Card like Spades and Clubs self.suit = suit # Representing Value of the Card like A for Ace, K for King self.value = value # Score Value for the Card like 10 for King self.card_value = card_value # Clear the terminal def clear(): os.system("clear") # Function to print the cards def print_cards(cards, hidden): s = "" for card in cards: s = s + "\t ________________" if hidden: s += "\t ________________" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| |" print(s) s = "" for card in cards: if card.value == '10': s = s + "\t| {} |".format(card.value) else: s = s + "\t| {} |".format(card.value) if hidden: s += "\t| |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| * * |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| * * |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| * * |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| * * |" print(s) s = "" for card in cards: s = s + "\t| {} |".format(card.suit) if hidden: s += "\t| * |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| * |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| * |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| |" print(s) s = "" for card in cards: s = s + "\t| |" if hidden: s += "\t| |" print(s) s = "" for card in cards: if card.value == '10': s = s + "\t| {} |".format(card.value) else: s = s + "\t| {} |".format(card.value) if hidden: s += "\t| * |" print(s) s = "" for card in cards: s = s + "\t|________________|" if hidden: s += "\t|________________|" print(s) print() # Function for a single game of blackjack def blackjack_game(deck): # Cards for both dealer and player player_cards = [] dealer_cards = [] # Scores for both dealer and player player_score = 0 dealer_score = 0 clear() # Initial dealing for player and dealer while len(player_cards) < 2: # Randomly dealing a card player_card = random.choice(deck) player_cards.append(player_card) deck.remove(player_card) # Updating the player score player_score += player_card.card_value # In case both the cards are Ace, make the first ace value as 1 if len(player_cards) == 2: if player_cards[0].card_value == 11 and player_cards[1].card_value == 11: player_cards[0].card_value = 1 player_score -= 10 # Print player cards and score print("PLAYER CARDS: ") print_cards(player_cards, False) print("PLAYER SCORE = ", player_score) input() # Randomly dealing a card dealer_card = random.choice(deck) dealer_cards.append(dealer_card) deck.remove(dealer_card) # Updating the dealer score dealer_score += dealer_card.card_value # Print dealer cards and score, keeping in mind to hide the second card and score print("DEALER CARDS: ") if len(dealer_cards) == 1: print_cards(dealer_cards, False) print("DEALER SCORE = ", dealer_score) else: print_cards(dealer_cards[:-1], True) print("DEALER SCORE = ", dealer_score - dealer_cards[-1].card_value) # In case both the cards are Ace, make the second ace value as 1 if len(dealer_cards) == 2: if dealer_cards[0].card_value == 11 and dealer_cards[1].card_value == 11: dealer_cards[1].card_value = 1 dealer_score -= 10 input() # Player gets a blackjack if player_score == 21: print("PLAYER HAS A BLACKJACK!!!!") print("PLAYER WINS!!!!") quit() clear() # Print dealer and player cards print("DEALER CARDS: ") print_cards(dealer_cards[:-1], True) print("DEALER SCORE = ", dealer_score - dealer_cards[-1].card_value) print() print("PLAYER CARDS: ") print_cards(player_cards, False) print("PLAYER SCORE = ", player_score) # Managing the player moves while player_score < 21: choice = input("Enter H to Hit or S to Stand : ") # Sanity checks for player's choice if len(choice) != 1 or (choice.upper() != 'H' and choice.upper() != 'S'): clear() print("Wrong choice!! Try Again") # If player decides to HIT if choice.upper() == 'H': # Dealing a new card player_card = random.choice(deck) player_cards.append(player_card) deck.remove(player_card) # Updating player score player_score += player_card.card_value # Updating player score in case player's card have ace in them c = 0 while player_score > 21 and c < len(player_cards): if player_cards[c].card_value == 11: player_cards[c].card_value = 1 player_score -= 10 c += 1 else: c += 1 clear() # Print player and dealer cards print("DEALER CARDS: ") print_cards(dealer_cards[:-1], True) print("DEALER SCORE = ", dealer_score - dealer_cards[-1].card_value) print() print("PLAYER CARDS: ") print_cards(player_cards, False) print("PLAYER SCORE = ", player_score) # If player decides to Stand if choice.upper() == 'S': break clear() # Print player and dealer cards print("PLAYER CARDS: ") print_cards(player_cards, False) print("PLAYER SCORE = ", player_score) print() print("DEALER IS REVEALING THE CARDS....") print("DEALER CARDS: ") print_cards(dealer_cards, False) print("DEALER SCORE = ", dealer_score) # Check if player has a Blackjack if player_score == 21: print("PLAYER HAS A BLACKJACK") quit() # Check if player busts if player_score > 21: print("PLAYER BUSTED!!! GAME OVER!!!") quit() input() # Managing the dealer moves while dealer_score < 17: clear() print("DEALER DECIDES TO HIT.....") # Dealing card for dealer dealer_card = random.choice(deck) dealer_cards.append(dealer_card) deck.remove(dealer_card) # Updating the dealer's score dealer_score += dealer_card.card_value # Updating player score in case player's card have ace in them c = 0 while dealer_score > 21 and c < len(dealer_cards): if dealer_cards[c].card_value == 11: dealer_cards[c].card_value = 1 dealer_score -= 10 c += 1 else: c += 1 # print player and dealer cards print("PLAYER CARDS: ") print_cards(player_cards, False) print("PLAYER SCORE = ", player_score) print() print("DEALER CARDS: ") print_cards(dealer_cards, False) print("DEALER SCORE = ", dealer_score) input() # Dealer busts if dealer_score > 21: print("DEALER BUSTED!!! YOU WIN!!!") quit() # Dealer gets a blackjack if dealer_score == 21: print("DEALER HAS A BLACKJACK!!! PLAYER LOSES") quit() # TIE Game if dealer_score == player_score: print("TIE GAME!!!!") # Player Wins elif player_score > dealer_score: print("PLAYER WINS!!!") # Dealer Wins else: print("DEALER WINS!!!") if __name__ == '__main__': # The type of suit suits = ["Spades", "Hearts", "Clubs", "Diamonds"] # The suit value suits_values = {"Spades":"\u2664", "Hearts":"\u2661", "Clubs": "\u2667", "Diamonds": "\u2662"} # The type of card cards = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"] # The card value cards_values = {"A": 11, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "10":10, "J":10, "Q":10, "K":10} # The deck of cards deck = [] # Loop for every type of suit for suit in suits: # Loop for every type of card in a suit for card in cards: # Adding card to the deck deck.append(Card(suits_values[suit], card, cards_values[card])) blackjack_game(deck)
Читатель не обязан следовать всей последовательности кодирования. Там могут быть различные поправки, сделанные указанному вышеуказанному коду, добавив возможность нескольких игроков против дилера.
Заключение
Во-первых, игра в блэкджек может показаться простой и случайной, но только тогда, когда игроки следуют определенным стратегиям, как подсчет карты, игра становится сложной.
Есть много версий блэкджека, плавающих по всему миру, как шведский паб блэкджек и блэкджек домашней игры. Любопытные читатели могут узнать об этих вариантах и попытаться внедрить их, используя знания, полученные в этой статье.
Спасибо за чтение. Не стесняйтесь проверить, как разработать игру Mastermind в Python.