Custom State Objects


The built-in DefaultStatus holds a key (String) and a value (any Object), which is sufficient for simple automata such as a binary-state Game of Life. For more complex simulations — where each cell might carry temperature, pressure, material type, or any other domain-specific data — you can extend DefaultStatus with a custom class.

Overview

  1. Define your custom status by extending DefaultStatus and adding fields.
  2. Cast in singleRun — in your executor, cast cell.getCurrentStatus() to your custom class to access the extra fields.
  3. Use your custom status as the default status and in the initial condition list.

Example: Game of Life with a custom status

The following three files show a complete Game of Life implementation using a custom status class. Although the logic is the same as the basic example, this pattern scales naturally to automata that need richer per-cell state.

The custom status class

Define your own class that extends DefaultStatus and adds domain-specific fields.

public class GoLStatus extends DefaultStatus {

	public boolean isAlive;

	public GoLStatus(boolean isAlive) {
		super("GoLStatus", null);
		this.isAlive = isAlive;
	}

	@Override
	public String toString() {
		return isAlive ? "1 " : "0 ";
	}

}

The executor

In singleRun, cast the current status to your custom class to read its fields. Always return a new DefaultCell with the next state — do not mutate the input cell.

public class GoLDSExecutor extends CellularAutomataExecutor {

	@Override
	public DefaultCell singleRun(DefaultCell cell, List<DefaultCell> neighbors) {

		Long alives = neighbors.stream().filter(item -> ((GoLStatus) item.currentStatus).isAlive).count();
		
		boolean isAlive = ((GoLStatus)cell.currentStatus).isAlive;
		
		DefaultCell toReturn = new DefaultCell(null, cell.getRow(), cell.getCol());
		if (!isAlive && alives == 3) {
			toReturn.currentStatus = new GoLStatus(true);
		} else if (isAlive && (alives == 2 || alives == 3)) {
			toReturn.currentStatus = new GoLStatus(true);
		} else {
			toReturn.currentStatus = new GoLStatus(false);
		}

		return toReturn;
	}

}

The application entry point

Use your custom status as the defaultStatus and when constructing initial cells.


public class GoLDSApplication {

	public static GoLStatus status = new GoLStatus(false);
	public static int totalInteraction = 1, width = 10, height = 10;

	public static void main(String[] args) throws Exception {

		Long start = System.currentTimeMillis();

		CellularAutomataConfigurationBuilder builder = new CellularAutomataConfigurationBuilder();

		List<DefaultCell> initalState = new ArrayList<DefaultCell>();

		initalState.add(new DefaultCell(new GoLStatus(true), 1, 1));
		initalState.add(new DefaultCell(new GoLStatus(true), 1, 2));
		initalState.add(new DefaultCell(new GoLStatus(true), 1, 3));
		initalState.add(new DefaultCell(new GoLStatus(true), 2, 1));

		CellularAutomata ca = new CellularAutomata();
		ca.init(builder.setWidth(width)
						.setHeight(height)
						.setInfinite(false)
						.setTotalIterations(totalInteraction)
						.setNeighborhoodType(NeighborhoodType.MOORE)
						.setDefaultStatus(status)
						.setInitalState(initalState)
				.build());

		Long end = System.currentTimeMillis();

		System.out.println(ca.toString());
		System.out.println("Init elapsed: " + (end - start) / 1000 + " seconds.");
		System.out.println();

		GoLDSExecutor gol = new GoLDSExecutor();

		try {
			start = System.currentTimeMillis();
			ca = gol.run(ca);
			System.out.println(ca.toString());
			end = System.currentTimeMillis();
			System.out.println("Single thread --> Elapsed: " + (end - start) + " seconds.");
			System.out.println();

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

Tips

  • Two DefaultStatus values are considered equal when both key and value are equal. Override equals / hashCode in your custom class if you need value-based comparison.
  • The value field accepts any Object, so you can store a Map, a POJO, or any domain object you need.
  • For automata that model natural flows (e.g., heat diffusion, landslides), the custom status can hold numeric quantities updated each generation.

See also