R中模拟游戏的功能

Function for simulation game in R

我有一个经典的骰子模拟问题,由于我是 R 语法的新手,所以我很难实现它。该函数(我称之为 simu)的工作原理如下:

  1. 从 0 分开始
  2. 模拟 n 次随机抽取三个六面骰子
  3. 每次开奖:
    • 如果三个骰子的总和 >12 --> +1 点
    • 如果三个骰子的总和 <6 --> -1 点
    • 否则(即 6 和 12 之间的总和):
      • 如果三个骰子点数相同 --> +5 分
      • 否则 --> 0 分
  4. Return n 次模拟结束时获得的总点数

尝试了多种不同的方法后,我似乎非常接近:

simu <- function(n){
  k <- 0
  for(i in 1:n) {
    a <- sample(y,1,replace=TRUE)
    b <- sample(y,1,replace=TRUE)
    c <- sample(y,1,replace=TRUE)  
    if ((a + b + c) > 12)  {
      k <- k+1
    } else if ((a + b + c) < 6)  {
      k <- k-1
    } else if ((a == b) & (b == c))  {
      k <- k+5
    } else k <- 0
  }
  return(k)
}

问题似乎是我无法为函数中的每个 "i" 迭代新的模拟(对于 a、b、c)。

我已经评论了我发现的唯一问题...最后一个 else 总是将 k 重新初始化为 0。相反,它应该是 k <- k + 0 但确实如此不更改任何内容以将其删除。

y <- seq(1,6) # 6-sided dice

simu <- function(n){
  k <- 0
  for(i in 1:n) {
    a <- sample(y,1,replace=TRUE)
    b <- sample(y,1,replace=TRUE)
    c <- sample(y,1,replace=TRUE)  
    if ((a + b + c) > 12)  {
      k <- k+1
    } else if ((a + b + c) < 6)  {
      k <- k-1
    } else if ((a == b) & (b == c))  {
      k <- k+5
    } #else k <- 0
  }
  return(k)
}

结果看起来相当不错:

> simu(1000)
[1] 297
> simu(100)
[1] 38

我不确定这是否是您需要的,但您可以尝试类似的操作:

# Draw the dice(s) - returns vector of length == n_dices
draw <- function(sides = 6, dices = 3){
  sample(1:sides, dices, replace = T)
}
# test simulation x and return -1, 0, 1, 1 or 5
test <- function(x){
  (sum(x) > 12)*1 + (sum(x) < 6)*(-1) + (sum(x) >= 6 & 
                                           sum(x) <= 12 & 
                                           var(x) == 0)*5 
}
# simulate n draws of x dices with y sides
simu <- function(sides = 6, dices = 3, n = 100){
  sum(replicate(n, test(draw(sides, dices))))
}
# run simulations of 100 draws for 1, 2, ..., 11, 12-side dices (3 dices each simulation) 
dt <- lapply(1:12, function(side) replicate(100, simu(side, 3, 100)))
# plot dicstribution of scores
par(mfrow = c(3,4))
lapply(1:length(dt), function(i) hist(dt[[i]],
                                      main = sprintf("%i sides dice", i),
                                      xlab = "Score"
                                      )
       )

如果您打算使用 R,那么您应该学习创建矢量化操作而不是 'for' 循环。这是对 100 万次掷骰子的模拟,计算时间不到 1 秒。我不确定 'for' 循环方法需要多长时间。

n <- 1000000  # trials
start <- proc.time()  # time how long it takes
result <- matrix(0L, ncol = 6, nrow = n)
colnames(result) <- c('d1', 'd2', 'd3', 'sum', 'same', 'total')

# initial the roll of three dice
result[, 1:3] <- sample(6L, n * 3L, replace = TRUE)

# compute row sum
result[, 'sum'] <- as.integer(rowSums(result[, 1:3]))

# check for being the same
result[, 'same'] <- result[,1L] == result[, 2L] & result[, 2L] == result[, 3L]

result[, 'total'] <- ifelse(result[, 'sum'] > 12L,
                      1L,
                      ifelse(result[, 'sum'] < 6L,
                             -1L,
                             ifelse(result[, 'same'] == 1L,
                                    5L,
                                    0L
                             )
                      )
)

table(result[, 'total'])

    -1      0      1      5 
 46384 680762 259083  13771 

cat("simulation took:", proc.time() - start, '\n')
simulation took: 0.7 0.1 0.8 NA NA