Теперь добавим подклассы для контейнера, которые часто встречаются в различных играх: рука игрока и колода карт.
Рука игрока не требует реализаций новых методов и вводится лишь ради улучшения читаемости кода. Хотя она могла содержать своим полем указание на игрока, которому она принадлежит, проще и логичнее сделать руку полем игрока.
from container import Container
class Hand(Container):
pass
Для класса колоды, однако, уже имеет смысл добавить новую функциональность. Во первых, чаще всего имеет смысл создавать только полную колоду карт - колоду, содержащую все карты определенного типа. Метод для перечесления карт уже написан, воспользуемся им:
from card import Card
from container import Container
class Deck(Container):
@classmethod
def full_deck(cls, card, player = None):
d = cls()
if player:
all_cards = card.all_cards(player)
else:
all_cards = card.all_cards()
for c in all_cards:
d.add_card(c)
return d
Обратим вниманее на декоратор к методу full_deck
. Статические методы принимают первым аргументом указатель на свой собственный класс. Данный метод сделан статическим, чтобы позволить создать пустую колоду, даже используя метод full_deck
у классов, отнаследованных от класса Deck
.
Последний класс, который мы реализуем в данном разделе, будет являться расширением к классу колоды карт. В некоторых играх, при необходимо взять карту из пустой колоды, в нее перед этим замешиваются карты из отбоя (зоны, в которую складываются сыгранные карты). Реализуем такой класс:
class ReshuflableDeck(Deck):
def __init__(self):
self.discard = Deck()
super(ReshuflableDeck, self).__init__()
def draw(self):
if len(self.cards) > 0:
return self.cards.pop()
else:
self.cards = self.discard.cards
self.shuffle()
self.discard = Deck()
return self.cards.pop()
def bury(self, card):
self.discard.add_card(card)
Перемешиваемая колода карт содержит в себе ссылку на отбой - отдельный контейнер карт, в который добавляются карты при помощи метода bury
.