R中模拟游戏的功能

时间:2017-10-15 13:12:35

标签: r simulation

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

  1. 从0点开始
  2. 模拟三个六面骰子的随机抽取
  3. 每次抽奖:
    • 如果三个骰子的总和> 12 - > +1点
    • 如果三个骰子的总和< 6-> -1点
    • 否则(即6到12之间的总和):
      • 如果三个骰子具有相同的数字 - > +5分
      • 否则 - > 0分
  4. 返回在n次模拟结束时获得的总分数
  5. 尝试了许多不同的方法后,我似乎非常接近:

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

3 个答案:

答案 0 :(得分:1)

我已经评论了我发现的唯一问题...最后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

答案 1 :(得分:1)

如果您打算使用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 

答案 2 :(得分:0)

我不确定这是你需要的,但你可以尝试这样的事情:

# 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"
                                      )
       )

enter image description here