)
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())
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
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()
"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} "'],
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)
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)
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()
)
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)}
+ 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
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)
-WIDTH=250
-HEIGHT=250
+WIDTH=25
+HEIGHT=25
ENTRY=2,5
#EXIT=100,100
OUTPUT_FILE=test