Шаг 101.
Задачи ComputerScience на Python.
Состязательный поиск. Основные компоненты настольной игры

    На этом шаге мы рассмотрим основные компоненты и гры и приведем их реализацию.

    Как и при рассмотрении большинства более сложных задач в предыдущих шагах, постараемся сделать решение как можно более обобщенным. В случае состязательного поиска это означает, что наши алгоритмы поиска не должны зависеть от игры. Начнем с определения нескольких простых базовых классов, которые выявляют состояние, необходимое алгоритмам поиска. Затем создадим подклассы базовых классов для конкретных игр (крестики-нолики и Connect Four) и введем эти подклассы в алгоритмы поиска, чтобы они могли "играть" в эти игры. Вот базовые классы (файл board.ру).

from __future__ import annotations
from typing import NewType, List
from abc import ABC, abstractmethod

Move = NewType('Move', int)


class Piece:
    @property
    def opposite(self) -> Piece:
        raise NotImplementedError("Должно быть реализовано подклассами.")


class Board(ABC):
    @property
    @abstractmethod
    def turn(self) -> Piece:
        ...

    @abstractmethod
    def move(self, location: Move) -> Board:
        ...

    @property
    @abstractmethod
    def legal_moves(self) -> List[Move]:
        ...

    @property
    @abstractmethod
    def is_win(self) -> bool:
        ...

    @property
    def is_draw(self) -> bool: 
        return (not self.is_win) and (len(self.legal_moves) == 0)

    @abstractmethod
    def evaluate(self, player: Piece) -> float:
        ...
Архив с файлом можно взять здесь.

    Тип Move будет представлять ход в игре. По сути, это просто целое число. В таких играх, как крестики-нолики и Connect Four, целое число может описывать ход, определяя квадрат или столбец, в котором должна быть размещена фигура. Piece - это базовый класс для фигуры на доске в игре. Его другая роль - индикатор хода. Именно для этого необходимо свойство opposite. Нам нужно знать, чей ход следует за текущим ходом.


Поскольку в крестиках-ноликах и игре Connect Four существует только один вид фигур, класс Piece может использоваться как индикатор хода. В более сложных играх, таких как шахматы, где есть разные виды фигур, ходы могут обозначаться целым числом или логическим значением. В качестве альтернативы можно применять для обозначения хода атрибут color более сложного типа Piece.

    Абстрактный базовый класс Board является фактическим хранилищем состояния. Для любой конкретной игры, которую будут выполнять алгоритмы поиска, они должны уметь ответить на следующие вопросы.

    Последний вопрос, касающийся ничьих, на самом деле является комбинацией двух предыдущих вопросов для многих игр. Если игра не выиграна, но возможных ходов нет, то это ничья. Вот почему в абстрактном базовом классе Game сразу можно создать конкретную реализацию свойства is_draw. Кроме того, есть еще несколько действий, которые необходимо реализовать.

    Каждый метод и свойство класса Board являются реализацией одного из предыдущих вопросов или действий. На языке игры класс Board можно было бы назвать Position, но мы используем это имя для чего-то более конкретного в каждом из подклассов.

    Со следующего шага мы начнем реализовывать игру "крестики-нолики".




Предыдущий шаг Содержание Следующий шаг