My project is a game of dice I made up. It is based kind of on the types of games I would have to make and play in Elementary Statistics classes. There was a particular name I was going to call it to make it more memorable, but I soon realized it had an explicit modern connotation. Right now, I’m calling it Dead on Six, because the game ends when a player rolls a 6. The game itself is pretty simple, yet the conclusions we can draw from analyzing it are interesting. In this game, there are two players, Player A and Player B, as represented in the code. Each player has his/her own six-sided die, as I envision it, red and blue apiece. Player A always goes first. Each player consecutively takes a turn rolling their die once. If either player rolls a six, then he/she wins and the game ends. If Player A doesn’t get a six, then Player B gets a turn. If Player B doesn’t get a six, then Player A gets a turn and so on.
Let’s look at the script code itself. I used library function to load and attach the tidyverse and scales packages. Both these packages help organize my data and allow me to perform certain operations; that scales package makes my graphs we’ll see in a second more organized and easier to see with the ggplot graphical function. Next we can see n here representing the number of samples we’re gonna take down here in the sample function. Here I pass the sample function to the dice variable, saying we’re gonna sample only the numbers 1-6, six sides of the die, sample will be conducted n number of times this case 100 times, then we put replace to TRUE so that each sample done will be independent on previous samples made. A win is whenever the die reads six, using the which function here. The results dataframe here uses several functions such as diff which helps distinguish the difference in value between wins. Then I use the pipeline operator instead of parentheses to encase another function inside this dataframe, just to keep it looking nicer than if I used parentheses. Then I use the mutate function to create a new dataframe with data modified from the game_length vector without changing the initial value of game_length vector itself. I’m telling it to return the remainder from dividing the current value of game_length and that if it’s 1 as the remainder, then the value passed to who_won is Player A, otherwise, the value passed is Player B.
I create a new dataframe named rs using the existing results dataframe to create a similar dataframe to results and further modify the who_won data as defined in results. Group_by sorts the data into a manageable group, with which to summarise into individual rows based on the occurences of n(), which is assigned to the variable freq, or frequency in this case. It’s generally advised on Stack Exchange and similar places to use the ungroup function after using the group_by function on a dataframe. As far as I understand from my own observations here, it is because if we don’t ungroup after group_by something, we can’t change the dataframe later if we wanted to because of some metadata that is assigned to the dataframe by group_by. Basically, I can set the columns with group_by and then set the rows inside rs after ungrouping them. Now we put all together into a readable chart using ggplot. Ggplot, abbreviation for Grammar of Graphics plot, is a function used to graph an input dataframe with already constructed graph templates, in this case we use the results dataframe to make a histogram. We further act on the supplied data with functions such as this aesthetic function here to specify values for the height and color of each column in the histogram based on the game_length and the who_won variables. The ggplot function creates not only a histogram in the plots section down here but it also makes a boxed chart from the results dataframe in the shell here. We can see the box chart in the shell by using the View function on results. As we can see, rerunning the script changes the values used in the histogram and the box graph each time. Because each roll of the die made is different each game. I pasted a statement above the histogram here to represent the probability of the starting player, Player A (the reddish colored column here) to win, based on the rs variable. After running it all a bunch of times, I found that the length of the game as specified in the shell diagram here determines who wins the game. If the game ends on an even number (if the game takes, say, 6 turns to for someone to roll a six), then Player B wins. If the game ends on an odd number, Player A wins. Also I wanted to see if Player A going first means Player A will win more often.
library(tidyverse)
## -- Attaching packages ------------------------------------------- tidyverse 1.2.1 --
## v ggplot2 3.2.1 v purrr 0.3.2
## v tibble 2.1.3 v dplyr 0.8.3
## v tidyr 0.8.3 v stringr 1.4.0
## v readr 1.3.1 v forcats 0.4.0
## -- Conflicts ---------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library(scales)
##
## Attaching package: 'scales'
## The following object is masked from 'package:purrr':
##
## discard
## The following object is masked from 'package:readr':
##
## col_factor
library(knitr)
n <- 100
dice <- sample(1:6, n, replace = TRUE)
wins <- which(dice == 6)
results <- data.frame(game_length = diff(c(0, wins))) %>%
mutate(who_won = ifelse(game_length %% 2 == 1, "Player A", "Player B"))
rs <- results %>%
group_by(who_won) %>%
summarise(freq = n()) %>%
ungroup() %>%
mutate(prop = freq / sum(freq))
ggplot(results, aes(x = game_length, fill = who_won)) +
geom_histogram(binwidth = 1) +
ggtitle("Results of an alternating dice roll game",
paste("First to roll a six wins; Starting player wins ", round(rs[1, "prop"], 2), " of the time")) +
scale_y_continuous(label = comma) +
labs(x = "Game length", fill = "Winner:",
y = paste("Number of wins out of", format(n, big.mark = ",", scientific = FALSE)))
kable(results)
| game_length | who_won |
|---|---|
| 4 | Player B |
| 10 | Player B |
| 19 | Player A |
| 3 | Player A |
| 6 | Player B |
| 5 | Player A |
| 6 | Player B |
| 5 | Player A |
| 1 | Player A |
| 8 | Player B |
| 13 | Player A |
| 5 | Player A |
| 14 | Player B |
| 1 | Player A |
Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.
When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).
The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.