comp20003-project03/docs/SPECIFICATION.md

251 lines
16 KiB
Markdown
Raw Normal View History

2024-06-13 14:25:56 +10:00
# Assignment Specification
Below is the assignment specification, in full, slightly edited for context and appearence.
## Purpose
The purpose of this assignment is for you to:
- Increase your proficiency in C programming, your dexterity with dynamic memory allocation and your understanding of data structures, through programming a search algorithm over Graphs.
- Gain experience with applications of graphs and graph algorithms to solving combinatorial games, one form of artificial intelligence.
## Sokoban
![](./images/image01.png)
In this assignment, youll be expected to build an AI algorithm to solve Sokoban. The game invented in 1980 (program released in 1982) is one of the classics among arcade puzzle games. You can play the game compiling the code given to you using the keyboard, or using this [web implementation](https://www.sokobanonline.com/) with tutorials ([alternative](https://sokoban.info/) without tutorials).
The code in this assignment was adapted from the open-source terminal version using [ncurses](https://invisible-island.net/ncurses/) made available by [CorrentinB](https://github.com/CorentinB/sokoban).
### Game Rules
![](./images/game-rules.gif)
As explained in the [Wikipedia](https://en.wikipedia.org/wiki/Sokoban) entry, the game is played on a board of squares, where each square is a floor or a wall. Some floor squares contain boxes, and some floor squares are marked as storage locations.
The player is confined to the board and may **move horizontally or vertically** onto empty squares (never through walls or boxes). The player can **move a box** by walking up to it and **pushing** it to the square beyond. <u>Boxes cannot be pulled</u>, and they <u>cannot be pushed to squares with walls or other boxes</u>.
The **number of boxes equals the number of storage locations**.
The puzzle is solved when <u>**all boxes are placed at storage locations**</u>.
### For the curious reader - the science of Sokoban
Here is some interesting material for those that want to take a deeper dive on Sokoban Solvers.
- [Official benchmarks and results](http://sokobano.de/wiki/index.php?title=Solver_Statistics) and best Sokoban solvers from 1980-2021. The best solver, [Festival](https://festival-solver.site/), was introduced at a conference last year, in 2020. A collaboration by a Google employee and a great professor [Jonathan Schaeffer](http://webdocs.cs.ualberta.ca/~jonathan/) who made outstanding contributions to AI and games.
- [Relevant publications](http://sokoban.dk/science/), A great starting point in that list is to read Andreas Junghanns Ph.D. dissertation about Sokoban. 1999. Pushing the Limits: New Developments in Single-Agent Search. *Ph.D. Dissertation, University of Alberta, 1999.*
- Everything about Sokoban: [WIKI](http://sokobano.de/wiki/index.php?title=Main_Page)
- The juice of the great [computational ideas](http://sokobano.de/wiki/index.php?title=Solver) & [insights](http://sokobano.de/wiki/index.php?title=Sokoban_solver_%22scribbles%22_by_Florent_Diedler_about_the_Sokolution_solver#Heuristic_score) behind the best Sokoban solvers.
## The Algorithm
A configuration of the Sokoban game is specified by the location of walls, boxes, storage areas and player. A configuration is called a *state*. The Sokoban Graph $G=\langle V, E \rangle$ is implicitly defined. The vertex set $V$ is defined as all the possible configurations (states), and the edges $E$ connecting two vertexes are defined by the legal movements **(right, left, up, down).** All edges have a weight of 1.
Your task is to find the path traversing the Sokoban Graph from the initial state (vertex) leading to a state (vertex) where all the boxes are located on a storage area. The best path is the shortest path. A path is a sequence of movements. You are going to use Dijkstra to find the shortest path first, along with some game-specific optimizations to speed up your algorithm.
When the AI solver is called (Algorithm 1), it should explore all possible paths (sequence of move actions) following a Dijktsra strategy, until a path solving the game is found. Note that we use transposition tables to avoid duplicate states in the search. If a state was already expanded (popped from the priority queue), we will not include it again in the priority queue (line 23 in Algorithm 1). We will also ignore states where the player doesn't move as a result of moving towards an adjacent wall, or a box which cannot move (line 18). We will finally avoid states where boxes are located in a corner (line 18, see file `utils.h`). The algorithm should return the **best solution found**. This path will then be executed by the game engine if the option `play_solution` was used as an argument.
![](./images/image02.png)
You might have multiple paths leading to a solution. **Your algorithm should consider the possible actions in the following order**: left, right, up or down.
<u>Make sure you manage the memory well.</u> When you finish running the algorithm, you have to free all the nodes from the memory, otherwise you will have memory leaks. You will notice that the algorithm can run out of memory fairly fast after expanding millions nodes.
The `applyAction` creates a **new node**, that
- points to the <u>parent</u>,
- updates the <u>state</u> with the action chosen,
- updates the <u>depth</u> of the node,
- updates the <u>priority</u> (used by the priority queue) of the node to be the negative node's depth d (if the node is the dth step of the path, then its priority is -d). This ensures the expansion of the shortest paths first, as the priority queue provided is a max heap,
- updates the <u>action</u> used to create the node.
Check the file `utils.h, hash_table.h, priority_queue.h` where you'll find many of the functions in the algorithm already implemented. Other useful functions are located directly in the file `ai.c` , which is the only file you need to edit to write your algorithm inside the function `findSolution` . Look for the comment `FILL IN THE GRAPH ALGORITHM` . All the files are in the folder `src/ai`.
## Deliverables
You are expected to hand in the source code for your solver, written in C. Obviously, your source code is expected to compile and execute flawlessly using the following makefile command: `make` generating an executable called `sokoban`. Remember to compile using the optimization flag `gcc -O3` for doing your experiments, it will run twice as quickly as compiling with the debugging flag `gcc -g` (see `Makefile`, and change the `CC` variable accordingly). For the submission, please **submit your makefile with `gcc -g` option**, as our scripts need this flag for testing. Your program must not be compiled under any flags that prevents it from working under gdb or valgrind.
Your implementation should work well over the first 3 layouts, but it will not be expected to find a solution to any layout, as it may exceed the available RAM in your computer before finding a solution. Feel free to explore maps given in the folder `maps_suites.` They are taken from the official benchmarks of sokoban. All you have to do is to copy and paste a single map into a new file, and then call it with your solver.
### Deadlock Detection (optimizations)
The simplest way to improve the code is by improving the [deadlock](http://sokobano.de/wiki/index.php?title=Deadlocks) detection algorithm. Implement at least 1 deadlock detection method in this link.
Take a look at these 2 links for further optimization [ideas](http://sokobano.de/wiki/index.php?title=Solver) & [insights](http://sokobano.de/wiki/index.php?title=Sokoban_solver_%22scribbles%22_by_Florent_Diedler_about_the_Sokolution_solver#Heuristic_score).
If you do any optimizations & change of Data Structures used & deadlock detection improvement, please make sure to explain concisely **what** it is that you implemented, **why** you chose that optimization, **how** it affects the performance (show number of expanded nodes before and after the optimization for a set of test maps), and **where** the code of the optimizations is located. This explanation should be included in the file located at the root of the basecode: `Report.md`. Please make sure that your solver still returns the optimal solution.
## Rubric
Assignment marks will be divided into three different components.
1. Solver (12)
2. Code Style (2)
3. Optimizations (1)
Please note that you should be ready to answer any question we might have on the details of your assignment solution by e-mail, or even attending a brief interview with me, in order to clarify any doubts we might have.
## Maps & Solution formats
### Puzzle file format
We adapted the sokoban file reader to support the following specification, but we don't support comments specified by `%`.
| **Symbol** | **Represents** |
| ----------- | --------------- |
| # | Wall |
| ` ` (space) | Empty space |
| . | Goal |
| @ | Sokoban |
| $ | Box |
| + | Sokoban on Goal |
| * | Box on Goal |
| % | Comment |
### Solution file format
Solutions returned by the solver follow this format. You can load your map and solution into the [JS Visualiser](#js-visualiser).
| **Symbol** | **Represents** |
| ---------- | -------------- |
| l | Move left |
| r | Move right |
| u | Move up |
| d | Move down |
| L | Push left |
| R | Push right |
| D | Push down |
| U | Push up |
## JS Visualiser
2024-06-13 14:32:00 +10:00
For the [visualiser](https://web.archive.org/web/20210430155801/https://www.cs.rochester.edu/u/kautz/sokoban/Sokoban.html) to work, puzzles must be rectangular. If your map is not rectangular, just filled it in with walls instead of empty spaces.
2024-06-13 14:25:56 +10:00
![](./images/image03.png)
## The Code Base
You are given a base code. You can compile the code and play with the keyboard (arrows). You are going to have to program your solver in the file `ai.c`. Look at the file `main.c` (main function) to know which function is called to call the AI algorithm.
You are given the structure of a node, the state, a max-heap (priority queue) and a hashtable implementation to check for duplicate states efficiently (line 23 in the Algorithm 1). Look into the `utils.*` files to know about the functions you can call to apply an action to update a game state. All relevant files are located in the folder `src/ai`.
In your final submission, you are free to change any file, but make sure the command line options remain the same.
### Input
You can play the game with the keyboard by executing
```bash
./sokoban map_file.txt
```
where `map_file.txt` is a file containing the sokoban problem to solve.
In order to execute your AI solver use the following command:
```bash
./sokoban -s map_file.txt play_solution
```
The `-s` flag calls your algorithm. `play_solution` is optional, and if typed in as an argument, the program will play the solution found by your algorithm once it finishes. All the options can be found if you use option `-h`:
```bash
./sokoban -h
USAGE
./sokoban <-s> map <play_solution>
DESCRIPTION
Arguments within <> are optional
-s calls the AI solver
play_solution animates the solution found by the AI solver
```
For example:
```bash
./sokoban -s test/maps/test_map2 play_solution
```
Will run the 2nd map expanding and will play the solution found.
### Output
Your solver will print into an `solution.txt` file the following information:
1. Solution
2. Number of expanded nodes.
3. Number of generated nodes.
4. Number of duplicated nodes.
5. Solutions length
6. Number of nodes expanded per second.
7. Total search time, in seconds.
For example, the output of your solver `./sokoban -s test/maps/test_map2` could be:
```bash
SOLUTION:
rrrrrrdrdLLLLLLLLullluRRRRRRRururRRRRRRRRRR
STATS:
Expanded nodes: 978745
Generated nodes: 3914976
Duplicated nodes: 2288345
Solution Length: 43
Expanded/seconds: 244506
Time (seconds): 4.002942
```
Expanded/Second is computed by dividing the total number of expanded nodes by the time it took to solve the game. A node is expanded if it was popped out from the priority queue, and a node is generated if it was created using the `applyAction` function. This code is already provided.
## Programming Style
[This](./programming-style.c) is a style guide which assignments are evaluated against. For this subject, the 80 character limit is a guideline rather than a rule - if your code exceeds this limit, you should consider whether your code would be more readable if you instead rearranged it.
Some automatic evaluations of your code style may be performed where they are reliable. As determining whether these style-related issues are occurring sometimes involves non-trivial (and sometimes even undecidable) calculations, a simpler and more error-prone (but highly successful) solution is used. You may need to add a comment to identify these cases, so check any failing test outputs for instructions on how to resolve incorrectly flagged issues.
## Plagiarism
This is an individual assignment. The work must be your own.
While you may discuss your program development, coding problems and experimentation with your classmates, you must not share files, as this is considered plagiarism.
**If you refer to published work in the discussion of your experiments, be sure to include a citation to the publication or the web link.**
“Borrowing” of someone elses code without acknowledgment is plagiarism. Plagiarism is considered a serious offense at the University of Melbourne. You should read the University code on [Academic integrity](https://academicintegrity.unimelb.edu.au/) and details on [plagiarism](https://academicintegrity.unimelb.edu.au/#plagiarism-and-collusion). Make sure you are not plagiarizing, intentionally or unintentionally.
You are also advised that there will be a C programming component (on paper, not on a computer) in the final examination. Students who do not program their own assignments will be at a disadvantage for this part of the examination.
## Late Policy
The late penalty is 10% of the available marks for that project for each day (or part thereof) overdue. Requests for extensions on medical grounds will need to be supported by a medical certificate. Any request received less than 48 hours before the assessment date (or after the date!) will generally not be accepted except in the most extreme circumstances. In general, extensions will not be granted if the interruption covers less than 10% of the project duration. Remember that departmental servers are often heavily loaded near project deadlines, and unexpected outages can occur; these will not be considered as grounds for an extension.
Students who experience difficulties due to personal circumstances are encouraged to make use of the appropriate University student support services, and to contact the lecturer, at the earliest opportunity.
**Finally, we are here to help!** There is information about getting help in this subject on the LMS. Frequently asked questions about the project will be answered on Ed.
## Additional Support
Your tutors will be available to help with your assignment during the scheduled workshop times. Questions related to the assignment may be posted on the Ed discussion forum, using the folder tag Assignments for new posts. You should feel free to answer other students questions if you are confident of your skills.
A tutor will check the discussion forum regularly, and answer some questions, but be aware that for some questions you will just need to use your judgment and document your thinking. For example, a question like, “How much data should I use for the experiments?”, will not be answered; you must try out different data and see what makes sense.
If you have questions about your code specifically which you feel would reveal too much of the assignment, feel free to post a private question on the discussion forum.
**Have fun!**