diff --git a/raskatovia/docs/data/task2/maps/simple.txt b/raskatovia/docs/data/task2/maps/simple.txt new file mode 100644 index 0000000..fe2e907 --- /dev/null +++ b/raskatovia/docs/data/task2/maps/simple.txt @@ -0,0 +1,5 @@ +####### +#S...F# +#.###.# +#.....# +####### \ No newline at end of file diff --git a/raskatovia/docs/data/task2/maze.py b/raskatovia/docs/data/task2/maze.py index e69de29..da42d64 100644 --- a/raskatovia/docs/data/task2/maze.py +++ b/raskatovia/docs/data/task2/maze.py @@ -0,0 +1,96 @@ +class Cell: + def __init__(self, row, col, value): + self.row = row + self.col = col + self.value = value + + def is_wall(self): + return self.value == "#" + + def is_start(self): + return self.value == "S" + + def is_finish(self): + return self.value == "F" + + +class Maze: + def __init__(self, cells, start, finish): + self.cells = cells + self.start = start + self.finish = finish + self.height = len(cells) + self.width = len(cells[0]) if cells else 0 + + def inside(self, row, col): + return 0 <= row < self.height and 0 <= col < self.width + + def get_cell(self, row, col): + if not self.inside(row, col): + return None + return self.cells[row][col] + + def is_free(self, row, col): + cell = self.get_cell(row, col) + return cell is not None and not cell.is_wall() + + def neighbors(self, row, col): + variants = [ + (row - 1, col), + (row + 1, col), + (row, col - 1), + (row, col + 1) + ] + result = [] + for next_row, next_col in variants: + if self.is_free(next_row, next_col): + result.append((next_row, next_col)) + return result + + def draw(self, path=None): + path_set = set(path) if path else set() + lines = [] + for row in range(self.height): + line = "" + for col in range(self.width): + cell = self.cells[row][col] + if (row, col) in path_set and not cell.is_start() and not cell.is_finish(): + line += "*" + else: + line += cell.value + lines.append(line) + return "\n".join(lines) + + +class MazeBuilder: + def __init__(self): + self.lines = [] + + def from_file(self, filename): + with open(filename, "r", encoding="utf-8") as file: + self.lines = [line.rstrip("\n") for line in file if line.strip()] + return self + + def build(self): + cells = [] + start = None + finish = None + width = len(self.lines[0]) + + for row, line in enumerate(self.lines): + if len(line) != width: + raise ValueError("maze lines have different length") + cell_row = [] + for col, value in enumerate(line): + cell = Cell(row, col, value) + if cell.is_start(): + start = (row, col) + if cell.is_finish(): + finish = (row, col) + cell_row.append(cell) + cells.append(cell_row) + + if start is None or finish is None: + raise ValueError("maze must have start and finish") + + return Maze(cells, start, finish) \ No newline at end of file