stats_noob
stats_noob

Reputation: 5897

Creating a "Coin Flipping" Game

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":

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:

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):

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!

Upvotes: 0

Views: 1063

Answers (1)

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(sample(c(-1,1), size = 1, prob = c(0.5,0.5)), sample(c(-3,4), size = 1, prob = c(0.7,0.3))),size = 1)
  }
  for (i in 1:length(p2)) {
    p2[i] <- sample(c(sample(c(-1,1), size = 1, prob = c(0.7,0.3)), sample(c(-3,4), size = 1, prob = c(0.7,0.3))),size = 1)
  }
  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 
    506     423      71  

Finally, if you want to visualize it:

barplot(table(replicate(1000,coin_flip(turns = 2, coins = 2)$winner)))

enter image description here

Upvotes: 3

Related Questions