Skip to content

Instantly share code, notes, and snippets.

@vvinichenko
Created February 23, 2012 19:48
Show Gist options
  • Save vvinichenko/1894697 to your computer and use it in GitHub Desktop.
Save vvinichenko/1894697 to your computer and use it in GitHub Desktop.
Game of Life in R
shiftMatrix <- function(mx, dr, dc) {
#Shift the matrix by dr (delta r) rows and dc columns
#by adding e.g. dr rows of zeros and removing dr rows from the other side
nr <- nrow(mx)
nc <- ncol(mx)
#If the matrix is shifted by more than its nrow or ncol, we get a matrix of zeros
if (abs(dr) >= nr || abs(dc) >= nc) {
mx <- matrix(0, nrow = nr, ncol = nc)
return(mx)
}
#Rows:
if (dr > 0) {
mx <- rbind(mat.or.vec(dr, nc), mx)
mx <- mx[1:nr,]
} else if (dr < 0) {
mx <- rbind(mx, mat.or.vec(-dr, nc))
mx <- mx[(1 - dr):(nr - dr),]
}
#Columns:
if (dc > 0) {
mx <- cbind(mat.or.vec(nr, dc), mx)
mx <- mx[,1:nc]
} else if (dc < 0) {
mx <- cbind(mx, mat.or.vec(nr, -dc))
mx <- mx[,(1 - dc):(nc - dc)]
}
return(mx)
}
life_cycle <- function(mx) {
#Move the board one generation forward
mx0 <- matrix(0, nrow = nrow(mx), ncol = ncol(mx))
#Produce 8 "shifted" boards and add them up
for (n in (-1:1)) {
for (m in (-1:1)) {
if (n !=0 || m !=0) {
mx0 <- mx0 + shiftMatrix(mx, n, m)
}
}
}
#Deaths and births
mx[mx0 > 3 | mx0 < 2] <- 0
mx[mx0 == 3] <- 1
return(mx)
}
#Initialization of parameters
n_rows <- 100
n_cols <- 100
n_cells <- n_rows * n_cols
n_cycles <- 100
sleep_time <- 0.1
clrs <- c("#f0f0f0", "#2f81c1") #colors for empty squares and cells
rnd_threshold <- 0.3 # 0 - empty board; 1 - all squares are filled
set.seed(1) #Random seed
#Create a board and plot it
board <- matrix(0, nrow = n_rows, ncol = n_cols)
board[runif(n_cells, 0, 1) < rnd_threshold] <- 1
image(board, axes = FALSE, col = clrs)
#The main cycle
for (i in (1:n_cycles)) {
Sys.sleep(sleep_time)
board <- life_cycle(board)
image(board, axes = FALSE, col = clrs)
}
@timriffe
Copy link

Hi Vadim,
wow, totally different approach! I think yours scales better. I dig it,
had never seen the function 'mat.or.vec()' before
Tim

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment