Skip to content

niklasdikkafa/BrainBallSolver

Repository files navigation

BrainBall Solver

An IDA*-based solver and terminal visualizer for the BrainBall, a spherical rotation puzzle with 13 numbered, two-colored tiles.

BrainBall GIF

How the BrainBall works

The BrainBall is a ball with 13 tiles, numbered 1 to 13, arranged in a single ring around its circumference. Every tile is either white or yellow. The puzzle starts solved (all tiles white, in order 1-13) and is scrambled by repeatedly performing one of two physical moves:

  • 180° flip (turn180) - the whole ball is turned inside out. Every one of the 13 tiles changes color (white becomes yellow and vice versa), and the ring's direction reverses (clockwise becomes counter-clockwise).

  • Side turn (turnSides(index)) - the ball contains an axis in the middle. You can turn the tiles around and place specific tiles on this axis. Now the ball is rotated around this axis that runs through one specific tile. This axis splits the remaining 12 tiles into two arcs on either side: a 3-tile arc centered on the chosen tile, and, on the opposite side of the ball, a 4-tile arc. Turning the ball around this axis reverses the order of each arc internally and flips the color of every tile in both arcs (7 tiles in total: 3 + 4). The tile the axis passes through does not move position, but it does still flip color.

The goal is to get all 13 tiles back to white, in their original numerical order.

Because a turnSides move can leave the ball with fewer white tiles facing up than yellow ones, this solver always normalizes the ball back to the "white majority up" orientation with an extra turn180() whenever that happens - both at the very start of the search and after every move during the search. That is a bookkeeping/search convenience, not a move you need to make on the physical ball; the visualizer shows it as its own separate step so it is never confused with an actual side turn.

How the solving algorithm works

The solver uses IDA* (Iterative Deepening A*): a depth-first search that repeatedly re-runs itself with an increasing cost threshold, only exploring branches whose estimated total cost (f = g + h) is within that threshold. Compared to plain BFS/DFS this keeps memory usage low (no huge open/closed lists) while still finding a shortest solution, provided the heuristic h never overestimates the true remaining cost ("admissible").

Two things make this tractable for a puzzle with a branching factor of 13 (13 possible side-turns from every position):

  1. Reverse-move pruning. A state never immediately re-applies the turnSides index that was just used to reach it. This is not a correctness requirement, just a pruning heuristic that cuts the effective branching factor from 13 to 12 and avoids the search wasting time undoing its own last move.

  2. Pattern database heuristic. Before solving, the solver runs one backward breadth-first search starting from the solved configuration, up to 6 moves deep, recording the exact number of moves back to the goal for every state it reaches (a few million states, easily fits in memory). During the main search, whenever the current state is found in this database, that exact distance is used as h instead of an estimate - this is far more informative than any simple formula and is what makes the last few moves of the search fast. For states outside the database's reach, a cheap fallback estimate is used instead: (misplaced colors + misplaced tile numbers) / 7, divided by 7 because a single move can affect at most 7 tiles at once (this keeps the estimate admissible, i.e. it never overestimates).

Project structure

src/
  logic/
    BrainBallColor.java     - the WHITE/YELLOW enum
    BrainBallTile.java      - a single numbered, colored tile
    BrainBallState.java     - one ring configuration + the two moves
    BrainBallSolver.java    - the IDA* search + pattern database
    SolveResult.java        - solver output (path, flags) for the UI
  ui/
    BrainBallConsoleRenderer.java - draws the ball as a circle in the
                                     terminal and narrates each step
  app/
    Main.java               - demo entry point: scrambles a ball, solves
                                it, prints the solution

Running it

Requires a JDK (17+). From the src/ directory:

javac -d out $(find . -name "*.java")
java -cp out app.Main

The terminal needs ANSI color support (any modern terminal / IntelliJ's run console / VS Code's integrated terminal all work) to show the white/yellow tile backgrounds correctly.

Example output (excerpt)

Each step is printed as a circle of the 13 tiles, tile number on a background matching its color, with the tiles affected by the current move shown in bold:

Terminal Output Example

(exact layout depends on your terminal's font)

About

Using an IDA*-based algorithm to solve the BrainBall puzzle

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages