I am working with the R programming language.
I am working with the R programming language. Recently, I thought of the following "game" to illustrate "mixed strategies and comparative advantages":
- There are two Players: Player 1 and Player 2
- There are two Coins: Coin 1 and Coin 2
- Coin 1 lands on "Heads" with a probability of 0.5 and "Tails" with a probability of 0.5
- Coin 2 lands on "Heads" with a probability of 0.7 and "Tails" with a probability of 0.3
- If Coin 1 is "Heads", a score of -1 is obtained; if Coin 1 is "Tails", a score of 1 is obtained
- If Coin 2 is "Heads", a score of -3 is obtained; if Coin 1 is "Tails", a score of 4 is obtained
In this game, Player 1 always starts first - Player 1 chooses either Coin 1 or Coin 2, flips the coin that they select and gets a "score". Then, Player 2 chooses either Coin 1 or Coin 2, flips the coin that they select and get a "score". The Player with the higher score wins, the Player with the lower score loses (a "tie" is also possible).
I wrote the R code to simulate this game being played 100 times:
score_coin_1 = c(-1,1)
score_coin_2 = c(-3, 4)
results <- list()
for (i in 1:100)
{
iteration = i
player_1_coin_choice_i = sample(2, 1, replace = TRUE)
player_2_coin_choice_i = sample(2, 1, replace = TRUE)
player_1_result_i = ifelse(player_1_coin_choice_i == 1, sample(score_coin_1, size=1, prob=c(.5,.5)), sample(score_coin_2, size=1, prob=c(.7,.3)) )
player_2_result_i = ifelse(player_2_coin_choice_i == 1, sample(score_coin_1, size=1, prob=c(.5,.5)), sample(score_coin_2, size=1, prob=c(.7,.3)))
winner_i = ifelse(player_1_result_i > player_2_result_i, "PLAYER_1", ifelse(player_1_result_i == player_2_result_i, "TIE", "PLAYER_2"))
my_data_i = data.frame(iteration, player_1_coin_choice_i, player_2_coin_choice_i, player_1_result_i, player_2_result_i , winner_i )
results[[i]] <- my_data_i
}
results_df <- data.frame(do.call(rbind.data.frame, results))
head(results_df)
iteration player_1_coin_choice_i player_2_coin_choice_i player_1_result_i player_2_result_i winner_i
1 1 1 1 -1 1 PLAYER_2
2 2 1 2 -1 -3 PLAYER_1
3 3 2 2 4 -3 PLAYER_1
4 4 1 2 1 -3 PLAYER_1
5 5 2 1 4 1 PLAYER_1
6 6 2 2 4 -3 PLAYER_1
My Question: I now want to make a more "complicated version" of this game in which:
Player 1 flips 2 coins (e.g. coin 1 coin 1 OR coin 1 coin 2 OR coin 1 coin 2 OR coin 2 coin 2) and records his score
Next, Player 2 flips 2 coins and records his score
Then, Player 1 flips 2 coins - records his score and adds it to his previous score
Finally, Player 2 flips 2 coins - records his score and adds it to his previous score
The player with the total highest score wins.
I was able to "extend" the above code for this modified version of the game above, but the code becomes very long and very complicated (the code also becomes "in stone" (fixed) for this specific set up) :
results <- list()
for (i in 1:100)
{
iteration = i
player_1_coin_choice_firstflip_turn_1_i = sample(2, 1, replace = TRUE)
player_1_coin_choice_secondflip_turn_1_i = sample(2, 1, replace = TRUE)
player_1_firstflip_result_turn_1_i = ifelse(player_1_coin_choice_firstflip_turn_1_i == 1, sample( LETTERS[1:2], 1, replace=TRUE, prob=c(0.5,0.5) ), sample( LETTERS[3:4], 1, replace=TRUE, prob=c(0.5,0.5) ))
player_1_secondflip_result_turn_1_i = ifelse(player_1_coin_choice_secondflip_turn_1_i == 1, sample( LETTERS[1:2], 1, replace=TRUE, prob=c(0.5,0.5) ), sample( LETTERS[3:4], 1, replace=TRUE, prob=c(0.5,0.5) ))
player_1_firstflip_result_turn_1_score_1_i = ifelse(player_1_firstflip_result_turn_1_i == "A", 0.5, ifelse(player_1_firstflip_result_turn_1_i == "B", 0.3, ifelse(player_1_firstflip_result_turn_1_i == "C", 0.3, 0.9)))
player_1_secondflip_result_turn_1_score_1_i = ifelse(player_1_secondflip_result_turn_1_i == "A", 0.5, ifelse(player_1_secondflip_result_turn_1_i == "B", 0.3, ifelse(player_1_secondflip_result_turn_1_i == "C", 0.3, 0.9)))
player_1_totalscore_turn_1_i = player_1_secondflip_result_turn_1_score_1_i player_1_firstflip_result_turn_1_score_1_i
player_2_coin_choice_firstflip_turn_1_i = sample(2, 1, replace = TRUE)
player_2_coin_choice_secondflip_turn_1_i = sample(2, 1, replace = TRUE)
player_2_firstflip_result_turn_1_i = ifelse(player_2_coin_choice_firstflip_turn_1_i == 1, sample( LETTERS[1:2], 1, replace=TRUE, prob=c(0.5,0.5) ), sample( LETTERS[3:4], 1, replace=TRUE, prob=c(0.5,0.5) ))
player_2_secondflip_result_turn_1_i = ifelse(player_2_coin_choice_secondflip_turn_1_i == 1, sample( LETTERS[1:2], 1, replace=TRUE, prob=c(0.5,0.5) ), sample( LETTERS[3:4], 1, replace=TRUE, prob=c(0.5,0.5) ))
player_2_firstflip_result_turn_1_score_1_i = ifelse(player_2_firstflip_result_turn_1_i == "A", 0.5, ifelse(player_2_firstflip_result_turn_1_i == "B", 0.3, ifelse(player_2_firstflip_result_turn_1_i == "C", 0.3, 0.9)))
player_2_secondflip_result_turn_1_score_1_i = ifelse(player_2_secondflip_result_turn_1_i == "A", 0.5, ifelse(player_2_secondflip_result_turn_1_i == "B", 0.3, ifelse(player_2_secondflip_result_turn_1_i == "C", 0.3, 0.9)))
player_2_totalscore_turn_1_i = player_2_secondflip_result_turn_1_score_1_i player_2_firstflip_result_turn_1_score_1_i
player_2_coin_choice_firstflip_turn_2_i = sample(2, 1, replace = TRUE)
player_2_coin_choice_secondflip_turn_2_i = sample(2, 1, replace = TRUE)
player_2_firstflip_result_turn_2_i = ifelse(player_2_coin_choice_firstflip_turn_2_i == 1, sample( LETTERS[1:2], 1, replace=TRUE, prob=c(0.5,0.5) ), sample( LETTERS[3:4], 1, replace=TRUE, prob=c(0.5,0.5) ))
player_2_secondflip_result_turn_2_i = ifelse(player_2_coin_choice_secondflip_turn_2_i == 1, sample( LETTERS[1:2], 1, replace=TRUE, prob=c(0.5,0.5) ), sample( LETTERS[3:4], 1, replace=TRUE, prob=c(0.5,0.5) ))
player_2_firstflip_result_turn_2_score_2_i = ifelse(player_2_firstflip_result_turn_2_i == "A", 0.5, ifelse(player_2_firstflip_result_turn_2_i == "B", 0.3, ifelse(player_2_firstflip_result_turn_2_i == "C", 0.3, 0.9)))
player_2_secondflip_result_turn_2_score_2_i = ifelse(player_2_secondflip_result_turn_2_i == "A", 0.5, ifelse(player_2_secondflip_result_turn_2_i == "B", 0.3, ifelse(player_2_secondflip_result_turn_2_i == "C", 0.3, 0.9)))
player_2_totalscore_turn_2_i = player_2_secondflip_result_turn_2_score_2_i player_2_firstflip_result_turn_2_score_2_i
player_1_coin_choice_firstflip_turn_2_i = sample(2, 1, replace = TRUE)
player_1_coin_choice_secondflip_turn_2_i = sample(2, 1, replace = TRUE)
player_1_firstflip_result_turn_2_i = ifelse(player_1_coin_choice_firstflip_turn_2_i == 1, sample( LETTERS[1:2], 1, replace=TRUE, prob=c(0.5,0.5) ), sample( LETTERS[3:4], 1, replace=TRUE, prob=c(0.5,0.5) ))
player_1_secondflip_result_turn_2_i = ifelse(player_1_coin_choice_secondflip_turn_2_i == 1, sample( LETTERS[1:2], 1, replace=TRUE, prob=c(0.5,0.5) ), sample( LETTERS[3:4], 1, replace=TRUE, prob=c(0.5,0.5) ))
player_1_firstflip_result_turn_2_score_2_i = ifelse(player_1_firstflip_result_turn_2_i == "A", 0.5, ifelse(player_1_firstflip_result_turn_2_i == "B", 0.3, ifelse(player_1_firstflip_result_turn_2_i == "C", 0.3, 0.9)))
player_1_secondflip_result_turn_2_score_2_i = ifelse(player_1_secondflip_result_turn_2_i == "A", 0.5, ifelse(player_1_secondflip_result_turn_2_i == "B", 0.3, ifelse(player_1_secondflip_result_turn_2_i == "C", 0.3, 0.9)))
player_1_totalscore_turn_2_i = player_1_secondflip_result_turn_2_score_2_i player_1_firstflip_result_turn_2_score_2_i
player_1_final_score_i = player_1_totalscore_turn_2_i player_1_totalscore_turn_1_i
player_2_final_score_i = player_2_totalscore_turn_2_i player_2_totalscore_turn_1_i
winner_i = ifelse(player_1_final_score_i > player_2_final_score_i, "PLAYER 1", ifelse( player_1_final_score_i == player_2_final_score_i, "TIE", "PLAYER 2"))
my_data_i = data.frame(iteration, player_1_coin_choice_firstflip_turn_1_i , player_1_coin_choice_secondflip_turn_1_i , player_1_firstflip_result_turn_1_i ,
player_1_secondflip_result_turn_1_i , player_1_firstflip_result_turn_1_score_1_i , player_1_secondflip_result_turn_1_score_1_i , player_1_totalscore_turn_1_i ,
player_2_coin_choice_firstflip_turn_1_i , player_2_coin_choice_secondflip_turn_1_i , player_2_firstflip_result_turn_1_i , player_2_secondflip_result_turn_1_i ,
player_2_firstflip_result_turn_1_score_1_i , player_2_secondflip_result_turn_1_score_1_i , player_2_totalscore_turn_1_i , player_2_coin_choice_firstflip_turn_2_i ,
player_2_coin_choice_secondflip_turn_2_i , player_2_firstflip_result_turn_2_i , player_2_secondflip_result_turn_2_i ,
player_2_firstflip_result_turn_2_score_2_i , player_2_secondflip_result_turn_2_score_2_i , player_2_totalscore_turn_2_i ,
player_1_coin_choice_firstflip_turn_2_i ,player_1_coin_choice_secondflip_turn_2_i , player_1_firstflip_result_turn_2_i ,player_1_secondflip_result_turn_2_i ,
player_1_firstflip_result_turn_2_score_2_i ,player_1_secondflip_result_turn_2_score_2_i ,player_1_totalscore_turn_2_i ,player_1_final_score_i , player_2_final_score_i ,winner_i )
results[[i]] <- my_data_i
}
#final results of 100 random iterations
results_df <- data.frame(do.call(rbind.data.frame, results))
I am wondering if there is a more "efficient" way to write the code for this simulation that "adapts" to different requirements. For instance, suppose I specify in advance (there will be no more than 2 coins):
- The probability of Heads/Tails for Coin 1 and Coin 2
- The score associated with Coin 1 and Coin 2
- The number of "turns" the game lasts (e.g. in the first example the game lasts for "1 turn", in the second example the game lasts for "2 turns") - e.g. suppose I want the game to last for 3 turns
Is there a way to "adapt" my code I have written so that it can easily accommodate different numbers of turns, probabilities and scores?
Thanks!
CodePudding user response:
I'm not sure how would you like to save your data. But I tried to make it more efficient, though, by creating a function where you can select the number of turns and the number of coins that will be flipped. The thing in here is that I didn't mind about the order of the turn as all the points were supossed to sum.
coin_flip <- function(turns = 1, coins = coins){
p1 <- vector(length = coins*turns)
p2 <- vector(length = coins*turns)
for (i in 1:length(p1)) {
p1[i] <- sample(c(-1,1), size = 1, prob = c(0.5,0.5))
}
for (i in 1:length(p2)) {
p2[i] <- sample(c(-3,4), size = 1, prob = c(0.7,0.3))
}
return(list(res = rbind(p1,p2),
points = c(sum(p1),sum(p2)),
winner = ifelse(sum(p1)>sum(p2), "Player1",
ifelse(sum(p1)==sum(p2), "tie", "Player2"))))
}
So, when you call for the function, it will return 3 items:
- a matrix with all the results
- the sum for player 1 and 2 (in that order)
- And the winner.
So, 1 game with 2 turns means that a each player will play 4 times:
> coin_flip(turns = 2, coins = 2)
$res
[,1] [,2] [,3] [,4]
p1 1 -1 -1 1
p2 -3 -3 -3 4
$points
[1] 0 -5
$winner
[1] "Player1"
If what calls your attention is just the winner, you can use replicate()
. In t he next example, a game with 2 turns and 2 coins will be repeated 1 thousand times.
> table(replicate(1000,coin_flip(turns = 2, coins = 2)$winner))
Player1 Player2 tie
658 287 55
Finally, if you want to visualize it:
barplot(table(replicate(1000,coin_flip(turns = 2, coins = 2)$winner)))