My Project
Documentation

Basic information

Sokoban is a logic game in which player tries to move barrels on marked places in a maze.

This application for Windows contains basic engine for standard Sokoban game (single player). To play the game is necessary to be logged in as a user (text box + button login). The name of user may not contain the character ;. The next step is to load a game pack (button load) which consist of several map. The game progress is saved for the logged user within the map pack. Character (Sokoban) is controlled by the arrows. There is a timer which measures the length of solving map. The best time for map and the best time for logged user is recorded. It is possible to let the program solve loaded map (button solve) and then to play the solution step by step (button next). To restart current map there is a button restart. There is also an option to load map pack which contains the maps with two Sokoban (multiplayer game) but there is no solver implemented yet for such game. The second sokoban is controlled by the keys w, a, s, d.

Data files for maps

Map pack file

Maps are grouped to map pack. The map pack file consists of the identifier on the first line, type of maps on the second line (SP for single player, MP for two player) and the paths to a map data files. Every path has to be on the separate line. The identifier must not contain the characters ; nor +.

There is two map pack files as examples. The first map_pack_1.txt contains single player maps, the second map_pack_2.txt contains maps for two player.

Map file

Map is stored in text format. Each map is in a separate file. Each line represents one row of the map grid. The elements of map are represented by digits where ground = 0, target for barrel = 1, barrel = 2, barrel on target = 3, sokoban = 4, sokoban on target = 5, wall = 6, grass = 7, second sokoban = 8, second sokoban on target = 9. The map has to be rectangular. To fulfill this requirement there is the element grass. At the end of file there has to be x on a separate line. Here is an example of the map file.

6667777
6166666
6110006
6022246
6000066
6666667
x

Used library

The GUI is provided by the library Cinder.

Compilation

There is Visul Studio .sln project in folder vc2013.

Implementation overview

The main class of this app is SokobanApp which represents the window and the user interface.

Representation of map

Maps are represented by the abstract class Map which provides an interface for SokobanApp and it is the ancestor for SinglePlayerMap and TwoPlayerMap. Game grid is represented by the array game_grid which contains game elements whose position is not changed during playing (ground, target for barrel, wall and grass).

The current game configuration for map is stored in the structure GameState which contains the position of sokoban, list of barrels for simple recognition the dead position - position when the barrel is not possible to move anymore (it is used in solving), barrel grid for simple recognition if there is a barrel on the position x,y (barrel is represented by its index to the list of barrels + 1) and hash which is the string with the same information as the barrel grid but every barrels have the same representation (not the index). Hash also contains information of Sokoban position and it is used in solving to determine which game configurations were visited. Map solving is realized by backtracking. For the two player map there is a special game state which includes position of the second sokoban of course. Since solver for two player map is not implemeted, hash and barrel list is not used yet in such game state.

Representation of user

User is represented by the class User which stores user's progress in the collection map indexed by the map indentifier. For writing progress to the data file there is implemeted operator <<.

Representation of highscore

Highscore is represented by the class Highscore. It consists of two collections std::unordered_map. The first maps the name of map name ("mapPackIdentifier+numberOfMap") to the name of user which has the best highscore for this map. The second one maps user and map name to the time of user on this map. That means it is possible to extract the best time for map and user which has this best time and also the best time of user on map.

Timer

To measure time there is a class MyTimer using std::chrono. It has the method for getting current time since start in string (format hh:mm:ss). Since there is more demands for current time during a second, this class remebers the last value. If it is the same as current time there is no redundant conversion to the string.