6 Commits

Author SHA1 Message Date
da7e b317f7a3a0 FIX(path render): path render was called twice 2026-03-27 21:42:14 +01:00
da7e 2fc67683d8 add key handling without color management (not implemented) 2026-03-27 20:58:28 +01:00
da7e cb19cf1413 ADD(mlx path animation) 2026-03-27 19:47:21 +01:00
da7e 6ec617848f Merge branch 'main' of github.com:maoakeEnterprise/amazing into mlx 2026-03-27 18:29:39 +01:00
da7e 349e58ce41 ifpjefp 2026-03-27 18:29:09 +01:00
Maoake Teriierooiterai b078241359 fix something on the solver 2026-03-27 18:05:05 +01:00
6 changed files with 129 additions and 49 deletions
+116 -13
View File
@@ -1,9 +1,10 @@
from typing import Any from typing import Any, Generator
from src.AMazeIng import AMazeIng from src.AMazeIng import AMazeIng
from src.parsing import Parsing from src.parsing import Parsing
from mlx.mlx import Mlx from mlx import Mlx
import numpy as np import numpy as np
import math import math
import time
class MazeMLX: class MazeMLX:
@@ -12,18 +13,33 @@ class MazeMLX:
self.height = height self.height = height
self.width = width self.width = width
self.mlx_ptr = self.mlx.mlx_init() self.mlx_ptr = self.mlx.mlx_init()
self.generator = None
self.win_ptr = self.mlx.mlx_new_window( self.win_ptr = self.mlx.mlx_new_window(
self.mlx_ptr, width, height, "amazing" self.mlx_ptr, width, height + 200, "A-Maze-Ing"
) )
self.img_ptr = self.mlx.mlx_new_image(self.mlx_ptr, width, height) self.img_ptr = self.mlx.mlx_new_image(self.mlx_ptr, width, height)
self.buf, self.bpp, self.size_line, self.format = ( self.buf, self.bpp, self.size_line, self.format = (
self.mlx.mlx_get_data_addr(self.img_ptr) self.mlx.mlx_get_data_addr(self.img_ptr)
) )
self.path_printer = None
self.generator = None
def close(self) -> None: def close(self) -> None:
self.mlx.mlx_destroy_image(self.mlx_ptr, self.img_ptr) self.mlx.mlx_destroy_image(self.mlx_ptr, self.img_ptr)
def redraw_image(self) -> None:
self.mlx.mlx_clear_window(self.mlx_ptr, self.win_ptr)
self.mlx.mlx_put_image_to_window(
self.mlx_ptr, self.win_ptr, self.img_ptr, 0, 0
)
self.mlx.mlx_string_put(
self.mlx_ptr,
self.win_ptr,
self.width // 3,
self.height + 100,
0xFFFFFF,
"1: regen; 2: path; 3: color; 4: quit;",
)
def put_pixel(self, x, y) -> None: def put_pixel(self, x, y) -> None:
offset = y * self.size_line + x * (self.bpp // 8) offset = y * self.size_line + x * (self.bpp // 8)
@@ -35,7 +51,6 @@ class MazeMLX:
def clear_image(self) -> None: def clear_image(self) -> None:
self.buf[:] = b"\x00" * len(self.buf) self.buf[:] = b"\x00" * len(self.buf)
self.mlx.mlx_clear_window(self.mlx_ptr, self.win_ptr)
def put_line(self, start: tuple[int, int], end: tuple[int, int]) -> None: def put_line(self, start: tuple[int, int], end: tuple[int, int]) -> None:
sx, sy = start sx, sy = start
@@ -75,28 +90,116 @@ class MazeMLX:
self.put_line((x0, y1), (x1, y1)) self.put_line((x0, y1), (x1, y1))
if maze[y][x].get_west(): if maze[y][x].get_west():
self.put_line((x0, y0), (x0, y1)) self.put_line((x0, y0), (x0, y1))
self.mlx.mlx_put_image_to_window( self.redraw_image()
self.mlx_ptr, self.win_ptr, self.img_ptr, 0, 0)
def put_block(self, ul: tuple[int, int], dr: tuple[int, int]) -> None:
for y in range(min(ul[1], dr[1]), max(dr[1], ul[1])):
self.put_line((min(ul[0], dr[0]), y), (max(ul[0], dr[0]), y))
def put_path(self, amazing: AMazeIng):
path = amazing.solve_path()
print(path)
actual = amazing.entry
actual = (actual[0] - 1, actual[1] - 1)
maze = amazing.maze.get_maze()
if maze is None:
return
margin = math.trunc(
math.sqrt(self.width if self.width > self.height else self.height)
// 2
)
cell_size = math.trunc(
(
(self.height - margin) // len(maze)
if self.height > self.width
else (self.width - margin) // len(maze[0])
)
)
self.update_maze(maze)
for i in range(len(path)):
ul = (
(actual[0]) * cell_size + margin + 12,
(actual[1]) * cell_size + 12 + margin,
)
dr = (
(actual[0]) * cell_size + cell_size + margin - 12,
(actual[1]) * cell_size + cell_size - 12 + margin,
)
self.put_block(ul, dr)
self.redraw_image()
x0 = actual[0] * cell_size + margin + 12
y0 = actual[1] * cell_size + margin + 12
x1 = actual[0] * cell_size + cell_size + margin - 12
y1 = actual[1] * cell_size + cell_size + margin - 12
yield
match path[i]:
case "N":
self.put_block((x0, y0), (x1, y0 - 24))
actual = (actual[0], actual[1] - 1)
case "E":
self.put_block((x1, y0), (x1 + 24, y1))
actual = (actual[0] + 1, actual[1])
case "S":
self.put_block((x0, y1), (x1, y1 + 24))
actual = (actual[0], actual[1] + 1)
case "W":
self.put_block((x0, y0), (x0 - 24, y1))
actual = (actual[0] - 1, actual[1])
ul = (
(actual[0]) * cell_size + margin + 12,
(actual[1]) * cell_size + 12 + margin,
)
dr = (
(actual[0]) * cell_size + cell_size + margin - 12,
(actual[1]) * cell_size + cell_size - 12 + margin,
)
self.put_block(ul, dr)
self.redraw_image()
return
def close_loop(self, _: Any): def close_loop(self, _: Any):
self.mlx.mlx_loop_exit(self.mlx_ptr) self.mlx.mlx_loop_exit(self.mlx_ptr)
def gen_maze(self, amazing: AMazeIng) -> None: def handle_key_press(self, keycode: int, amazing: AMazeIng) -> None:
self.generator = amazing.generate() if keycode == 49:
self.restart_maze(amazing)
if keycode == 50:
self.restart_path(amazing)
if keycode == 51:
pass
if keycode == 52:
self.close_loop(None)
def start(self, amazing: AMazeIng) -> None: def start(self, amazing: AMazeIng) -> None:
self.gen_maze(amazing) self.restart_maze(amazing)
self.mlx.mlx_loop_hook(self.mlx_ptr, self.render, amazing) self.mlx.mlx_loop_hook(self.mlx_ptr, self.render_maze, amazing)
self.mlx.mlx_hook(self.win_ptr, 33, 0, self.close_loop, None) self.mlx.mlx_hook(self.win_ptr, 33, 0, self.close_loop, None)
self.mlx.mlx_hook(
self.win_ptr, 2, 1 << 0, self.handle_key_press, amazing
)
self.mlx.mlx_loop(self.mlx_ptr) self.mlx.mlx_loop(self.mlx_ptr)
def render(self, amazing: AMazeIng): def restart_maze(self, amazing: AMazeIng) -> None:
self.generator = amazing.generate()
def restart_path(self, amazing: AMazeIng) -> None:
self.path_printer = self.put_path(amazing)
def render_path(self):
try:
next(self.path_printer)
time.sleep(0.03)
except StopIteration:
pass
def render_maze(self, amazing: AMazeIng):
try: try:
next(self.generator) next(self.generator)
self.update_maze(amazing.maze.get_maze()) self.update_maze(amazing.maze.get_maze())
# time.sleep(0.01) # time.sleep(0.01)
except StopIteration: except StopIteration:
pass if self.path_printer is not None:
self.render_path()
def main() -> None: def main() -> None:
+5 -5
View File
@@ -1,8 +1,8 @@
WIDTH=20 WIDTH=11
HEIGHT=20 HEIGHT=11
ENTRY=1,1 ENTRY=1,1
EXIT=2,2 EXIT=11,11
OUTPUT_FILE=maze.txt OUTPUT_FILE=maze.txt
PERFECT=False PERFECT=True
GENERATOR=DFS GENERATOR=Kruskal
SOLVER=AStar SOLVER=AStar
+3 -3
View File
@@ -20,9 +20,9 @@ class AMazeIng(BaseModel):
@model_validator(mode="after") @model_validator(mode="after")
def check_entry_exit(self) -> Self: def check_entry_exit(self) -> Self:
if self.entry[0] >= self.width or self.entry[1] >= self.height: if self.entry[0] > self.width or self.entry[1] > self.height:
raise ValueError("Entry coordinates exceed the maze size") raise ValueError("Entry coordinates exceed the maze size")
if self.exit[0] >= self.width or self.exit[1] >= self.height: if self.exit[0] > self.width or self.exit[1] > self.height:
raise ValueError("Exit coordinates exceed the maze size") raise ValueError("Exit coordinates exceed the maze size")
return self return self
@@ -33,7 +33,7 @@ class AMazeIng(BaseModel):
return return
def solve_path(self) -> str: def solve_path(self) -> str:
return self.solver.solve(self.maze) return self.solver.solve(self.maze, self.height, self.width)
def __str__(self) -> str: def __str__(self) -> str:
res = self.maze.__str__() res = self.maze.__str__()
+3 -3
View File
@@ -152,7 +152,8 @@ class AStar(MazeSolver):
str(list(c[1].keys())[0]) for c in path if len(c[1]) > 0 str(list(c[1].keys())[0]) for c in path if len(c[1]) > 0
) )
def solve(self, maze: Maze) -> str: def solve(self, maze: Maze, height: int = None,
width: int = None) -> str:
res = self.get_path(maze.get_maze()) res = self.get_path(maze.get_maze())
if res is None: if res is None:
raise Exception("Path not found") raise Exception("Path not found")
@@ -161,8 +162,7 @@ class AStar(MazeSolver):
class DepthFirstSearchSolver(MazeSolver): class DepthFirstSearchSolver(MazeSolver):
def __init__(self, start, end): def __init__(self, start, end):
self.start = (start[1] - 1, start[0] - 1) super().__init__(start, end)
self.end = (end[1] - 1, end[0] - 1)
def solve(self, maze: Maze, height: int = None, def solve(self, maze: Maze, height: int = None,
width: int = None) -> str: width: int = None) -> str:
+2 -1
View File
@@ -1,5 +1,5 @@
from src.amaz_lib.MazeGenerator import DepthFirstSearch, Kruskal from src.amaz_lib.MazeGenerator import DepthFirstSearch, Kruskal
from src.amaz_lib.MazeSolver import AStar from src.amaz_lib.MazeSolver import AStar, DepthFirstSearchSolver
class DataMaze: class DataMaze:
@@ -68,6 +68,7 @@ class DataMaze:
} }
available_solver = { available_solver = {
"AStar": AStar, "AStar": AStar,
"DFS": DepthFirstSearchSolver
} }
res = {} res = {}
res["GENERATOR"] = available_generator[data["GENERATOR"]](entry, exit, res["GENERATOR"] = available_generator[data["GENERATOR"]](entry, exit,
-24
View File
@@ -1,24 +0,0 @@
B9153957955513953953
AEA96A9569792C6BAAD6
C5443AA9169281102C53
95556A82816C2AC2A952
A93916A86A956C3A86D6
AEC6C542944513806953
C395553AC393C2AC787A
BC69512C7AAC56855692
A952BAAF96AFFFAD53AE
A810686FC5057FC516C3
AAC4543FFFAFFFB96952
AC5553817FAFD52ABC3A
815552843FEFFF80296A
AC553A85413D55406C12
C53BAAC392C3953C13AA
9386AC386A9683C56AAA
846903AE96C568517C2A
AD3A82C385397C3C5546
C12AA87AA94293AD5513
D46C6C5446D46C45556E
1,1
2,2
SSEEENENWWWS