🧩 UbongoSolve
A Python solver for Ubongo-style tile-placement puzzles using constraint programming (OR-Tools CP-SAT).
Given a set of polyomino pieces and a board, UbongoSolver finds a placement that tiles the board exactly — no gaps, no overlaps.
Features
- Automatic piece orientation: handles all rotations (0°/90°/180°/270°) and flips
- Constraint programming engine: powered by Google OR-Tools CP-SAT for fast, exact solving
- Visualization: text-based and matplotlib-based solution display with colored pieces and piece-boundary outlines
- Built-in puzzles: includes the White Chocolate puzzle with a few board variants
Installation
Requires Python 3.10+.
pip install ubongosolve
From source
git clone https://github.com/kota7/ubongosolve.git
cd ubongosolve
pip install -U .
Quick Start
from ubongosolve import Piece, Board, UbongoPuzzle
# Define pieces as sets of (x, y) coordinates
pieces = [
Piece([(0,0), (0,1), (0,2), (0,3), (1,3)]), # L-shape
Piece([(0,0), (1,0), (1,1), (2,1)]), # S-shape
Piece([(0,0), (0,1), (1,1)]), # mini L-shape
]
# Define a board
board = Board([(x, y) for x in range(4) for y in range(3)])
# Solve
solver = UbongoPuzzle(pieces, board)
status = solver.solve()
print(status) # "OPTIMAL" or "FEASIBLE"
# View the solution
solver.print_solution() # text output
solver.plot_solution() # matplotlib figure
Example: Ubongo Sample problem
from ubongosolve import UbongoPuzzle, ubongo
problem = ubongo.sample_problems[0] # Two problems are included
solver = UbongoPuzzle(problem["pieces"], problem["board"])
solver.solve()
solver.plot_solution()
Example: White Chocolate puzzle
from ubongosolve import UbongoPuzzle, whitechocolate
# Solve the basic 5×8 board
solver = UbongoPuzzle(whitechocolate.pieces, whitechocolate.board)
solver.solve()
solver.plot_solution()
# Try a challenge board
solver = UbongoPuzzle(whitechocolate.pieces, whitechocolate.boards["challenge_6"])
solver.solve()
solver.plot_solution()
API Reference
Piece(coordinates)
A polyomino piece defined by a set of (x, y) cell coordinates. Coordinates are automatically normalized so the minimum x and y are zero.
Board(coordinates)
A board defined by a set of (x, y) cell coordinates. Can be any shape — rectangles, L-shapes, boards with holes, split boards, etc.
UbongoPuzzle(pieces, board)
| Method / Property | Description |
|---|---|
solve(timeout=100) |
Solve the puzzle. Returns status string ("OPTIMAL", "FEASIBLE", "INFEASIBLE", ...) |
solution |
dict[tuple[int,int], int] mapping each cell to its piece ID |
print_solution() |
Print an ASCII representation |
plot_solution() |
Display a matplotlib figure with colored pieces |
solution_as_fig |
Returns (fig, ax) without displaying |
How It Works
- Piece expansion: each piece is expanded into all distinct orientations (up to 8: 4 rotations × 2 flips).
- Origin candidates: for each orientation, all valid placements on the board are precomputed.
- CP-SAT model: boolean variables represent "piece i in orientation o is placed at origin (x, y)". Constraints enforce:
- Each piece is placed exactly once (one orientation + origin selected).
- Each board cell is covered by exactly one piece.
- Solve: OR-Tools CP-SAT finds a feasible assignment or proves infeasibility.
License
MIT
Metadata
Release files for ubongosolve 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ubongosolve-0.2.0.tar.gz | 9.0 kB | Without provenance | Details for ubongosolve-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ubongosolve-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for ubongosolve-0.2.0-py3-none-any.whl |
Total release size: 18.4 kB
Release files / ubongosolve-0.2.0.tar.gz
| Download URL | ubongosolve-0.2.0.tar.gz |
|---|---|
| Size | 9.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
35b63b479d959545f524128988f868169c9fee0374d08e1f60038f24b7281cdb
|
|
BLAKE2b-256 checksum How to use checksums |
cbdb9e2ad5e1bdd3f6e13765d5f56a4f2ab353f1ae823a12f91f1cab128e1efc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Release files / ubongosolve-0.2.0-py3-none-any.whl
| Download URL | ubongosolve-0.2.0-py3-none-any.whl |
|---|---|
| Size | 9.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7960cb97a2df70ae37b7d4681533195b3f0458d98af493b8843a5e0920a59556
|
|
BLAKE2b-256 checksum How to use checksums |
3616a0fa2deb3492bf2cfedbacf09edd3be0fd110c889cbc469703da4066f272
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Security for ubongosolve 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.