2017-10-15 96 views
0

我有一个经典的骰子模拟问题,我很努力实现,因为我是新的R语法。函数(我称之为捷联惯组)的工作原理如下:功能模拟游戏在R

  1. 开始与0点
  2. 模拟n个随机抽取的三头六面的骰子
  3. 对于每个抽奖:
    • 如果总和的三个骰子> 12 - > 1点
    • 如果三个骰子总和< 6 - > -1点
    • 否则(即总和和6之间12):
      • 如果三个骰子具有相同数目的 - > 5点
      • 否则 - > 0分
  4. 返回以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)。

+1

它看起来并不有什么不对的功能,你只是重置'k'为零的大部分时间,因此,如果调用'捷联惯组(N)'和'N> 1'赔率你会得到'k < - 0'。是不是“否则0点”意味着'否则添加零点? –

+0

你是对的 - 最后的陈述应该是k < - k + 0.谢谢。 – Macter

回答

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

此外,也许'样本(6,1)'会做,在这种情况下,它是完全一样的,更简单和可读。作为奖励,不需要额外的变量'y'。 –

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

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