Skip to content

A bit of code I wrote for constructing the state graph of a puzzle. The code is designed to be compatible with any puzzle with a state that can be described as set of variables with discrete states (i.e. an array of integers). I've included an implementation of an example puzzle.

Notifications You must be signed in to change notification settings

musinggriffin/PuzzleGrapher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 

Repository files navigation

PuzzleGrapher

This repo holds sample code from a small experiment I did in 2017. I was interested in generalized software for analyzing and constructing puzzles. This code is a prototype for an important component of such software, a puzzle agnostic state explorer. It works with any puzzle for which each state can produce a unique hashcode. This is used to perform a breadth-first exploration of the puzzle's state graph.

There are two groups of scripts in this file: The agnostic puzzle graphing code itself, and an example implentation based on the mechanics of the Kami mobile games.

How the agnostic puzzle grapher works: The graph is created during the construction of a StateGraph object. Stategraph's constructor takes an argument that implements the IPuzzle interface. The main method provided by this interface is the GetReachableStates method. This method takes an IPuzzleState object and returns an array of puzzle state objects (objects that implement IPuzzleState) that contain all the states that the given state can transition into through player input. The StateGraph uses this method to perform a breadth-first exploration outward from the initial state, building out a dictionary of StateNode objects (which holds a state object along with some metadata). The dictionary is keyed with the unique hashcode's of each state, allowing the algorithm to keep track of which states have already been explored.

How the Kami puzzle implementation works: I decided to use a mobile puzzle game I enjoyed playing as a test case, Kami 2 by State of Play Games. Kami puzzles start as a quilt of areas in different colors. The player uses a "paintbucket" mechanic to fill an area in with a different color, causing it to merge with adjacent areas that share that new color. To solve each puzzle, the player must strategically fill areas in order to paint the entire screen one color within a finite number of steps. KamiPuzzle implements the IPuzzle interface, and KamiState implements IPuzzleState. I used a couple of tricks to optimize the internal workings of KamiPuzzle. Each state's hashcode is based of the current colors of the initial areas. However, each KamiState also contains an array of current colored areas, which use bitmasks to describe which starting area they contain. The bitmasks make it cheap and easy to compare and merge areas. Adjacency relationships also use bitmasks, and KamiPuzzle memoizes a dictionary of area-to-adjacency pairs so that this doesn't need to be calculated more than once for any combination of starting areas. I use the ColorArea struct to store the data for each superarea. There are two other scripts in the repo. KamiPuzzleBuilder is a Unity3D monobehavior that I use to actually test the code. It takes a description of a Kami Puzzle in a very raw format (currently I am manually entering in the initial adjacency bitmasks for the starting areas) and then constructs a KamiPuzzle object and then a StateGraph. KamiPuzzleEditor is the custom inspector script for KamiPuzzleBuilder.

About

A bit of code I wrote for constructing the state graph of a puzzle. The code is designed to be compatible with any puzzle with a state that can be described as set of variables with discrete states (i.e. an array of integers). I've included an implementation of an example puzzle.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages