Шаг 108.
Задачи ComputerScience на Python.
Состязательный поиск. Connect Four. Подключите четыре игровых автомата

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

    Игра Connect Four во многом похожа на крестики-нолики. Обе они ведутся на поле в виде сетки, и для выигрыша требуется, чтобы игрок расположил фишки в ряд. Но в Connect Four сетка больше, что предполагает гораздо больше способов выиграть, поэтому оценить каждую позицию значительно сложнее.

    Представленный далее код (файл connectfour.py) будет выглядеть в чем-то очень знакомым, но структуры данных и метод оценки сильно отличаются от использованных для игры в крестики-нолики. Обе игры реализованы как подклассы тех же базовых классов Piece и Board, с которыми мы познакомились в предыдущих шагах, что делает функцию minimax() пригодной для обеих игр.

from __future__ import annotations
from typing import List, Optional, Tuple
from enum import Enum
from board import Piece, Board, Move


class C4Piece(Piece, Enum):
    B = "B"
    R = "R"
    E = " "  # пустое поле

    @property
    def opposite(self) -> C4Piece:
        if self == C4Piece.B:
            return C4Piece.R
        elif self == C4Piece.R:
            return C4Piece.B
        else:
            return C4Piece.E

    def __str__(self) -> str:
        return self.value

    Класс C4Piece практически идентичен классу TTTPiece.

    Теперь определим функцию для генерации всех потенциальных выигрышных сегментов в сетке Connect Four определенного размера (файл connectfour.py).

def generate_segments(num_columns: int, num_rows: int,
                      segment_length: int) -> List[List[Tuple[int, int]]]:
    segments: List[List[Tuple[int, int]]] = []
    # генерируем вертикальные сегменты
    for c in range(num_columns):
        for r in range(num_rows - segment_length + 1):
            segment: List[Tuple[ int , int ]] = []
            for t in range(segment_length):
                segment.append((c, r + t))
            segments.append(segment)

    # генерируем горизонтальные сегменты
    for c in range(num_columns - segment_length + 1):
        for r in range(num_rows):
            segment = []
            for t in range(segment_length):
                segment.append((c + t, r))
            segments.append(segment)

    # генерируем сегменты диагонали из нижнего левого в верхний правый угол
    for c in range(num_columns - segment_length + 1):
        for r in range(num_rows - segment_length + 1):
            segment = []
            for t in range(segment_length):
                segment.append((c + t, r + t))
            segments.append(segment)

    # генерируем сегменты диагонали из верхнего левого в нижний правый угол
    for c in range(num_columns - segment_length + 1):
        for r in range(segment_length - 1, num_rows):
            segment = []
            for t in range(segment_length):
                segment.append((c + t, r - t))
            segments.append(segment)
    return segments

    Эта функция возвращает список списков ячеек сетки (кортежей, состоящих из комбинаций "столбец/строка"). Каждый список в списке содержит четыре ячейки сетки. Мы будем называть списки, состоящие из четырех ячеек сетки, сегментами. Если какой-либо сегмент на доске окажется окрашен в один цвет, это будет означать, что данный цвет выиграл.

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




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