Implementing a Rule


The transition function

In JCAL, the transition function (σ) is the core of any cellular automaton. It determines how each cell evolves from one generation to the next.

To define a transition function, extend CellularAutomataExecutor and implement the singleRun method. JCAL calls this method once per cell per generation, passing the current cell and its neighbors. Return a new DefaultCell carrying the cell’s next state.

singleRun(cell, neighbors) → next cell state

Example: Conway’s Game of Life executor

public class GOLExecutor extends CellularAutomataExecutor {

	@Override
	public DefaultCell singleRun(DefaultCell cell, List<DefaultCell> neighbors) {
		
       	DefaultStatus dead = new DefaultStatus("dead", "0");
       	DefaultStatus alive = new DefaultStatus("alive", "1");
		Long alives = neighbors.stream().filter(item -> item.currentStatus.equals(alive)).count();	
		DefaultCell toReturn = new DefaultCell(null, cell.getRow(), cell.getCol());	
		if (cell.currentStatus.equals(dead) && alives == 3) {
			toReturn.currentStatus = alive;
		} else if (cell.currentStatus.equals(alive) && (alives == 2 || alives == 3)) {
			toReturn.currentStatus = alive;
		} else {
			toReturn.currentStatus = dead;
		}
		return toReturn;
	}
}

Running the cellular automaton

Once you have an executor, wire it together with a configured grid and call run:

public class Main {

	public static int WIDTH = 10, HEIGHT = 10;

	public static DefaultStatus dead = new DefaultStatus("dead", "0");
	public static DefaultStatus alive = new DefaultStatus("alive", "1");
	public static List<DefaultStatus> status = Arrays.asList(dead, alive);
	public static List<DefaultCell> initalState = new ArrayList<DefaultCell>();
	
	public static void main(String[] args) throws Exception {

		initalState.add(new DefaultCell(alive, 1, 1));
		initalState.add(new DefaultCell(alive, 1, 2));
		initalState.add(new DefaultCell(alive, 1, 3));
		initalState.add(new DefaultCell(alive, 2, 1));
		
	    
        CellularAutomataConfigurationBuilder configBuilder = new CellularAutomataConfigurationBuilder();
        CellularAutomataConfiguration config = configBuilder.setHeight(WIDTH)
                                                            .setWidth(HEIGHT)
                                                            .setTotalIterations(10)
                                                            .setDefaultStatus(Main.dead)
                                                            .setNeighborhoodType(NeighborhoodType.MOORE)
                                                            .setInitalState(initalState)
                                                            /** ... */
                                                            .build();
	    
		CellularAutomata ca = new CellularAutomata(config);
		GOLExecutor executor = new GOLExecutor();
		ca = executor.run(ca);
		System.out.println(ca);
	}
}

Parallel execution

For large grids, replace CellularAutomataExecutor with CellularAutomataParallelExecutor. The singleRun signature is identical; JCAL distributes the work across threads automatically.

public class MyParallelRule extends CellularAutomataParallelExecutor {
    @Override
    public DefaultCell singleRun(DefaultCell cell, List<DefaultCell> neighbors) {
        // same logic as the sequential version
    }
}

See also