# 2048 in R

• A simple/naive implementation of 2048 in plain R - with `{ggplot2}` output for a little bit of zing.
• Interactive keypress response seems basically impossible from R, so this uses `readline()` and you have to press return to register each action.
• Code in a gist
• Motivation:
• Looking at some game stuff in R and this was the simplest thing I could think to write
• There’s an existing package on CRAN: twenty48
• But I wanted to re-invent the wheel so I could think about the process of game creation.
``````#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
#    #####    ###   #        #####
#   #     #  #   #  #    #  #     #
#         # #     # #    #  #     #
#    #####  #     # #    #   #####
#   #       #     # ####### #     #
#   #        #   #       #  #     #
#   #######   ###        #   #####
#
#
#
# Board Size: Default = 4
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library(ggplot2)
N <- 4L

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Collapse a vector in the style of 2048
#
# Collapse vector by removing zeros, then summing pairs of adjacent values
#
# Result is padded with zeros to length of input
#
# @param x vector of integers
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
collapse_vec <- function(x) {
new  <- x[x > 0]

i <- 1L
while (i < length(new)) {
if (new[i] == new[i + 1L]) {
new[i] <- new[i] * 2L
new    <- new[-(i + 1L)]
}

i <- i + 1L
}

c(new, integer(N - length(new)))
}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Initialise game board
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
m       <- matrix(0L, N, N)
init    <- sample(N*N, 2)
m[init] <- 2L
m_prior <- m

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Plot game board
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
plot_m <- function(m) {
grid <- expand.grid(1:N, 1:N)
idx  <- arrayInd(which(m > 0), .dim = c(N, N))
df   <- cbind(as.data.frame(idx), V3 = factor(m[m > 0], levels = 2^(1:11)))
ggplot(df, aes(V2, N + 1L - V1)) +
geom_tile(data = grid, aes(Var1, Var2), fill = 'grey90', width = 0.9, height = 0.9) +
geom_tile(aes(fill = V3), width = 0.9, height = 0.9) +
geom_text(aes(label = V3), colour = 'white', size = 10) +
theme_void() +
xlim(0, N+1L) + ylim(0, N+1L) +
coord_equal() +
theme(legend.position = 'none') +
scale_fill_viridis_d(option = 'D', drop = FALSE, end = 0.9)
}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Game loop
#    Use WASD to collapse the board in up/left/down/right directions
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
print(plot_m(m))

while (max(m) < 2048 && any(m == 0)) {
if (!identical(m, m_prior)) {
# if the board has changed, then add a new '2' tile
m[sample(which(m == 0), 1)] <- 2L

print(m)
print(plot_m(m))
}

m_prior <- m
# cmd <- readline(prompt = "move?: ")
m <- switch(