Home > other >  Creating a "Coin Flipping" Game
Creating a "Coin Flipping" Game

Time:03-03

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:

  1. a matrix with all the results
  2. the sum for player 1 and 2 (in that order)
  3. 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)))

enter image description here

  • Related