Наконец, приступим к реализации последнего класса: фазы игры.

Для начального приближения воспользуемся почти что пустым классом:

class Phase(object):
  def __init__(self):
    pass

  def __call__(self):
    self.play()

  def play(self):
    raise NotImplementedError

  def __str__(self):
    return self.__class__.__name__

  def __repr__(self):
    return str(self)

Этого класса хватит для простых карточных игр, в которых правила не могут меняться по ходу игры, и карты не влияют на правила. Когда это может быть не так? К примеру, в игре Fluxx есть тип карт "правил", которые меняют ход игры, заставляя, к примеру, игрока играть первую карту за ход вслепую, запрещающая выиграть стандартным способом и т.п. Также текущая архитектура плохо подходит для такого рода изменений, так как тогда потребуется содавать фазы, в которых будет длинная цепочка условий "если в игре есть карта А, то ... , если В, то ...". Для того чтобы избавиться от такой проблемы, создадим возможность добавлять к классу фазы перечни других фаз, которые надо (временно) исполнять после выполнения этой фазы. Игра в слепую - особая пасле после фаза начала хода, невозможность победить - особая фаза отмены победы после фазы победы, и т.д. Реализуем это в отдельном классе, так как это не обязательный для всех игр функционал:

def HookablePhase(Phase):
  __hooks = []

  @staticmethod
  def add_hook(hook):
    __hooks.append(hook)

  @staticmethod
  def remove_hook(hook):
    #TODO: check if safe
    __hooks.remove(hook)

  def __call__(self):
    self.play()
    self.end()

  def play(self):
    raise NotImplementedError

  def end(self):
    for h in self.__hooks:
      h()()

results matching ""

    No results matching ""