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:packages scope. 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:

  1. Define the possible states (DefaultStatus).
  2. Specify the initial condition (which cells start alive).
  3. Configure the grid via CellularAutomataConfigurationBuilder.
  4. 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