Skip to content

Instantly share code, notes, and snippets.

@JosiahParry
Created October 16, 2024 15:56
Show Gist options
  • Save JosiahParry/417d90be0487a0dae6b18909ae0beb31 to your computer and use it in GitHub Desktop.
Save JosiahParry/417d90be0487a0dae6b18909ae0beb31 to your computer and use it in GitHub Desktop.
The game of life written in R with spdep
library(spdep)
n <- 25
geo <- sf::st_make_grid(
cellsize = c(1, 1),
offset = c(0, 0),
n = n
)
# create contiguity neighbors for the grid
nb <- poly2nb(geo)
# create binary spatial weights matrix
listw <- nb2listw(nb, style = "B")
# initialize game of life
x <- sample(c(0, 1), n^2, prob = c(0.8, 0.2), replace = TRUE)
# this function plays one round and updates x globally
play_round <- function(x, listw) {
results <- lag.listw(listw, x)
# 1. Any live cell with fewer than two live neighbours **dies**, as if by underpopulation.
dead_by_underpop <- x == 1 & results < 2
# 2. Any live cell with two or three live neighbours **lives** on to the next generation.
alive_to_alive <- x == 1 & (results == 2 | results == 3)
# 3. Any live cell with more than three live neighbours dies, as if by overpopulation.
dead_by_overpop <- x == 1 & results > 3
# 4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
dead_to_alive <- x == 0 & results == 3
alive <- alive_to_alive | dead_to_alive
dead <- dead_by_overpop | dead_by_underpop
# Update the state
x[alive] <<- 1
x[dead] <<- 0
}
for (i in seq_len(10)) {
cat("playing round ", i, "\n")
play_round(x, listw)
print(plot(sf::st_sf(x = x, geo)))
Sys.sleep(0.5)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment