На этом шаге мы рассмотрим создание лабиринта.
Класс Maze будет сам следить за сеткой (списком списков), описывающей состояние лабиринта. В нем также будут переменные экземпляра, хранящие количество строк и столбцов, начальное и конечное местоположение. Сетка лабиринта будет случайным образом заполнена заблокированными ячейками.
Сгенерированный лабиринт должен быть достаточно разреженным, чтобы почти всегда существовал путь от заданного начального до конечного местоположения. (В конце концов, это нужно для тестирования наших алгоритмов.) Мы позволим функции, вызывающей новый лабиринт, точно задавать степень разреженности, но определим значение по умолчанию, составляющее 20% заблокированных ячеек. Если случайное число превысит порог, заданный параметром sparseness, просто заменим пустое пространство стеной. Если так поступать для каждой возможной точки лабиринта, то статистически разреженность лабиринта в целом будет приближаться к заданному параметру sparseness.
class Maze: def __init__(self, rows: int = 10, columns: int = 10, sparseness: float = 0.2, start: MazeLocation = MazeLocation(0, 0), goal: MazeLocation = MazeLocation(9, 9)) -> None: # инициализация базовых переменных экземпляра self._rows: int = rows self._columns: int = columns self.start: MazeLocation = start self.goal: MazeLocation = goal # заполнение сетки пустыми ячейками self._grid: List[List[Cell]] = [[Cell.EMPTY for c in range(columns)] for r in range(rows)] # заполнение сетки заблокированными ячейками self._randomly_fill(rows, columns, sparseness) # заполнение начальной и конечной позиций в лабиринте self._grid[start.row][start.column] = Cell.START self._grid[goal.row][goal.column] = Cell.GOAL def _randomly_fill(self, rows: int, columns: int, sparseness: float): for row in range(rows): for column in range(columns): if random.uniform(0, 1.0) < sparseness: self._grid[row][column] = Cell.BLOCKED
Теперь, когда у нас есть лабиринт, нужно, чтобы он кратко выводился в консоль. Мы хотим, чтобы элементы лабиринта располагались близко друг к другу и все было похоже на настоящий лабиринт.
# вывести красиво отформатированную версию лабиринта для печати def __str__(self) -> str: output: str = "" for row in self._grid: output += "".join([c.value for c in row]) + "\n" return output
Теперь протестируем эти функции лабиринта:
maze: Maze = Maze()
print(maze)
Рис.1. Вывод лабиринта
На следующем шаге мы обратим внимание не мелкие детали лабиринта.