Welcome! This repository is for a C++17 implementation of the Rush Hour sliding block puzzle game. A description of the board game can be found here.
The game instructions are simple, each vehicle can slide only in its normal direction of travel (forward and backward, not side-to-side). The goal is to clear a path such that the player car can escape the traffic jam via the opening on the right of the board.
The source code has been developed for academic purposes, i.e. to explore various solution algorithms and modern C++ containers in the STL. CMake files are provided to assist building the code. It is provided as free & open-source software.
-
A compiler that supports C++17
Install Command
-
Debian / Ubuntu (g++):
sudo apt update sudo apt install build-essential sudo apt-get install manpages-dev -
MacOS (g++):
brew install gcc -
Windows (cl):
Comes installed with Microsoft Visual Studio 2022
-
-
Install Command
-
Debian / Ubuntu:
sudo apt-get install cmake -
MacOS:
brew install cmake -
Windows:
Comes installed with Microsoft Visual Studio 2022
Download (alternative)
Alternatively, download and install from source.
-
-
Install Command
-
Debian / Ubuntu:
sudo wget -qO /usr/local/bin/ninja.gz https://github.com/ninja-build/ninja/releases/latest/download/ninja-linux.zip sudo gunzip /usr/local/bin/ninja.gz sudo chmod a+x /usr/local/bin/ninja ninja --version -
MacOS:
brew install ninja -
Windows:
Comes installed with Microsoft Visual Studio 2022
-
-
Git (required for dependency fetching)
Install Command
-
Debian / Ubuntu:
sudo apt install git -
MacOS:
brew install git -
Windows:
A limited version (suitable for use) comes installed with Microsoft Visual Studio 2022
-
-
Googletest
Googletest is used for generating and running tests. While this is a necessary dependency, retrieval and building is handled by theGoogleTestHelper.cmakefile. No action is required by as this is all automated. However, because Googletest is cloned from its github repository, a stable internet connection is required.
[toc]
RUSHHOUR/
├── cmake/
├── demos/
│ ├── CMakeLists.txt
│ └── cmdline/
│ └── CMakeLists.txt
├── sample_boards/
│ └── README.md
├── src/
│ ├── GameEngine/
│ │ ├── Vehicles/
│ │ │ ├── PhysicsEngine/
│ │ │ │ └── CMakeLists.txt
│ │ │ └── CMakeLists.txt
│ │ └── CMakeLists.txt
│ ├── Setup/
│ │ └── CMakeLists.txt
│ ├── Solvers/
│ │ └── CMakeLists.txt
│ └── CMakeLists.txt
├── test/
│ ├── GameEngine/
│ │ ├── Vehicles/
│ │ │ ├── PhysicsEngine/
│ │ │ │ └── CMakeLists.txt
│ │ │ └── CMakeLists.txt
│ │ └── CMakeLists.txt
│ ├── Setup/
│ │ └── CMakeLists.txt
│ ├── Solvers/
│ │ └── CMakeLists.txt
│ └── CMakeLists.txt
├── .gitignore
├── .gitmodules
├── CMakeLists.txt
├── CMakePresets.json
├── LICENSE
└── README.mdTo review each directory and file provided in the directory structure in detail, review the following Details.
Details
This is the parent directory for the project.
In addition to the directories described below, the parent directory contains:
- a
.gitignorefile, - a
.gitmodulesfile (described in more detail in the Prelude To Madness section), - the main (driver)
CMakeLists.txtfile, - a
CMakePresets.jsonfile (which contains each configuration / build / test preset, compiler settings, etc.), and - a
README.mdfile that contains build instructions (i.e. this file).
The cmake directory contains the CMake include files which are used to both simplify the CMakeLists.txt files and to modularize the build system.
The demos directory contains a single CMakeLists.txt file and subdirectories for all of the different types of demos.
The cmdline directory contains the source code for running demos of the Rush Hour Game / AI engine from the command line:
- *.hpp for C++ header files
- *.cpp for C++ source files
The cmdline directory contains a CMakeLists.txt file which handles compiling and linking for the command line demo executable.
The sample_boards directory is where sample board layouts are kept as text files. More details regarding sample boards can be found in the Run Command Line Demo section of this README.
The src directory is where all of the source code for the rush hour game, solvers, physics, etc. is provided:
- *.hpp for C++ header files
- *.cpp for C++ source files
The src directory contains a CMakeLists.txt file which handles compiling the engine source code into a static library. Other subdirectories are located in the src directory with thier own CMakeLists.txt files for automatic inclusion in a build.
The test directory is where all of the source code for unit testing the rush hour game, solvers, physics, etc. is provided:
- *.hpp for C++ header files
- *.cpp for C++ source files
The test directory is constructed to mirror the src directory so that finding tests for associated functions / routines in the src directory should be relatively straightforward.
The googletest framework is used. It is automatically downloaded and included in the build by CMake.
[toc]
The project uses CMake to generate a build configuration and the Ninja generator to compile the source code (see Prerequisites). The CMake build configuration is controlled by the supplied CMakePresets.json file in the RUSHHOUR/ parent directory.
NOTE: A preset must be reconfigured anytime there is a change made to the CMakePresets.json file which affects that preset (or a configuration from which the preset inherits). Changes to the source code do not require a preset to be reconfigured, the preset can just be directly rebuilt.
Debian / Ubuntu / MacOS build instructions
To build a configuration, the CMake preset for that configuration must first be initialized. To view the list of available preset configurations, in the RUSHHOUR/ parent directory
cmake --list-presetsA preset configuration can then be initialized from the RUSHHOUR/ parent directory
cmake --preset=<preset-name>where <preset-name> is one of the presets produced from the cmake --list-presets command (e.g. rush-hour-release-linux).
The preset is then build from the RUSHHOUR/ parnet directory
cmake --build --preset=<preset-name>where <preset-name> is the preset just configured.
Windows build instructions
Open the project in Visual Studio. Visual Studio will automatically generate the configurations from the detected CMake files. Select the desired configuration to run from the drop-down in the configuration ribbon.
Select Build rush_hour_cmdline_demo.exe from the Build dropdown menu.
Build artifacts
The build artifacts are produced in the out/build/<preset-name> directory, where <preset-name> is the preset built.
Build artifacts - Libraries
Library build artifacts are produced in the out/build/<preset-name>/lib directory, where <preset-name> is the preset built.
Build artifacts - Demo Executables
Demo executable build artifacts are produced in the out/build/<preset-name>/bin directory, where <preset-name> is the preset built.
[toc]
Generally, a run command from the out/build/<preset-name>/bin directory has the structure
./rush_hour_cmdline_demo <command> <option1>where command can be
printdonefilenextrandomastarbfsbfs_as_astardfs
and option1 provides three (3) run options for the command line demo to be run, namely,
- default mode
- command line string representing the board configuration
- text file holding the board configuration
NOTE: ./rush_hour_cmdline_demo will require the addition of .exe when running in Windows.
Run Modes
default mode
Default mode is enabled if option1 is left blank.
In default mode the default board, which is hard-coded, is used for all commands (with the exception of file, as described below).
Default mode is mainly in place for testing / demonstration purposes.
command line string representing the board configuration
The command line demo application can be run using a string on the command line to represent the board. For example
./rush_hour_cmdline_demo random " oaa | o | oxx | pppq| q| q"Note: The string is provided in " ".
The | represent new rows and are not provided at the beginning and end of the string.
All rows must be the same width (including spaces).
The code will automatically deduce the exit row from the row containing the player vehicle (denoted by 'x').
text file holding the board configuration
The command line demo application can be run using a prestored text file representing the board configuration.
This mode is enabled with the file command, which is desribed below in greater detail.
Command Descriptions / Details
The print command prints the initial board configuration to the terminal. For example
./rush_hour_cmdline_demo printBoard configuration:
------
| o aa|
| o |
|xxo
|ppp q|
| q|
| q|
------and
./rush_hour_cmdline_demo print " ooo |ppp q |xx qa|rrr qa|b c dd|b c ee"Board configuration:
------
| ooo |
|ppp q |
|xx qa
|rrr qa|
|b c dd|
|b c ee|
------done
The done command is used to identify if an initial board configuration is in a solution state. For example
./rush_hour_cmdline_demo doneBoard configuration:
------
| o aa|
| o |
|xxo
|ppp q|
| q|
| q|
------
Solution state? falseand
./rush_hour_cmdline_demo done " oaa | o | o xx| pppq| q| q"Board configuration:
------
| oaa |
| o |
| o xx
| pppq|
| q|
| q|
------
Solution state? truefile
The file command is a special command that is used to read a file that contains an input board configuration and then perform some action. Use of the file command requires the form
./rush_hour_cmdline_demo file <path/location> <command>path/location is the relative path from the build folder to the text file containing the board configuration, or an absolute path on the user system. Sample board configurations are supplied in the sample_boards/ directory.
command can be any of the commands listed above, with the exception of file (for obvious reasons).
next
The next command prints all the possible next board states from the initial board state. That is, the set of possible board states that can be reached from the given board state with a single movement of a single vehicle.
random
The random command provides a random walk through the next board states. It
- generates all moves that can be generated can be reached from the given board state with a single movement of a single vehicle
- selects one at random
- executes that move
- stops if the goal state is reached OR if it has executed 10 moves, otherwise, it repeats.
It is hard coded for 10 moves, but this can be easily modified, if desired.
astar
The astar command performs an A* search for a solution. It will either find a solution, print the number of moves it explored whilst searching for the solution, and print the solution path, OR it will fail to find a solution and print the number of moves it explored whilst searching for the solution. An example of an A* run using a sample board is
./rush_hour_cmdline_demo file ../../../../sample_boards/sample5.txt astarBoard configuration:
------
|paaq |
|p q |
|pxxq
|b o|
|bcc o|
| rrro|
------
Solution found!
9 moves explored.
Solution path:
------ ------ ------ ------
|paaq | |paaq | |paa | |paa |
|p q | |p q | |p | |p |
|pxxq |pxxq |pxx |p xx
|b o| |b o| |b q o| |b q o|
|bcc o| |bcc o| |bccq o| |bccq o|
| rrro| |rrr o| |rrrq o| |rrrq o|
------ ------ ------ ------ The A* routine uses a combination of the manhattan distance and the number of vehicles blocking the player vehicle from exiting the board as its heuristic function.
bfs
The bfs command performs a breadth-first search for a solution. It will either find a solution, print the number of moves it explored whilst searching for the solution, and print the solution path, OR it will fail to find a solution and print the number of moves it explored whilst searching for the solution.
bfs_as_astar
The bfs_as_astar command performs a breadth-first search for a solution. It calls the A* search algorithm with a heuristic function == 0. It will either find a solution, print the number of moves it explored whilst searching for the solution, and print the solution path, OR it will fail to find a solution and print the number of moves it explored whilst searching for the solution. This is provide to demonstrate the relationship between breadth-first search and A*.
dfs
The dfs command performs a depth-first search for a solution. It will either find a solution, print the number of moves it explored whilst searching for the solution, and print the solution path, OR it will fail to find a solution and print the number of moves it explored whilst searching for the solution.
[toc]
This code is provided free and open source for educational purposes. The code is provided for learning and not necessarily optimized for efficiency or compactness. It is solely the work of the author.
[toc]