comp20003-project03/docs/SPECIFICATION.md
2024-06-13 14:25:56 +10:00

16 KiB
Raw Blame History

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

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 with tutorials (alternative without tutorials).

The code in this assignment was adapted from the open-source terminal version using ncurses made available by CorrentinB.

Game Rules

As explained in the Wikipedia 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. Boxes cannot be pulled, and they cannot be pushed to squares with walls or other boxes.

The number of boxes equals the number of storage locations.

The puzzle is solved when all boxes are placed at storage locations.

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 and best Sokoban solvers from 1980-2021. The best solver, Festival, was introduced at a conference last year, in 2020. A collaboration by a Google employee and a great professor Jonathan Schaeffer who made outstanding contributions to AI and games.

  • Relevant publications, 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

  • The juice of the great computational ideas & insights 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.

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.

Make sure you manage the memory well. 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 parent,

  • updates the state with the action chosen,

  • updates the depth of the node,

  • updates the priority (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 action 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 detection algorithm. Implement at least 1 deadlock detection method in this link.

Take a look at these 2 links for further optimization ideas & insights.

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.

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

For the visualiser to work, puzzles must be rectangular. If your map is not rectangular, just filled it in with walls instead of empty spaces.

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

./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:

./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:

./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:

./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:

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 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 and details on plagiarism. 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!