top | item 45587666

Show HN: I modeled the puzzle game Railbound with Constraint Programming

2 points| th1nhng0 | 4 months ago |github.com

Hi HN, I've been working on a solver for the puzzle game Railbound and wanted to share it.

The backstory is that I'm a big fan of the game and was curious if I could model its logic using constraint programming. I used MiniZinc to build it. The project treats each puzzle as a constraint satisfaction problem—it defines the rules of the game (how tracks connect, how switches work, etc.) and then searches for a layout that solves the level.

It's different from other solvers because it's a declarative model rather than an imperative search algorithm. It was a fun challenge to translate mechanics like timed gates, dynamic switches, and decoy cars into formal constraints.

You can run it on your own machine. The repo has instructions, but the basics are: 1. Install the MiniZinc IDE/toolchain. 2. Clone the repo. 3. Run a command like minizinc --solver or-tools main.mzn data/1/1-1.dzn

The project is open source and currently solves the first 8 worlds of the game.

Repo: https://github.com/Th1nhNg0/railbound_cp

I'm here to answer any questions. I'd love to hear your feedback.

4 comments

order

mzl|4 months ago

Very nice project. Do you have some statistics for how long it takes to solve the harder instances for different solvers? One thing to note for that, is that I saw the default parallelism of 4 in the run file. OR-Tools CP-SAT works best if it is given at least 8 threads to work with.

Have you considered using records for some of the data definitions? For example, a record `(row: int, col: int, piece: Piece)` for pre-placed pieces to avoid having .1, .2 and so on in the models. If you are concerned with the size of the data files, one way to handle that is to have the data as a list of tuples that are mapped via a function from a tulle to the record.

th1nhng0|4 months ago

Thanks for the great feedback! I didn't know OR-Tools CP-SAT worked best with at least 8 threads; I'll definitely try that out.

In my local tests, Chuffed is often faster on the simpler instances. However, I've noticed on the harder puzzles, Chuffed can take over 10 minutes, while OR-Tools (with just 4 threads) solves them in about 5.

You're also right about the records. I started with tuples for simplicity, but as the model grew more complex, it's clear that records would be a much better approach for readability.