From 9e96603a6af00ed7b4a8d3527ee2af9980b54153 Mon Sep 17 00:00:00 2001 From: Axy Date: Wed, 4 Feb 2026 19:40:15 +0100 Subject: [PATCH] Simple maze stuff, soon generator --- mase.py | 1 - maze.py | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+), 1 deletion(-) delete mode 100644 mase.py create mode 100644 maze.py diff --git a/mase.py b/mase.py deleted file mode 100644 index 8b13789..0000000 --- a/mase.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/maze.py b/maze.py new file mode 100644 index 0000000..9ec3e72 --- /dev/null +++ b/maze.py @@ -0,0 +1,134 @@ +from enum import Enum +from typing import Optional, cast + + +class NetworkID: + __uuid_gen: int = 0 + + def __init__(self) -> None: + self.uuid = NetworkID.__uuid_gen + NetworkID.__uuid_gen += 1 + + +class MazeWall: + def __init__(self, network_id: Optional[NetworkID] = None) -> None: + self.network_id: Optional[NetworkID] = network_id + + def is_full(self) -> bool: + return self.network_id is not None + + +class Orientation(Enum): + HORIZONTAL = "horizontal" + VERTICAL = "vertical" + + def opposite(self) -> "Orientation": + if self == Orientation.HORIZONTAL: + return Orientation.VERTICAL + return Orientation.HORIZONTAL + + +class WallId: + def __init__(self, orientation: Orientation, a: int, b: int) -> None: + self.orientation: Orientation = orientation + self.a: int = a + self.b: int = b + + def a_neighbours(self) -> list["WallId"]: + return [ + WallId(self.orientation.opposite(), self.b - 1, self.a), + WallId(self.orientation, self.a - 1, self.b), + WallId(self.orientation.opposite(), self.b, self.a), + ] + + def b_neighbours(self) -> list["WallId"]: + return [ + WallId(self.orientation.opposite(), self.b - 1, self.a + 1), + WallId(self.orientation, self.a + 1, self.b), + WallId(self.orientation.opposite(), self.b, self.a + 1), + ] + + def neighbours(self) -> list["WallId"]: + return self.a_neighbours() + self.b_neighbours() + + +class WallNetwork: + def __init__(self) -> None: + self.walls: set[WallId] = set() + + def size(self) -> int: + return len(self.walls) + + def add_wall(self, id: WallId) -> None: + self.walls.add(id) + + +class Maze: + def __init__(self, width: int, height: int) -> None: + self.width: int = width + self.height: int = height + self.horizontal: list[list[MazeWall]] = [ + [MazeWall() for _ in range(0, width)] for _ in range(0, height + 1) + ] + self.vertical: list[list[MazeWall]] = [ + [MazeWall() for _ in range(0, height)] for _ in range(0, width + 1) + ] + self.networks: dict[NetworkID, WallNetwork] = {} + + def _get_wall(self, id: WallId) -> MazeWall: + if id.orientation == Orientation.HORIZONTAL: + return self.horizontal[id.a][id.b] + return self.vertical[id.a][id.b] + + def _check_id(self, id: WallId) -> bool: + if id.a < 0 or id.b < 0: + return False + (a_max, b_max) = ( + (self.height + 1, self.width) + if id.orientation == Orientation.HORIZONTAL + else (self.width + 1, self.height) + ) + if id.a > a_max or id.b > b_max: + return False + return True + + def get_walls_checked(self, ids: list[WallId]) -> list[MazeWall]: + return [self._get_wall(id) for id in ids if self._check_id(id)] + + def get_neighbours(self, id: WallId) -> list[MazeWall]: + return self.get_walls_checked(id.neighbours()) + + def _fill_wall_alone(self, id: WallId, wall: MazeWall) -> None: + network_id: NetworkID = NetworkID() + wall.network_id = network_id + network = WallNetwork() + network.add_wall(id) + self.networks[network_id] = network + + def fill_wall(self, id: WallId) -> None: + wall: MazeWall = self._get_wall(id) + + if wall.is_full(): + return + + networks = { + cast(NetworkID, neighbour.network_id) + for neighbour in self.get_neighbours(id) + if neighbour.is_full() + } + + if networks == {}: + return self._fill_wall_alone(id, wall) + + dest_id = max(networks, key=lambda n: self.networks[n].size()) + dest = self.networks[dest_id] + + wall.network_id = dest_id + dest.add_wall(id) + + for to_merge in filter(lambda n: n != dest_id, networks): + for curr in self.networks[to_merge].walls: + self._get_wall(curr).network_id = dest_id + dest.add_wall(curr) + + del self.networks[to_merge] -- 2.52.0