← Back to project summary

Parallel CA Simulator

A closer look at what it is, what is in it, and what I built.

What it does

  • Loads a starting world from a CSV file, one row per line and one integer state per cell, skipping blank lines and # comments.
  • Steps it with a pluggable ruleset: Game of Life, Brian's Brain, Seeds, Wireworld, or Langton's Ant, plus an identity rule for testing.
  • Draws each generation to a Swing window at one pixel per cell, scaled up so cells stay sharp blocks, with its own color map for each ruleset.
  • Starting patterns include the acorn, Wireworld logic gates, and a heart, on grids from 10 by 10 up to 1600 by 800.

How the parallel step works

  • Every step reads the current generation and writes a fresh grid, so no cell ever sees a half-updated neighbor.
  • The parallel step cuts the grid into horizontal bands, runs each band as a Scala Future on the global execution context, and stitches the results back together.
  • Neighbors wrap around the edges, and because the previous generation is read-only, bands can read across their borders without copying halo rows.
  • Langton's Ant needed a rewrite to go parallel. The first version keeps the ant's heading in shared mutable fields, so the parallel version stores the heading in the cell itself, with eight extra states for four directions on black or white.

What I built

  • The CSV loader, and a CSV runner that loads a world and steps a ruleset over it.
  • The JUnit suite: shared helpers for building and comparing worlds, and 21 tests that run every ruleset through the sequential step, the parallel step, and its rule directly.
  • Part of the sequential Langton's Ant.
  • Ben Smith built the world, ruleset, simulator, and renderer, including the parallel step and the space-bar toggle. Two classmates wrote Game of Life, Wireworld, Seeds, Brian's Brain, and the ant rulesets.

Known limitations

  • The parallel step always creates 8 bands but sizes them by the machine's core count, so the bands only cover the grid exactly on an 8-core machine. With more cores part of the grid is never computed, and with fewer the bands run past its edge.
  • The starting file can be passed as an argument, but choosing a ruleset means editing Main.
  • No benchmark results are committed, so there are no speedup numbers to report.