From: Axy Date: Thu, 5 Mar 2026 00:51:32 +0000 (+0100) Subject: Fixed things and now you can config the look of the maze :3 X-Git-Url: https://git.uwuaxy.net/?a=commitdiff_plain;h=a70abd89327e796070971a45b2d042462834ced4;p=axy%2Fft%2Fa-maze-ing.git Fixed things and now you can config the look of the maze :3 --- diff --git a/__main__.py b/__main__.py index 1fa2f49..f7e494f 100644 --- a/__main__.py +++ b/__main__.py @@ -9,9 +9,10 @@ from amazeing import ( ) import random +from sys import stderr from amazeing.config.config_parser import Config from amazeing.maze_class.maze_walls import Cardinal, CellCoord -from amazeing.maze_display.TTYdisplay import Tile, extract_pairs +from amazeing.maze_display.TTYdisplay import Tile, TileMaps, extract_pairs from amazeing.maze_display.backend import BackendEvent, CloseRequested, IVec2 config = Config.parse(open("./example.conf").read()) @@ -30,33 +31,20 @@ pattern.fill(maze) walls_const = set(maze.walls_full()) -backend = TTYBackend(dims, IVec2(2, 1), IVec2(2, 1)) -curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_BLACK) -black = curses.color_pair(1) -empty = (" ", black) -style_empty = backend.add_style( - Tile( - [ - [empty, empty, empty, empty], - [empty, empty, empty, empty], - ] - ) -) -curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_WHITE) -white = curses.color_pair(2) -full = (" ", white) -style_full = backend.add_style( - Tile( - [ - [full, full, full, full], - [full, full, full, full], - ] - ) -) +backend = TTYBackend(dims, config.tilemap_wall_size, config.tilemap_cell_size) +pair_map = extract_pairs(config) +tilemaps = TileMaps(config, pair_map, backend) + +backend.set_style(tilemaps.empty) +for wall in maze.all_walls(): + for tile in wall.tile_coords(): + backend.draw_tile(tile) +for cell in CellCoord(*dims.xy()).all_up_to(): + backend.draw_tile(cell.tile_coords()) def clear_backend() -> None: - backend.set_style(style_empty) + backend.set_style(tilemaps.empty) for wall in maze.walls_dirty(): if maze.get_wall(wall).is_full(): continue @@ -67,7 +55,7 @@ def clear_backend() -> None: def display_maze(maze: Maze) -> None: clear_backend() - backend.set_style(style_full) + backend.set_style(tilemaps.full) rewrites = { wall for wall in maze.walls_dirty() if maze.get_wall(wall).is_full() diff --git a/amazeing/config/config_parser.py b/amazeing/config/config_parser.py index fa47b28..4a4f37f 100644 --- a/amazeing/config/config_parser.py +++ b/amazeing/config/config_parser.py @@ -337,8 +337,12 @@ class Config: "SCREENSAVER": DefaultedField(BoolField, False), "VISUAL": DefaultedField(BoolField, False), "INTERACTIVE": DefaultedField(BoolField, False), - "TILEMAP_WALL_SIZE": DefaultedField(CoordField, (2, 1)), - "TILEMAP_CELL_SIZE": DefaultedField(CoordField, (2, 1)), + "TILEMAP_WALL_SIZE": DefaultedField( + CoordField, IVec2(2, 1) + ), + "TILEMAP_CELL_SIZE": DefaultedField( + CoordField, IVec2(2, 1) + ), "TILEMAP_FULL": DefaultedStrField( ColoredLineField, ['"{WHITE:WHITE} "', '"{WHITE:WHITE} "'], diff --git a/amazeing/maze_class/maze_walls.py b/amazeing/maze_class/maze_walls.py index c45d4b4..6283ff3 100644 --- a/amazeing/maze_class/maze_walls.py +++ b/amazeing/maze_class/maze_walls.py @@ -173,8 +173,8 @@ class CellCoord: case Cardinal.WEST: return WallCoord(Orientation.VERTICAL, self.__x + 1, self.__y) - def pixel_coords(self) -> Iterable[IVec2]: - return [IVec2(self.__x * 2 + 1, self.__y * 2 + 1)] + def tile_coords(self) -> IVec2: + return IVec2(self.__x * 2 + 1, self.__y * 2 + 1) def offset(self, by: IVec2) -> "CellCoord": return CellCoord(self.__x + by.x, self.__y + by.y) @@ -184,3 +184,8 @@ class CellCoord: def y(self) -> int: return self.__y + + def all_up_to(self) -> Iterable["CellCoord"]: + for x in range(0, self.__x): + for y in range(0, self.__y): + yield CellCoord(x, y) diff --git a/amazeing/maze_display/TTYdisplay.py b/amazeing/maze_display/TTYdisplay.py index 64c965d..88354db 100644 --- a/amazeing/maze_display/TTYdisplay.py +++ b/amazeing/maze_display/TTYdisplay.py @@ -28,12 +28,24 @@ def pad_write_safe( class Tile: - def __init__(self, pixels: list[list[tuple[str, int]]]) -> None: - dims = IVec2(max(map(len, pixels), default=0), len(pixels)) + def __init__( + self, pixels: list[list[tuple[str, int]]], dims: IVec2 + ) -> None: + if ( + len(pixels) > dims.y + or max( + map(lambda line: sum(map(lambda s: len(s[0]), line)), pixels) + ) + > dims.x + ): + raise BackendException("Tile too big to fit in set dimensions") self.__pad: curses.window = curses.newpad(dims.y, dims.x) for y, line in enumerate(pixels): - for x, (char, attrs) in enumerate(line): - pad_write_safe(self.__pad, IVec2(x, y), char, attrs) + x = 0 + for s, attrs in line: + for char in s: + pad_write_safe(self.__pad, IVec2(x, y), char, attrs) + x += 1 def dims(self) -> IVec2: y, x = self.__pad.getmaxyx() @@ -216,7 +228,7 @@ def extract_pairs( ) for color, color_number in zip(value_colors, available_colors): curses.init_color( - color_number, *(min(0, max(1000, channel)) for channel in color) + color_number, *(max(0, min(1000, channel)) for channel in color) ) res_colors[color] = color_number available_pairs = {i for i in range(1, curses.COLOR_PAIRS)} @@ -227,14 +239,36 @@ def extract_pairs( + f"got: {len(pairs)}" ) res_pairs = {} - for colors, pair_number in zip(pairs, available_pairs): - fg, bg = colors + for pair, pair_number in zip(pairs, available_pairs): + fg, bg = pair curses.init_pair(pair_number, res_colors[fg], res_colors[bg]) - res_pairs[colors] = pair_number + res_pairs[pair] = curses.color_pair(pair_number) return res_pairs +class TileMaps: + def __init__( + self, + config: Config, + pair_map: dict[ColorPair, int], + backend: "TTYBackend", + ) -> None: + mazetile_dims = config.tilemap_wall_size + config.tilemap_cell_size + + def new_tilemap(lines: list[ColoredLine]) -> Tile: + return Tile( + [ + [(s, pair_map[color_pair]) for color_pair, s in line] + for line in lines + ], + mazetile_dims, + ) + + self.empty: int = backend.add_style(new_tilemap(config.tilemap_empty)) + self.full: int = backend.add_style(new_tilemap(config.tilemap_full)) + + class TTYBackend(Backend[int]): def __init__( self, maze_dims: IVec2, wall_dim: IVec2, cell_dim: IVec2 diff --git a/amazeing/maze_display/backend.py b/amazeing/maze_display/backend.py index 71551fb..e4497f1 100644 --- a/amazeing/maze_display/backend.py +++ b/amazeing/maze_display/backend.py @@ -47,6 +47,11 @@ class IVec2[T = int]: def __mod__(self, other: "T | IVec2[T]") -> "IVec2[T]": return self.with_op(self.innertype().__mod__)(self, other) + def __eq__(self, value: object, /) -> bool: + if not isinstance(value, IVec2): + return False + return self.x == value.x and self.y == value.y + def xy(self) -> tuple[T, T]: return (self.x, self.y) diff --git a/example.conf b/example.conf index a8366b3..50b57d8 100644 --- a/example.conf +++ b/example.conf @@ -1,5 +1,5 @@ -WIDTH=250 -HEIGHT=250 +WIDTH=25 +HEIGHT=25 ENTRY=2,5 #EXIT=100,100 OUTPUT_FILE=test