Package: aamaze
maze-packageA python package for generating, solving and displaying mazes.ContentsSetupPre-requisites/Requirements to use the PackageSetting up the Virtual EnvironmentInstalling Dependencies (User Build)Poetrysetup.pyUsing the PackageSupported AlgorithmsGenerating AlgorithmsSolving AlgorithmsBasic use case: Create a Maze and SolutionGenerating a Maze solution at runtimeManipulating the solving algorithm at runtimeConfiguring GraphicsAppOption input types KeyFull list of optionsOther functionalityConfiguring the GrowingTree Maze Generation AlgorithmSetupPre-requisites/Requirements to use the PackagePython version 3.7+ (Program originally written using Python 3.9 interpreter)Setting up the Virtual EnvironmentIt is good practice to create a virtual environment for this project (and for any other project with non-standard-library dependencies).
See this guide for how to setup and activate a virtual environment:Python docsNOTE: Ensure that you activate the environment once you have created it (See Python docs)Installing Dependencies (User Build)Note: This guide assumes you are in the root project directoryPoetryIf you have poetry installed on your machine, simply run poetry install.setup.pyTo install the relevant packages, select the directory that requirements.txt is in and run the following command:pip install .To check that all the packages have been installed, run the following command:pip listThis should produce an output that contains these itemsPackage    Version
---------- -------
aamaze     latest_version
pip        20.2.3
pygame     2.3.0
setuptools 49.2.1You are now ready to make Mazes!Using the PackageSupported AlgorithmsGenerating AlgorithmsEllerGrowingTreeKruskalsPrimsRecursiveBacktrackerRecursiveDivisorWilsonsAll Generation algorithms (with the exception of RecursiveDivisor) require a maze with all walls filled(start_filled=True)Solving AlgorithmsAStarSolverDijkstraSolverFloodFillSolutionCheckAStarSolver and DijkstraSolver find the shortest path between a Maze's entrance and exit. FloodFillSolutionCheck checks to see if every node in a maze can be reached from every other node.Basic use case: Create a Maze and SolutionCreating a Maze and Solution to a Maze can be done in the following way:Create a new Maze Object (In this case a 20x10 Maze)from aamaze import Maze
maze = Maze(20, 10, start_filled=True, entrance_index=0, exit_index=-1)Create a new GenerationAlgorithm ObjectRun the "generate_maze" method on GenerationAlgorithm Objectfrom aamaze.generation import X_GeneratingAlgorithm
X_GenerationAlgorithm(maze).generate_maze()Create a new SolvingAlgorithmRun the "solve_maze" method on SolvingAlgorithm Objectfrom aamaze.solving import Y_SolvingAlgorithm
maze_solver = Y_SolvingAlgorithm(maze)
maze_solver.solve_maze()The Objects you want to keep in this case are "maze" and "maze_solver". The GenerationAlgorithm can be safely discarded once its "generate_maze" has been run.Basic use case: Displaying a Maze and its solutionTo display a maze and itssolution (optional):Generate maze and solution Objects (as shown inBasic use case: Create a Maze and Solution).Create a GraphicsApp Objectfrom aamaze import GraphicsApp
app = GraphicsApp(maze, solver)   # solver is optionalCall the "run" method on the GraphicsApp Objectapp.run()Calling "app.run()" should open a new pygame Window that displays the Maze and its associated Solution (if a solution object is provided).Generating a Maze solution at runtimeaamaze allows for solutions to be generated dynamically while the GraphicsApp is running. To do this:Create a maze using the workflow described in Basic use case: Create a Maze and Solution (1-4) DO NOT run "solve_maze" on the SolvingAlgorithm.from aamaze import Maze
from aamaze.generation import X_GeneratingAlgorithm
from aamaze.solving import Y_SolvingAlgorithm

maze = Maze(20, 10, start_filled=True, entrance_index=0, exit_index=-1)
X_GenerationAlgorithm(maze).generate_maze()
maze_solver = Y_SolvingAlgorithm(maze)Create a GraphicsApp objectfrom aamaze import GraphicsApp
app = GraphicsApp(maze, maze_solver)(Optional) Configure whether a solution starts to be generated as soon as "app.run()" is called (start_paused), and the speed of generation (target_steps_per_second). By default, start_paused=False, target_steps_per_second=50app.configure(start_paused=True, target_steps_per_second=50)Run the app as usualapp.run()Manipulating the solving algorithm at runtimeControls for manipulating the solving algorithm at runtime are:[SPACE] topause/unpausesolving algorithm generation[S] tomanually run one stepof the solving algorithm[R] toresetsolving algorithm[+] toincreasetarget_steps_per_second (speed of solution generation)[-] todecreasetarget_steps_per_second (speed of solution generation)Configuring GraphicsAppBelow are all options that can be set using the app.configure() method. Options are always set using keyword args (var_x = val_y). Multiple options can be set in the same app.configure call. Available options can be printed via accessing the ".options_list" property of a GraphicsApp object instance.
Examples:app = GraphicsApp(maze)


app.configure(aspect_ratio=[16, 10])
app.configure(exit_colour=[200, 32, 32], entrance_colour=[32, 200, 32])
app.configure(window_width=1600, wall_colour=[0, 0, 0], show_fps_counter=True)Option input types KeyColour:Set using RGB values between 0 and 255 (inclusive). Takes 3 integers in a List, Tuple or any other object that is subscriptable.e.g. [200, 200, 205], (0, 4, 8), [255, 32, 16]Pair of Numbers:Takes 2 numbers in a List, Tuple or any other object that is subscriptable.e.g. [200, 100], (16, 9), [6, 4.5]Bool:Takes a standard python bool.e.g. True, FalsePositive Integer:Takes a standard python integer that is greater than or equal to 0.e.g. 0, 253, 1000000Full list of optionsaspect_ratio:Sets the aspect ratio that the GraphicsApp window will open at (e.g. [16, 9]). -Pair of Numbersbackground_colour:Sets the background colour of the GraphicsApp window (e.g. [200, 200, 205]). -Colourentrance_colour:Sets colour of Start/Entrance tile of maze. -Colourexit_colour:Sets colour of End/Exit tile of maze. -Colourshow_fps_counter:Determines whether fps counter is displayed in the top right of the GraphicsApp window. -Boolshow_step_counter:Determines whether target steps per second counter is displayed in the top right of the GraphicsApp window. -Boolsolution_colour:Sets the colour of solution nodes -Colourstart_paused:Determines whether the maze tries to start generating a solution as soon as GraphicsApp window is opened -Booltarget_fps:Target Frames per Second of the GraphicsApp window. -Positive Integertarget_steps_per_second:Target number of times step() method is called on the SolvingAlgorithm -Positive Integerwall_colour:Sets colour of maze walls -Colourwindow_width:Sets the width of the GraphicsApp window -Positive IntegerOther functionalityConfiguring the GrowingTree Maze Generation AlgorithmCurrently, GrowingTree is a special GeneratingAlgorithm that allows for editing how a maze is generated. This can be done by setting thenode_selection_modeattribute to one of three valuesrandom- The next path will start at a random node that has already been visited (approximates Prims Algorithm)newest- The next path will start at the most recently visited node that still has an unvisited neighbour (approximates Recursive Backtracker Algorithm)random-newest-split-x- The next path has anx% probability to start from a random node, and anx-100% chance of starting from the most recently visited node with an unvisited neighbour.See implementation below:maze = Maze(16, 16, start_filled=True)                        # Creating 16x16 maze
growing_tree = GrowingTree(maze)                              # Created GrowingTree instance

growing_tree.node_selection_mode = "random"                   # Randomly select node
growing_tree.node_selection_mode = "newest"                   # Select newest node with unvisited neighbour

growing_tree.node_selection_mode = "random-newest-split-25"   # 25% chance random, 75% change newest
growing_tree.node_selection_mode = "random-newest-split-50"   # 50% chance random, 50% change newest
growing_tree.node_selection_mode = "random-newest-split-98"   # 2% chance random, 98% change newestEND