---
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)
```