Blackjack на Python

Blackjack на Python


Попробуем написать игру 21 на Python. Так же она известна как блек-джек (Blackjack) или очко. В процессе написания игры black jack, мы попрактикуемся в использовании объективно-ориентированного подхода и генераторов списков на Python.

Начнем с создания трех классов, необходимых для карточной игры:

  • класс Карты,
  • класс Руки (на русском лучше сказать Карт на Руке),
  • класс Колоды

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

class Card(object):
    def
__init__(self, rank, suit):
        self.rank =
rank
        self.suit =
suit
    def
card_value(self):
    """ Возращает количество очков которое дает карта """
        if
self.rank in "TJQK":
            # По 10 за десятку, валета, даму и короля
            return
10
        else:
            # Возвращает нужное число очков за любую другую карту
            # Туз изначально дает одно очко.
            return
" A23456789".index(self.rank)
    def
get_rank(self):
        return
self.rank
    def
__str__(self):
        return
"%s%s" % (self.rank, self.suit)

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

class Hand(object):
    def
__init__(self, name):
        # имя игрока
        self.name =
name
        # Изначально рука пустая
        self.cards =
[]
    def
add_card(self, card):
        """ Добавляет карту на руку """
        self.cards.append(card)
    def
get_value(self):
        """ Метод получения числа очков на руке """
        result =
0
        # Количество тузов на руке.
        aces =
0
        for
card in self.cards:
            result +=
card.card_value()
            # Если на руке есть туз - увеличиваем количество тузов
            if
card.get_rank() == "A":
                aces +=
1
        # Решаем считать тузы за 1 очко или за 11
        if
result + aces * 10 <= 21:
            result +=
aces * 10
        return
result
    def
__str__(self):
        text =
"%s's contains:\n" % self.name
        for
card in self.cards:
            text +=
str(card) + " "
        text +=
"\nHand value: " + str(self.get_value())
        return
text

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

class Deck(object):
    def
__init__(self):
        # ранги
        ranks =
"23456789TJQKA"
        # масти
        suits =
"DCHS"
        # генератор списков создающий колоду из 52 карт
        self.cards =
[Card(r,s) for r in ranks for s in suits]
        # перетасовываем колоду. Не забудьте импортировать функцию shuffle из модуля random
        shuffle(self.cards)
    def
deal_card(self):
        """ Функция сдачи карты """
        return
self.cards.pop()

Все классы готовы, осталось создать функцию, в которой собственно и реализуется процесс игры.


def new_game():
    # создаем колоду
    d =
Deck()
    # задаем "руки" для игрока и дилера
    player_hand =
Hand("Player")
    dealer_hand =
Hand("Dealer")
    # сдаем две карты игроку
    player_hand.add_card(d.deal_card())
    player_hand.add_card(d.deal_card())
    # сдаем одну карту дилеру
    dealer_hand.add_card(d.deal_card())
    print
dealer_hand
    print
"="*20
    print
player_hand
    # Флаг проверки необходимости продолжать игру
    in_game =
True
    # набирать карты игроку имеет смысл только если у него на руке меньше 21 очка
    while
player_hand.get_value() < 21:
        ans =
raw_input("Hit or stand? (h/s) ")
        if
ans == "h":
            player_hand.add_card(d.deal_card())
            print
player_hand
            # Если у игрока перебор - дилеру нет смысла набирать карты
            if
player_hand.get_value() > 21:
                print
"You lose"
                in_game =
False
        else:
            print
"You stand!"
            break
    print
"=" * 20
    if
in_game:
        # По правилам дилер обязан набирать карты пока его счет меньше 17
        while
dealer_hand.get_value() < 17:
            dealer_hand.add_card(d.deal_card())
            print
dealer_hand
            # Если у дилера перебор играть дальше нет смысла - игрок выиграл
            if
dealer_hand.get_value() > 21:
                print
"Dealer bust"
                in_game =
False
    if
in_game:
        # Ни у кого не было перебора - сравниваем количество очков у игрока и дилера.
        # В нашей версии если у дилера и игрока равное количество очков - выигрывает казино
        if
player_hand.get_value() > dealer_hand.get_value():
            print
"You win"
        else:
    print
"Dealer win"

Теперь можно спокойно запускать нашу игру вызвав функцию new_game()

Приятной игры!



Report Page