---
title: "Basic usage"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{basic-usage}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
```{r setup}
library(cellularautomata)
```
## Create the plot of a cellular automaton
You can generate a cellular automaton using the `ca` function, specifying the Wolfram rule. For example:
```{r}
ca(18) |> plot()
ca(30) |> plot()
ca(45) |> plot()
ca(195) |> plot()
```
The number of rows to be generated are specified with the `steps` parameter in the `ca()` function.
The length of the cellular automaton can be specified with the `ncols` parameter in the `ca()` function. See below how to specify arbitrary initial states.
## Animations
You can get an animation of a cellular automaton using `plot(animate = TRUE)`:
```{r fig.height=1, fig.width=4}
ca(30, ncols = 20, steps = 30) |> plot(animate = TRUE)
```
## Get the rule definition
You can get the visual representation of the definition of a rule with `wolfram_rule_def()`:
```{r fig.height=1, fig.width=4}
wolfram_rule_def(18)
wolfram_rule_def(30)
wolfram_rule_def(45)
wolfram_rule_def(195)
```
The first line in each box is a possible input, and the second line is the output of the function. For example, Rule 30 is defined as:
```
111 -> 0
110 -> 0
101 -> 0
100 -> 1
011 -> 1
010 -> 1
001 -> 1
000 -> 0
```
The function `wolfram_rule()` gives the output of the rule as a numeric vector:
```{r}
wolfram_rule(30)
```
## Multiple plots at once
To generate multiple plots in one go, you can wrap the `ca(rule) |> plot()` inside a `purrr::map()` call and then pipe the resulting list into `patchwork::wrap_plots()`.
For example, you can generate a preview of all the 256 rules this way:
```{r eval=FALSE}
all_rules <- purrr::map(0:255, \(rule){
ca(rule,
ncols = 30,
steps = 30) |>
plot()
}) |>
patchwork::wrap_plots(nrow = 32)
ggplot2::ggsave("all-cellular-automata.png",
plot = all_rules,
width = 12,
height = 48)
```
This will create a long png file with all the rules.
## Specify the initial state
You can define how long the cellular automaton line is using the `ncols` parameter in the `ca()` function. Alternatively, you can define an arbitrary initial state, which will determine how long the line is.
By default, the initial state has a single filled cell in the middle of an empty row. You can specify different initial states using the `initialstate` parameter in the `ca()` function. The `initialstate` needs to be a vector of 0s and 1s. When you specify the `initialstate`, the `ncols` is calculated as `length(initialstate)`.
For example, here we are running _Rule 30_ for 10 steps from several random initial states:
```{r}
# sample rule 30 from different random starting points
purrr::map(1:25, \(i){
ca(30,
initialstate = sample(c(0, 1), size = 10, replace = TRUE),
steps = 10) |>
plot(title = NULL)
}) |>
patchwork::wrap_plots()
```
The function `sample(c(0, 1), size = 10, replace = TRUE)` generates a random vector of 0s and 1s of length 10.
## Wrap the line, or don't
By default the line is wrapped around, meaning it is actually a circle, with the end connected to the beginning.
You can turn off wrapping with `wrap = FALSE` in the `ca()` function, which will keep the first and the last cells always empty.
Given the circular default, you can also plot the cellular automaton in polar coordinates, adding the `circle = TRUE` option to `plot()`. To make the time flow from the center to the outer edges, set `time_flow = "up"` as well.
```{r}
ca(193, steps = 50) |> plot(time_flow = "up", circle = TRUE)
```
This also works for animations:
```{r}
ca(193, ncols = 25, steps = 100) |> plot(circle = TRUE, animate = TRUE)
```