From 4013971a3ef99ed40f10cb5785b450e8ba2cf18e Mon Sep 17 00:00:00 2001 From: Matheus Jardim Bernardes Date: Fri, 2 Aug 2024 08:22:52 -0300 Subject: [PATCH] Map generator (#15) * maps review * wip * update lib * csv to txt * add maze generator --------- Co-authored-by: Matheus Jardim --- .github/workflows/pip_publish.yml | 2 +- VERSION | 2 +- example/main.py | 2 +- example/maze_generator.py | 4 ++++ maps/01.csv | 3 --- maps/01.txt | 3 +++ maps/02.csv | 3 --- maps/02.txt | 3 +++ maps/03.csv | 5 ---- maps/03.txt | 5 ++++ maps/04.csv | 6 ----- maps/04.txt | 6 +++++ maps/05.csv | 5 ---- maps/05.txt | 5 ++++ maps/06.csv | 7 ------ maps/06.txt | 7 ++++++ maps/07.csv | 7 ------ maps/07.txt | 7 ++++++ maps/08.csv | 7 ------ maps/08.txt | 7 ++++++ maps/{09.csv => 09.txt} | 3 +-- maps/10.csv | 10 -------- maps/10.txt | 10 ++++++++ maps/50.txt | 21 +++++++++++++++++ maze_runner/__init__.py | 3 ++- maze_runner/animation.py | 17 +++++++++++--- maze_runner/maze.py | 10 ++++---- maze_runner/maze_creator.py | 39 +++++++++++++++++++++++++++++++ 28 files changed, 142 insertions(+), 67 deletions(-) create mode 100644 example/maze_generator.py delete mode 100644 maps/01.csv create mode 100644 maps/01.txt delete mode 100644 maps/02.csv create mode 100644 maps/02.txt delete mode 100644 maps/03.csv create mode 100644 maps/03.txt delete mode 100644 maps/04.csv create mode 100644 maps/04.txt delete mode 100644 maps/05.csv create mode 100644 maps/05.txt delete mode 100644 maps/06.csv create mode 100644 maps/06.txt delete mode 100644 maps/07.csv create mode 100644 maps/07.txt delete mode 100644 maps/08.csv create mode 100644 maps/08.txt rename maps/{09.csv => 09.txt} (83%) delete mode 100644 maps/10.csv create mode 100644 maps/10.txt create mode 100644 maps/50.txt create mode 100644 maze_runner/maze_creator.py diff --git a/.github/workflows/pip_publish.yml b/.github/workflows/pip_publish.yml index 842399c..6dccc92 100644 --- a/.github/workflows/pip_publish.yml +++ b/.github/workflows/pip_publish.yml @@ -32,7 +32,7 @@ jobs: publish-to-pypi: name: >- Publish Python 🐍 distribution 📦 to PyPI -# if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes + if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes needs: - build runs-on: ubuntu-latest diff --git a/VERSION b/VERSION index 6da28dd..341cf11 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.1 \ No newline at end of file +0.2.0 \ No newline at end of file diff --git a/example/main.py b/example/main.py index de91750..7a715c5 100644 --- a/example/main.py +++ b/example/main.py @@ -1,7 +1,7 @@ from maze_runner import Maze if "__main__" == __name__: - maze = Maze("../maps/02.csv") + maze = Maze("../maps/02.txt") maze.clear_console() maze.print_maze_status() diff --git a/example/maze_generator.py b/example/maze_generator.py new file mode 100644 index 0000000..085a185 --- /dev/null +++ b/example/maze_generator.py @@ -0,0 +1,4 @@ +from maze_runner.maze_creator import MazeGenerator + +maze = MazeGenerator.generate_maze_structure() +MazeGenerator.save_maze_to_file(maze, "labirinto.txt") diff --git a/maps/01.csv b/maps/01.csv deleted file mode 100644 index 05be1af..0000000 --- a/maps/01.csv +++ /dev/null @@ -1,3 +0,0 @@ -#,#,#,#,#,#,# -#,S, , , ,F,# -#,#,#,#,#,#,# diff --git a/maps/01.txt b/maps/01.txt new file mode 100644 index 0000000..6373dbb --- /dev/null +++ b/maps/01.txt @@ -0,0 +1,3 @@ +####### +#S F# +####### diff --git a/maps/02.csv b/maps/02.csv deleted file mode 100644 index c161f1a..0000000 --- a/maps/02.csv +++ /dev/null @@ -1,3 +0,0 @@ -#,#,#,#,#,#,# -#,F, , , ,S,# -#,#,#,#,#,#,# diff --git a/maps/02.txt b/maps/02.txt new file mode 100644 index 0000000..f41e10c --- /dev/null +++ b/maps/02.txt @@ -0,0 +1,3 @@ +####### +#F S# +####### diff --git a/maps/03.csv b/maps/03.csv deleted file mode 100644 index 48d6861..0000000 --- a/maps/03.csv +++ /dev/null @@ -1,5 +0,0 @@ -#,#,#,#,#,#,# -#, , , , ,F,# -#,S, , , , ,# -#, , , , ,F,# -#,#,#,#,#,#,# diff --git a/maps/03.txt b/maps/03.txt new file mode 100644 index 0000000..a8f4ce1 --- /dev/null +++ b/maps/03.txt @@ -0,0 +1,5 @@ +####### +# F# +#S # +# F# +####### diff --git a/maps/04.csv b/maps/04.csv deleted file mode 100644 index 6f79508..0000000 --- a/maps/04.csv +++ /dev/null @@ -1,6 +0,0 @@ -#,#,#,#,#,#,#,# -#, , , , , ,S,# -#, , , , , , ,# -#, , , , , , ,# -#,F, , , , , ,# -#,#,#,#,#,#,#,# \ No newline at end of file diff --git a/maps/04.txt b/maps/04.txt new file mode 100644 index 0000000..79236a2 --- /dev/null +++ b/maps/04.txt @@ -0,0 +1,6 @@ +######## +# S# +# # +# # +#F # +######## \ No newline at end of file diff --git a/maps/05.csv b/maps/05.csv deleted file mode 100644 index d8206ea..0000000 --- a/maps/05.csv +++ /dev/null @@ -1,5 +0,0 @@ -#,#,#,#,#,#,#,# -#, , , , , ,S,# -#, ,#,#,#,#,#,# -#, , , , , ,F,# -#,#,#,#,#,#,#,# \ No newline at end of file diff --git a/maps/05.txt b/maps/05.txt new file mode 100644 index 0000000..066b022 --- /dev/null +++ b/maps/05.txt @@ -0,0 +1,5 @@ +######## +# S# +# ###### +# F# +######## \ No newline at end of file diff --git a/maps/06.csv b/maps/06.csv deleted file mode 100644 index cb63a0a..0000000 --- a/maps/06.csv +++ /dev/null @@ -1,7 +0,0 @@ -#,#,#,#,#,#,#,# -#, , , , , ,S,# -#, ,#,#,#,#,#,# -#, , , , , , ,# -#,#,#,#,#,#, ,# -#,F, , , , , ,# -#,#,#,#,#,#,#,# \ No newline at end of file diff --git a/maps/06.txt b/maps/06.txt new file mode 100644 index 0000000..0a692b0 --- /dev/null +++ b/maps/06.txt @@ -0,0 +1,7 @@ +######## +# S# +# ###### +# # +###### # +#F # +######## \ No newline at end of file diff --git a/maps/07.csv b/maps/07.csv deleted file mode 100644 index 9e7fb46..0000000 --- a/maps/07.csv +++ /dev/null @@ -1,7 +0,0 @@ -#,#,#,#,#,#,#,#,#,# -#,S, , , , , , , ,# -#,#,#,#,#,#,#,#, ,# -#, , , , , , , , ,# -#, ,#,#,#,#,#,#,#,# -#, , , , , , , ,F,# -#,#,#,#,#,#,#,#,#,# \ No newline at end of file diff --git a/maps/07.txt b/maps/07.txt new file mode 100644 index 0000000..eca6287 --- /dev/null +++ b/maps/07.txt @@ -0,0 +1,7 @@ +########## +#S # +######## # +# # +# ######## +# F# +########## \ No newline at end of file diff --git a/maps/08.csv b/maps/08.csv deleted file mode 100644 index e64401e..0000000 --- a/maps/08.csv +++ /dev/null @@ -1,7 +0,0 @@ -#,#,#,#,#,##,#,#,# -#,S,#, , , #, , ,# -#, ,#, ,#, #, , ,# -#, ,#, ,#, #, , ,# -#, ,#, ,#, #, , ,# -#, , , ,#, , ,F,# -#,#,#,#,#,##,#,#,# \ No newline at end of file diff --git a/maps/08.txt b/maps/08.txt new file mode 100644 index 0000000..9df149f --- /dev/null +++ b/maps/08.txt @@ -0,0 +1,7 @@ +########## +#S# # # +# # # # # +# # # # # +# # # # # +# # F# +########## \ No newline at end of file diff --git a/maps/09.csv b/maps/09.txt similarity index 83% rename from maps/09.csv rename to maps/09.txt index acdb96e..9c90ff1 100644 --- a/maps/09.csv +++ b/maps/09.txt @@ -1,6 +1,5 @@ ################## -############ # -# # # # +# # # # # #### # # # # # # # S# # # # # # # # ## # # # # diff --git a/maps/10.csv b/maps/10.csv deleted file mode 100644 index 5785ef6..0000000 --- a/maps/10.csv +++ /dev/null @@ -1,10 +0,0 @@ -#,#,#,#,#,#,#,#,#,# -#,F, , , , , ,#,F,# -#,#,#,#,#,#, ,#, ,# -#, , ,S, ,#, ,#, ,# -#, , , , ,#, ,#, ,# -#,#,#,#, ,#, ,#, ,# -#, , , , , , , , ,# -#,#,#,#,#,#,#,#, ,# -#,F, , , , , , , ,# -#,#,#,#,#,#,#,#,#,# diff --git a/maps/10.txt b/maps/10.txt new file mode 100644 index 0000000..b67244e --- /dev/null +++ b/maps/10.txt @@ -0,0 +1,10 @@ +########## +#F #F# +###### # # +# S # # # +# # # # +#### # # # +# # +######## # +#F # +########## diff --git a/maps/50.txt b/maps/50.txt new file mode 100644 index 0000000..7972a95 --- /dev/null +++ b/maps/50.txt @@ -0,0 +1,21 @@ +##################### +#S# # # # +# # # # # ### ### # # +# # # # # # # +# ##### ### ####### # +# # # # # +##### ##### # # ##### +# # # # # # # # +# # # # # ### # # # # +# # # # # # # # # +# # ####### # # ### # +# # # # # # # +# # # ### # # ####### +# # # # # # # +# ##### # # # ##### # +# # # # # # # # +# # ##### # ### # # # +# # # # # +### # ############# # +# # F# +##################### diff --git a/maze_runner/__init__.py b/maze_runner/__init__.py index 24b0cdc..0d630de 100644 --- a/maze_runner/__init__.py +++ b/maze_runner/__init__.py @@ -1,4 +1,5 @@ from .maze import Maze from .maze import Position +from .maze_creator import MazeGenerator -__all__ = [Maze, Position] +__all__ = [Maze, Position, MazeGenerator] diff --git a/maze_runner/animation.py b/maze_runner/animation.py index 24cd8b2..e96cb1d 100644 --- a/maze_runner/animation.py +++ b/maze_runner/animation.py @@ -89,7 +89,15 @@ def plot_maze( return image -def create_gif(header, maze, path, start_position, finish_positions, fps: int = 1): +def create_gif( + header, + maze, + path, + start_position, + finish_positions, + fps: int = 1, + filename: str = None, +): if fps < 1: raise Exception("fps must be >= 1") @@ -117,6 +125,9 @@ def create_gif(header, maze, path, start_position, finish_positions, fps: int = ) frames.append(image) + if not filename: + timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + filename = f"maze_path_{timestamp}.gif" + # Save frames as a GIF - timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") - imageio.mimsave(f"maze_path_{timestamp}.gif", frames, fps=fps) + imageio.mimsave(filename, frames, fps=fps) diff --git a/maze_runner/maze.py b/maze_runner/maze.py index fc6f089..9a350f9 100644 --- a/maze_runner/maze.py +++ b/maze_runner/maze.py @@ -1,5 +1,4 @@ import copy -import csv import logging import os from time import sleep @@ -36,11 +35,11 @@ def __init__( self.finish_positions = [] # Start loading Maze file - with open(maze_file_path) as csv_file: - csv_reader = csv.reader(csv_file, delimiter=",") + with open(maze_file_path) as file: + lines = file.readlines() line_count = 0 - for y_pos, cells in enumerate(csv_reader): + for y_pos, cells in enumerate(lines): # Validate maze width if self.maze_width is None: self.maze_width = len(cells) @@ -82,7 +81,7 @@ def __init__( self.steps_taken = 0 - def generate_animation(self, header: str, fps: int = 1): + def generate_animation(self, header: str, fps: int = 1, filename: str = None): create_gif( header, self.maze, @@ -90,6 +89,7 @@ def generate_animation(self, header: str, fps: int = 1): self.start_position, self.finish_positions, fps, + filename, ) def print_maze_status(self, clean_console: bool = True) -> None: diff --git a/maze_runner/maze_creator.py b/maze_runner/maze_creator.py new file mode 100644 index 0000000..14e0b79 --- /dev/null +++ b/maze_runner/maze_creator.py @@ -0,0 +1,39 @@ +import random + + +class MazeGenerator: + # Movimentos possíveis + MOVES = [(0, 2), (2, 0), (0, -2), (-2, 0)] + + @staticmethod + def generate_maze_structure(width: int = 21, height: int = 21): + # Inicializa o labirinto com paredes + maze = [["#" for _ in range(width)] for _ in range(height)] + + # Função recursiva para criar o labirinto + def carve_passages_from(x, y): + directions = MazeGenerator.MOVES[:] + random.shuffle(directions) + for dx, dy in directions: + nx, ny = x + dx, y + dy + if 0 <= nx < width and 0 <= ny < height and maze[ny][nx] == "#": + if 1 <= nx < width - 1 and 1 <= ny < height - 1: + maze[ny][nx] = " " + maze[ny - dy // 2][nx - dx // 2] = " " + carve_passages_from(nx, ny) + + # Define o ponto de partida + start_x, start_y = (1, 1) + maze[start_y][start_x] = "S" + carve_passages_from(start_x, start_y) + + # TODO add multi exits + # exits = [(width - 2, height - 2)] + maze[height - 2][width - 2] = "F" + + return maze + + @staticmethod + def save_maze_to_file(maze, filename): + with open(filename, "w", newline="") as file: + file.writelines([f"{''.join(line)}\n" for line in maze])