Monthly Archives: December 2016

Zombie Dice Simulation

A while back at an MadR Meetup hack night I spent some time working on a way to simulate the game Zombie Dice. Zombie Dice is made up of 13 six-sided dice, six green, five yellow, and three red. Each side of the die has either a foot symbol, a shotgun symbol, or a brain symbol. The player is a zombie, looking for victim’s brains and avoiding shotguns. The foot symbol means that the victim got away.

On the first turn, the player randomly selects three dice. Green dice are the best for the player, with four brains and one shotgun. Yellow has three brains and two shotguns. Red dice have two brains and three shotguns. The three selected dice are rolled. Shotguns and brains are set aside. Feet are kept to be rolled again on the next turn. If a player is shot three times their turn ends and they don’t get to add the brains to their score. After any turn they can choose to stop and let the next player go while adding any brains they have rolled to their score. Confusing? It’s actually an easy game to learn and play. You can see the game in action starting at about 10 minutes into this video:

After playing this game a few times I wondered if I could simulate this game in R to determine the best strategy. I decided to try it without spending much time on the project. I limited myself to what could be done in a single MadR meetup hack night.

The result was code that is a good start at simulating Zombie Dice but doesn’t follow the rules correctly. It works but doesn’t set aside the dice that rolled shotguns or brains. It also doesn’t allow for the user to set the strategy and just continues rolling until it wins the game or is shot three times (a better strategy seems to be for the player to stop when a few brains have been rolled). Here is what the (inaccurate) output looks like:

Zombie Dice simulation results.

Zombie Dice simulation results.

Maybe someone else wants to finish this project? The code is below and you can also view it on github at https://github.com/justinmeyer/zombie_dice_simulation.

# Set the number of games to play
games <- 10000

# Create a data frame to store the game results in
game_results <- as.data.frame(matrix(NA, games, 2))

library(data.table)
setnames(game_results, c("V1", "V2"), c("outcome", "round"))

game_results$outcome <- as.factor(game_results$outcome)
levels(game_results$outcome) <- c("lost", "won")

# Create a loop that simulates the specified number of games

for (i in 1:games) {

 print(paste0("############ GAME: ", i, " STARTED ############"))
 
 # Create a loop that runs as long as the game hasn't been won or lost
 round <- 0
 count_brains <- 0
 count_shotguns <- 0
 
 while (count_brains < 13 & count_shotguns < 3) {
 
 # Create matrix representing the 13 dice
 # Brain = 1, runner = 0, shotgun = -1
 dice <- matrix(NA, 13, 6)
 
 dice[1, ] <- c(1, 1, 1, 0, 0, -1) # green
 dice[2, ] <- c(1, 1, 1, 0, 0, -1) # green
 dice[3, ] <- c(1, 1, 1, 0, 0, -1) # green
 dice[4, ] <- c(1, 1, 1, 0, 0, -1) # green
 dice[5, ] <- c(1, 1, 1, 0, 0, -1) # green
 dice[6, ] <- c(1, 1, 1, 0, 0, -1) # green
 dice[7, ] <- c(1, 1, 0, 0, -1, -1) # yellow
 dice[8, ] <- c(1, 1, 0, 0, -1, -1) # yellow
 dice[9, ] <- c(1, 1, 0, 0, -1, -1) # yellow
 dice[10, ] <- c(1, 1, 0, 0, -1, -1) # yellow
 dice[11, ] <- c(1, 0, 0, -1, -1, -1) # red
 dice[12, ] <- c(1, 0, 0, -1, -1, -1) # red
 dice[13, ] <- c(1, 0, 0, -1, -1, -1) # red
 
 # Simulate a round by randomly drawing three dice from the 13
 selected_dice <- dice[sample(1:nrow(dice), 3, replace = FALSE),]
 
 # Simulate rolling the three selected dice
 roll_result_1 <- sample(selected_dice[1, ], 1)
 roll_result_2 <- sample(selected_dice[2, ], 1)
 roll_result_3 <- sample(selected_dice[3, ], 1)
 rm(selected_dice)
 
 # Combine the results
 round_results <- as.data.frame(rbind(roll_result_1, roll_result_2, roll_result_3))
 rm(roll_result_1, roll_result_2, roll_result_3)
 
 # Determine if the player won or lost
 round_results$count <- 1
 round_brains <- sum(round_results$count[round_results$V1 == 1])
 count_brains <- count_brains + round_brains
 
 round_shotguns <- sum(round_results$count[round_results$V1 == -1])
 count_shotguns <- count_shotguns + round_shotguns
 
 rm(round_brains, round_shotguns)
 
 # Add one to round and print number of rounds
 round <- round + 1
 print(paste0("###### Round: ", round, " ######"))
 
 # Report brains count and shotguns count
 print(paste0("Brains: ", count_brains))
 print(paste0("Shotguns: ", count_shotguns))
 
 # Report status of game at end of each round
 if(count_brains >= 13 & count_shotguns < 3){print(paste0("Won in ", round, " rounds."))
 game_results[i, 1] <- "won"
 game_results[i, 2] <- round}
 
 else if(count_shotguns >= 3){print(paste0("Lost in ", round, " rounds."))
 game_results[i, 1] <- "lost"
 game_results[i, 2] <- round}
 else {print(paste0("Play another round."))}
 
 rm(round_results)
 
 }
 
 print(paste0("############ GAME: ", i, " COMPLETE. ############"))
 
 }

summary(game_results)
table(game_results$round)