Getting Started
Install JCAL and run your first cellular automaton.
Installation
Option 1 — GitHub Maven Registry
JCAL is published on the GitHub Maven Registry. Follow the
GitHub guide
to configure authentication, then add this dependency to your pom.xml:
<dependency>
<groupId>io.github.carmelolg</groupId>
<artifactId>jcal</artifactId>
<version>1.0.0.alpha</version>
</dependency>Note: You need a GitHub personal access token with
read:packagesscope. See the linked guide for instructions on setting up your~/.m2/settings.xml.
Option 2 — Download the JAR
Download the latest release JAR from the Releases page and add it to your project’s build path as a local dependency.
Maven Central
Not yet available. Maven Central publication is planned for a future release.
Quick Start
The following example implements Conway’s Game of Life — a classic two-state 2D cellular automaton. It demonstrates all four steps of the JCAL workflow:
- Define the possible states (
DefaultStatus). - Specify the initial condition (which cells start alive).
- Configure the grid via
CellularAutomataConfigurationBuilder. - Implement the transition rule by extending
CellularAutomataRule.
Step 1 — Implement the transition rule
Extend CellularAutomataRule and implement transition. This method is called
once per cell per generation; return the cell’s next state.
public class GameOfLifeExecutor extends CellularAutomataExecutor {
@Override
public DefaultCell singleRun(DefaultCell cell, List<DefaultCell> neighbors) {
DefaultStatus dead = new DefaultStatus("dead", "0");
DefaultStatus alive = new DefaultStatus("alive", "1");
long aliveCount = neighbors.stream()
.filter(n -> n.getCurrentStatus().equals(alive))
.count();
boolean isAlive = cell.getCurrentStatus().equals(alive);
DefaultCell next = new DefaultCell(dead, cell.getCol(), cell.getRow());
if (!isAlive && aliveCount == 3) {
next.setCurrentStatus(alive); // dead cell with 3 live neighbors is born
} else if (isAlive && (aliveCount == 2 || aliveCount == 3)) {
next.setCurrentStatus(alive); // live cell survives with 2 or 3 neighbors
}
// otherwise the cell stays / becomes dead
return next;
}
}Step 2 — Configure and run
public class Main {
public static void main(String[] args) throws Exception {
DefaultStatus dead = new DefaultStatus("dead", "0");
DefaultStatus alive = new DefaultStatus("alive", "1");
// Set the initial live cells (a "blinker" oscillator)
List<DefaultCell> initialState = Arrays.asList(
new DefaultCell(alive, 5, 4),
new DefaultCell(alive, 5, 5),
new DefaultCell(alive, 5, 6)
);
CellularAutomataConfiguration config = new CellularAutomataConfigurationBuilder()
.setWidth(10)
.setHeight(10)
.setTotalIterations(2)
.setDefaultStatus(dead)
.setNeighborhoodType(NeighborhoodType.MOORE)
.setInitalState(initialState) // note: intentional spelling in the API
.build();
CellularAutomata ca = new CellularAutomata(config);
GameOfLifeExecutor executor = new GameOfLifeExecutor();
ca = executor.run(ca);
System.out.println(ca);
}
}Run the main method. The CA iterates for the configured number of steps and
prints the final grid to standard output.
Next steps
- Implementing a Rule — deeper dive into the executor pattern.
- Configuration Reference — all available builder options.
- Custom State Objects — model richer state with custom Java classes.