这是一个模拟一个玩家的蛇和梯子游戏的代码:
ladder.df <- data.frame(start=c(1,4,9,21,28,36,51,71,80), end=c(38,14,31,42,84,44,67,91,100))
slide.df <- data.frame(start=c(98,95,93,87,64,62,56,49,47,16), end=c(78,75,73,24,60,19,53,11,26,6))
curLoc <- 0 # Current location
nroll <- 0 # Number of rolls
slides <- 0 # Number of slides encountered
ladders <- 0 # Number of ladders encountered
# Keep rolling dice and moving until reach 100 or greater ending the game
while(curLoc < 100) {
roll <- sample(6,1) # generate random number between [1 to 6]
curLoc <- curLoc + roll # increase position
nroll <- nroll + 1 # increase number of rolls
# Need to check if we landed on a ladder or slide and move forward or back
if (any(ladder.df$s %in% curLoc)) {
curLoc <- ladder.df$e[ladder.df$s %in% curLoc]
ladders <- ladders + 1
}
if (any(slide.df$s %in% curLoc)) {
curLoc <- slide.df$e[slide.df$s %in% curLoc]
slides <- slides + 1
}
}
现在,我想将其扩展到一些用户将指定此号码的玩家。我试图创建一个函数并使用'for'循环,但是,未能提供更新全局变量的代码片段。提前谢谢了!
答案 0 :(得分:2)
首先将提供的代码放入名为play_game()
的函数中
play_game <- function(ladder_df, slide_df) {
curLoc <- 0 # Current location
nroll <- 0 # Number of rolls
slides <- 0 # Number of slides encountered
ladders <- 0 # Number of ladders encountered
# Keep rolling dice and moving until reach 100 or greater ending the game
while(curLoc < 100) {
roll <- sample(6,1) # generate random number between [1 to 6]
curLoc <- curLoc + roll # increase position
nroll <- nroll + 1 # increase number of rolls
# Need to check if we landed on a ladder or slide and move forward or back
if (any(ladder_df$s %in% curLoc)) {
curLoc <- ladder_df$e[ladder_df$s %in% curLoc]
ladders <- ladders + 1
}
if (any(slide_df$s %in% curLoc)) {
curLoc <- slide_df$e[slide_df$s %in% curLoc]
slides <- slides + 1
}
}
return(data.frame( num_rolls = nroll,
num_ladders = ladders,
num_slides = slides))
}
这使您可以快速玩游戏(使用不同的“电路板” - 即ladder_df
和slide_df
的不同配置。
play_game(ladder.df, slide.df)
# num_rolls num_ladders num_slides
# 1 23 2 3
然后你可以扩展这个功能,以便与任意数量的玩家一起运行:
play_game_with_players <- function(num_players = 1, ladder_df, slide_df) {
# Pre-allocate a list with the number of players
results <- vector("list", num_players)
for (i in seq_along(results)) {
results[[i]] <- play_game(ladder_df, slide_df)
}
return(results)
}
此时您可以与任意数量的玩家一起玩,它们将在results[[i]]
中返回。也就是说,results[[2]]
表示玩家2的结果。
play_game_with_players(num_players = 3, ladder.df, slide.df)
# [[1]]
# num_rolls num_ladders num_slides
# 14 3 0
#
# [[2]]
# num_rolls num_ladders num_slides
# 8 2 0
#
# [[3]]
# num_rolls num_ladders num_slides
# 67 4 7
然后您可以灵活地汇总结果,例如将所有行绑定在一起:
library(dplyr)
bind_rows(play_game_with_players(num_players = 4, ladder.df, slide.df),
.id = "player")
# player num_rolls num_ladders num_slides
# 1 1 98 4 14
# 2 2 43 3 5
# 3 3 87 4 14
# 4 4 80 5 11
每条评论更新:要模拟多个游戏,您可以使用replicate
。例如,让我们模拟三个四人游戏:
sim_3 <-
replicate(3,
bind_rows(play_game_with_players(num_players = 4, ladder.df, slide.df),
.id = 'player'),
simplify = FALSE)
bind_rows(sim_3, .id = "trial") %>% as_data_frame
# # A tibble: 12 x 5
# trial player num_rolls num_ladders num_slides
# <chr> <chr> <dbl> <dbl> <dbl>
# 1 1 1 47.0 4.00 7.00
# 2 1 2 32.0 4.00 5.00
# 3 1 3 15.0 5.00 1.00
# 4 1 4 25.0 2.00 2.00
# 5 2 1 22.0 3.00 2.00
# 6 2 2 42.0 5.00 6.00
# 7 2 3 28.0 2.00 2.00
# 8 2 4 14.0 2.00 1.00
# 9 3 1 18.0 2.00 1.00
# 10 3 2 29.0 3.00 2.00
# 11 3 3 12.0 1.00 0
# 12 3 4 46.0 4.00 5.00
此时,您可以对结果表进行总结。
bind_rows(sim_3, .id = "trial") %>%
as_data_frame %>%
group_by(player) %>%
summarise(avg_rolls = mean(num_rolls),
max_ladders = max(num_ladders))
# # A tibble: 4 x 3
# player avg_rolls max_ladders
# <chr> <dbl> <dbl>
# 1 1 29.0 4.00
# 2 2 34.3 5.00
# 3 3 18.3 5.00
# 4 4 28.3 4.00