install.packages(c("ggplot2", "gganimate", "gifski"))
library(ggplot2)
library(gganimate)

ising_final_df <- function(g = 80, beta = 0.4, trials = 30000) {
  grid <- matrix(sample(c(-1L, 1L), (g + 2)^2, replace = TRUE), nrow = g + 2)
  grid[c(1, g + 2), ] <- 0L
  grid[, c(1, g + 2)] <- 0L
  
  for (m in seq_len(trials)) {
    i <- sample.int(g, 1) + 1L
    j <- sample.int(g, 1) + 1L
    deg <- grid[i, j + 1L] + grid[i, j - 1L] + grid[i - 1L, j] + grid[i + 1L, j]
    p <- 1 / (1 + exp(-beta * 2 * deg))
    grid[i, j] <- if (runif(1) < p) 1L else -1L
  }
  
  final <- grid[2:(g + 1), 2:(g + 1)]
  expand.grid(x = seq_len(g), y = seq_len(g)) |>
    transform(spin = as.vector(final))
}

betas <- seq(-1.5, 1.5, length.out = 40)

df <- do.call(
  rbind,
  lapply(betas, function(b) transform(ising_final_df(beta = b), beta = b))
)

p <- ggplot(df, aes(x, y, fill = factor(spin))) +
  geom_raster() +
  coord_equal() +
  scale_fill_manual(values = c(`-1` = "black", `1` = "white"), guide = "none") +
  labs(title = "beta = {closest_state}") +
  theme_void() +
  transition_states(beta, transition_length = 1, state_length = 1)

animate(p, fps = 12, width = 500, height = 500)
# anim_save("ising_beta.gif")
