A collection of Puzzles bundled together in a simple yet powerful Python interface. Developed as of part of the UC Berkeley GamesCrafters.
Clone this repository and install the dependencies (it's recommended to use a virtualenv when installing dependencies of any project):
git clone https://github.com/GamesCrafters/GamesmanPuzzles.git
cd GamesmanPuzzles
pip install -r requirements.txt
pip install -e .
To get optional closed-form solver for Lights Out, run the following commands from the project's root directory:
cd puzzlesolver/extern
python setup.py build_ext --inplace
Run from the base directory of the repository
cd puzzlesolver/players
python tui.py hanoi
to play a puzzle of Towers of Hanoi.
You can solve all the puzzles by running the following in the base project directory:
python -m scripts.solve
Run from the base directory of the respository
python -m scripts.server
to access the webserver locally. The server should be running at http://127.0.0.1:9001/.
-
/health:-
Returns the current health and status of the service.
Health fields:
status: (String) Always "ok". Indicates that GamesmanPuzzles is online.http_code: (Integer) Always HTTP200. Indicates that GamesmanPuzzles is online.timestamp: (Integer) ISO 8601 UTC timestamp of when the health response was made (e.g.,"2025-05-16T20:25:55Z").uptime: (String) Time GamemsanPuzzles has been running inXd Yh Zm Wsformat.cpu_usage: (String) Process CPU utilization percentage (e.g.,"21.2%").memory_usage: (String) Process memory percentage of total physical memory (e.g.,"10.1%").
Below is an example response from
/health:{ "cpu_usage": "0.00%", "http_code": 200, "memory_usage": "0.12%", "status": "ok", "timestamp": "2025-05-29T18:07:35Z", "uptime": "0d 0h 0m 6s" }
-
-
/<puzzle_id>/<variant_id>/start/-
Returns the initial position of the variant of ID
variant_idof the puzzle of IDpuzzle_id. If the puzzle supports randomized starting positions, the content of the response will correspond to a random initial position.The response contains two fields:
position: (String) The human-readable string representation of the position.autoguiPosition: (String) The AutoGUI-formatted string corresponding to the position, which tells the frontend application how to render the position.
Below is an example response for
/npuzzle/3/start/which gives a starting position for the variant withvariant_id"3" of the puzzle withpuzzle_id"npuzzle" (i.e., the 8-Puzzle variant of the Sliding Number Puzzle).{ "position": "7-2453681", "autoguiPosition": "1_7-2453681" }Since the Sliding Number Puzzle supports randomized starting positions, this response is randomized. Below is another example response for
/npuzzle/3/start/.{ "position": "62-581374", "autoguiPosition": "1_62-581374" }
-
-
/<puzzle_id>/<variant_id>/positions/?p=<position_string>-
Returns information about the position specified by
position_stringof the variant specified byvariant_idof the game specified bygame_id. This is used, for example, by GamesmanUni when it needs to load a new position every time a user makes a move.When using this route to get information about a position,
position_stringshould be the human-readable string representation of the position, and NOT the AutoGUI-formatted position string corresponding to that position.The response contains the following fields:
position: (String) The human-readable string representation of the puzzle position.autoguiPosition: (String) The AutoGUI-formatted string corresponding to the position, which tells the frontend application how to render the position.positionValue: (String) The value of this position. This field will either bewin(the puzzle is solvable from this position) orlose(the puzzle cannot be solved from this position).remoteness: (Number, may be undefined) IfpositionValueiswin, i.e., the puzzle is solvable from this position, then this is a non-negative integer indicating the number of moves needed to solve the puzzle from this position. IfpositionValueislose, i.e., the puzzle cannot be solved from this position, then this field is undefined.moves: (Array): A list of move objects, in no particular order. If there are no legal moves from this position, this is an empty array. Each move object contains the following fields:move: (String) The human-readable string representation of the move.autoguiMove: (String) An AutoGUI-formatted move string, which tells the frontend application how to render the button that the user can click to make this move.position,autoguiPosition,positionValue,remotenessof the child position reached after making this move.
Below is the response for position
-87125364of the 8-Puzzle variant (variant_idof "3") of the Sliding Number Puzzle (puzzle_idof "npuzzle"), i.e., the response for/npuzzle/3/positions/?p=-87125364. The puzzle can be solved in as few as 28 moves and both legal moves make progress toward the solved state.{ "position": "-87125364", "autoguiPosition": "1_-87125364", "positionValue": "win", "remoteness": 28, "moves": [ { "autoguiMove": "M_1_0_x", "autoguiPosition": "1_8-7125364", "move": "8", "position": "8-7125364", "positionValue": "win", "remoteness": 27 }, { "autoguiMove": "M_3_0_x", "autoguiPosition": "1_187-25364", "move": "1", "position": "187-25364", "positionValue": "win", "remoteness": 27 } ] }
-
To run all the tests, run the following command:
pytest --cov puzzlesolver
Tips for exploring this repository:
- Follow the guides and learn how to create a puzzle and a solver!
- Definitely explore the puzzlesolver in depth.
- Understand what a puzzle tree is.
See contributing
Spring 2020: Anthony Ling, Mark Presten, Arturo Olvera
Fall 2020: Anthony Ling, Mark Presten, Brian Delaney, Yishu Chao, Sophia Xiao
Spring 2021: Anthony Ling, Mark Presten, Mia Campdera-Pulido
Fall 2022: Linh Tran
Spring 2023: Christopher Nammour
Current: Cameron Cheung, Robert Shi