3. Maze Solver Too — A Better Path is Also a Path
Worth: 5%
DUE: Monday August 4, 2025, 11:55pm; submitted on MOODLE
3.1. Task
The goal is to solve a maze, again, but this time with artificial intelligence (AI). The A* (A-star) algorithm will be used to find an optimal solution.
Objectives:
Create a
LinkedPriorityQueueclass that implements aPriorityQueueThis data structure greatly helps with the implementation of A*
Create an
AStarMazeSolverclass that implements theMazeSolverinterfaceWithin this class, write the
solvemethod
Use the
AStarMazeSolver, along with some of the other provided classes, in themaintoCreate the maze
Solve the maze
Display the solution
Test the implementation with test classes
3.2. Provided Files
A package containing maze specific classes
A
Cellclass withCellTestunit testsA
Mazeclass withMazeTestunit testsA
MazeRendererclass withMazeRendererTestunit testsTwo exceptions —
LocationNotInMazeExceptionandMazeEndpointsExceptionA
MazeSolverinterface
A
QueueandPriorityQueueinterfaceA nearly empty
LinkedPriorityQueueclass with aLinkedPriorityQueueTestclass containing empty testsA nearly empty
AStarMazeSolverwith anAStarMazeSolverTestclass containing empty testsAn
Asn3class with an emptymainThree maze files
All of this can be downloaded from hereThis is a compressed IntelliJ project
Just unzip, put it in the desired location on the computer, and open the project through IntelliJ
Warning
When opening the project, IntelliJ may mention a missing JDK. If this is the case, simply select the download link in the notification to download and install the missing JDK.
3.3. Part 0 — Read the Assignment
Read the assignment description in its entirety before starting.
3.4. Part 1 — Read Through the Provided Code
Read through all the provided code. The code is commented and there is documentation describing everything. These are several objects and methods you will be using to solve the problem.
Reading through and understanding existing code is a significant part of the assignment. Although there are no marks directly associated with it, it is a requirement in order to do anything useful. Further, if you continue studying CS, you will be reading documentation and other people’s code a lot.
Be sure to also read through all the test classes. Take the time to make sense of what is going on — these will save you. You may want to do some brief reading on @Nested and @ParameterizedTest. The documentation may seem intimidating at first, but take your time and have a read. You may be surprised at how helpful reading the docs actually is.
Lastly, it’s not just having a superficial understanding of the provided code. Sure, one of the big points of abstraction is not needing to fully understand everything under the hood; however, you’re still new at this, and taking the time to understand what is happening in the code, and how it does it, is important.
3.5. Part 2 — Run Unit Tests
Run all the tests for the provided completed classes
All these tests should pass
If not, something has gone wrong
Was the code changed?
Did the test folder get changed?
Try re-downloading the project and starting over if they do not pass
Notice the test classes
AStarMazeSolverTestandLinkedPriorityQueueTestare provided, but incompleteThey have empty tests to be completed in their respective parts discussed below
3.6. Part 3 — Complete LinkedPriorityQueue
A priority queue is going to help with the implementation of the A* algorithm. Feel free to read up on priority queues, but in short, a priority queue is a queue with a twist — whenever dequeuing something, the element with the most important priority is returned. In other words, the order the elements are removed is based on the priority value, not the standard FIFO of a regular queue.
An example of this is triage at an emergency room: someone may have arrived at the emergency room with a bad cut earlier than the person with a giant crack in their skull, but they will get seen before given the severity of their injury.
3.6.1. Notes About The Implementation
The regular
LinkedQueuemay provide a good referenceHave priority values that are lower be considered “more important” (lower values get dequeued first)
Given the definition, all that matters is that when something gets dequeued, it has the most important priority
Enqueue with a linear search for the correct insertion spot (\(O(n)\)) and then always dequeue from the front (\(O(1)\))?
Or enqueue always append to the end (\(O(1)\)) and do a linear search for the most important priority on the dequeue (\(O(n)\))?
The former is suggested — have the enqueue find the correct spot to add the element, and have the dequeue simply remove from the front
An already complete
equalsandhashCodemethod for theLinkedPriorityQueueclass is providedLeave these alone
A complete
PriorityNodeclass contained within theLinkedPriorityQueueclass is providedLeave this alone
3.6.2. Implementing the Class
In order to complete the
LinkedPriorityQueue, write a constructor and implement all the required methods:boolean enqueue(T element, int priority)boolean enqueue(T element)T dequeue()T first()int size()boolean isEmpty()
Also write a
String toString()method for the class
3.6.3. Implementing the Unit Tests
The LinkedPriorityQueueTest class contains empty test methods, but each has a name that explains what the test
should do — complete all these methods. As a starting point, look at any of the unit tests for any of the
ADTs implemented.
There is no need to test the provided equals method as it has already been tested. Having a working equals makes
it safe to use assertEquals in the unit tests.
Having complete tests should help with debugging the LinkedPriorityQueue class.
3.7. Part 4 — Complete AStarMazeSolver
Read up on the A* algorithm. The linked article is great, and there are likely many YouTube videos on the subject.
One of the key parts of A* is the estimated cost function
\(f(x) = g(x) + h(x)\)
\(x\) is some maze cell
\(g(x)\) is the cost of getting to \(x\) from the start
\(h(x)\) is the heuristic’s estimated cost of getting to the end from \(x\)
\(f(x)\) is the total estimated cost of a path from start to finish going through \(x\)
3.7.1. Notes About the Implementation
\(g(x)\) will be the number of steps it takes to get to \(x\) from the start
\(h(x)\) will be the estimated distance to the end from \(x\) based on the Manhattan Distance
\(\lvert x_{1} - x_{2} \rvert + \lvert y_{1} - y_{2} \rvert\)
\(f(x)\) will be the priority of the cell \(x\)
3.7.2. Implementing the Class
Write the solve method to find an optimal path in the maze using A*.
The general idea is this
Dequeue from the priority queue
If it’s the end, done
If it’s not, calculate all the neighbours’ \(f(x)\) (priority) and add each to the priority queue
Repeat
Something for keeping track of the number of steps it takes to get to a given cell is needed
Perhaps a
Map?
Something for keeping track of each cell’s predecessor in the path is needed
Which cell was step from to get to the current cell?
Perhaps a
Map?
Feel free to use as many private helper methods as needed
Warning
Do not get distracted by the depth first search solution in DfsMazeSolver. Although there are similarities, the
actual algorithms have several noteworthy differences.
3.7.3. Implementing the Unit Tests
The AStarMazeSolverTest class contains a few constants and empty test methods. The constants are provided to help
with writing the tests. Each method has a name that explains what the test should do — complete all these methods. As
a starting point, look at the DfsMazeSolverTest class provided in previous assignment.
Having complete tests should help with debugging the AStarMazeSolver class.
3.8. Part 5 — Putting it Together
Once confident that the LinkedPriorityQueue and AStarMazeSolver are working correctly, write a main method.
Expect it to be short (less than 10 lines); if the main is long, something is wrong. The final main method is remarkably
similar to the one from the previous assignment.
In order to actually solve a maze, a few objects are needed
A
MazeA
MazeSolverto solve the mazeA
MazeRendererfor rendering the maze with the solution so it can be printed out
Run the program on the mazes from files. There is a provided RELATIVE_RESOURCES constant within the Asn3 class.
This is the relative path to the directory where the maze files are stored. Simply take this relative path and
concatenate it with the file name of the maze to be opened.
3.9. Part 6 — Testing
The correctness of the LinkedPriorityQueue and AStarMazeSolver classes may have already been verified by
completing and running their test classes. If not, do it!
If they have already been verified, for good measure, re-run all the tests provided and the ones completed for the assignment. If they all pass, one should be pretty confident that everything is working correctly.
There is no test provided for the Asn3 class, but that’s nothing to worry about. Get a sense that it is working
correctly by
Running the program on the maze files provided
Create new maze files and try running the program on them too
3.10. Some Hints
Work on one method at a time
Get each method working perfectly before you go on to the next one
Test each method as you write it
This is a really nice thing about programming; you can call your methods and see what result gets returned
Mentally test before you even write — what does this method do? What problem is it solving?
If you need help, ask
Drop by office hours
3.11. Some Marking Details
Warning
Just because your program produces the correct output, that does not necessarily mean that you will get perfect, or even that your program is correct.
Below is a list of both quantitative and qualitative things we will look for:
Correctness?
Did you follow instructions?
Comments?
Variable Names?
Style?
Did you do just weird things that make no sense?
3.12. What to Submit to Moodle
Make sure your NAME, SCHOOL EMAIL, and STUDENT NUMBER appear in a comment at the top of the classes
Submit the completed .java files to Moodle
LinkedPriorityQueue.java and LinkedPriorityQueueTest.java
AStarMazeSolver.java and AStarMazeSolverTest.java
Asn3.java
Do not submit the provided test classes
Do not submit the maze files
Do not submit the .class files
Do not compress the files
Warning
Verify that your submission to Moodle worked. If you submit incorrectly, you will get a 0.