cavl
is a simple library for simulating and visualizing various cellular automata.
Install using pip
:
pip install cavl
Note: If you want to use the built-in animation functionality, you also need to install ffmpeg
.
cavl
provides two main classes for creating and simulating cellular automata: CellularAutomaton1D
and CellularAutomaton2D
, for 1D and 2D cellular automata respectively.
Both classes take the same number and type of parameters for initialization:
init
: the starting grid for the cellular automataneighbors
: list of coordinates to represent the neighborhood of a cellapply
: function to apply a given rule to a single cell (signature depends on whether working with 1D or 2D cellular automata)- 1D: takes dictionary with keys as relative coordinates of a neighbor and values representing the current state number of that neighbor (
dict[tuple[int, int], float]
) - 2D: takes same dictionary as with 1D
apply
function, as well as the state number of the current cell being worked on - The given
apply
function should return the state number that the current cell should be in the next generation.
- 1D: takes dictionary with keys as relative coordinates of a neighbor and values representing the current state number of that neighbor (
cavl
provides built-in helper functions for retrieving lists of tuple coordinates representing common neighborhoods.
moore(radius: int)
: returns list oftuple[int, int]
representing a Moore neighborhood with givenradius
(default of 1)- i.e.
moore()
returns[(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]
- i.e.
von_neumann(radius: int)
: returns list oftuple[int, int]
representing a von Neumann neighborhood with givenradius
(default of 1)- i.e.
von_neumann()
returns[(0, -1), (-1, 0), (1, 0), (0, 1)]
- i.e.
cavl
provides several built-in functions for visualizing your cellular automata:
plot
: used to visualize the generations of a 1D cellular automatonanimate
: used to animate the progression of the generations of a 1D cellular automatonplot2d
: used to visualize the most recent generation of a 2D cellular automatonanimate2d
: used to animate the progression of the generations of a 2D cellular automaton
cavl
also provides some built-in classes for common cellular automata rules. Currently, there are only two built-in 1D cellular automata rules:
General1DRule
: takes a rule using the Wolfram code naming systemTotalistic1DRule
: rule that looks at the total of the values of the cells in a neighborhood; more information here
import cavl
start = cavl.init(50) # returns 1D array with width of 50
rule = cavl.General1DRule(30)
automaton = cavl.CellularAutomaton1D(init=start, neighbors=rule.neighbors, apply=rule.apply)
automaton.evolve(20)
cavl.plot(automaton, save=True, filename='1D_automaton')
Currently, there are no built-in rule classes that work with 2D cellular automata; some will be added later on.
import cavl
# simple period 2 oscillator
start = [[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]]
neighbors = cavl.moore()
# Conway's Game of Life rules
def apply(neighbors, current) -> int:
alive = sum(neighbors.values())
if current == 1 and (alive == 2 or alive == 3):
return 1
elif current == 0 and alive == 3:
return 1
else:
return 0
automaton = cavl.CellularAutomaton2D(init=start, neighbors=neighbors, apply=apply)
automaton.evolve(21)
cavl.plot2d(automaton, save=True, filename='2D_automaton')
- More built-in rules
- Cyclic
- Life-like
- Additional grid layouts
- Hexagonal
- Triangular
- ...and more