使用R作为游戏模拟器

时间:2013-04-29 16:27:35

标签: r for-loop simulation

我正在尝试模拟一个简单的游戏,你旋转一个标记为1-5的微调器,然后继续前进,直到你通过终点线(点50)。我对R有点新意,并且一直在寻找答案。当我运行下面的代码时,它不会按顺序添加数字,它会返回我的50个随机旋转及其值​​的列表。如何让它在彼此之上添加旋转,然后停止一次=> 50?

SpacesOnSpinner<-(seq(1,5,by=1))
N<-50
L1<-integer(N)

for (i in 1:N){
takeaspin<-sample(SpacesOnSpinner,1,replace=TRUE)
L1[i]<-L1[i]+takeaspin
} 

3 个答案:

答案 0 :(得分:4)

这是replicate的一个很好的用例。我不确定你是否必须使用for循环,但你可以这样做(replicate也是循环):

SpacesOnSpinner<-(seq(1,5,by=1))
N<-10
cumsum( replicate( N , sample(SpacesOnSpinner,1,replace=TRUE) ) )
#[1]  5 10 14 19 22 25 27 29 30 33

但是,由于你有条件要break开启,或许while条件的其他答案正是你在这种情况下所需要的(人们会告诉你他们不好R,但它们有它们的用途)。使用这种方法,您可以看到之后通过一个简单的子集花了多少次旋转超过50(但您不会事先知道需要多少次旋转,但在大多数它将是50):

N<-50
x <- cumsum( replicate( N , sample(5,1) ) )

# Value of accumulator at each round until <= 50
x[ x < 50 ]
#[1]  5  6  7  8 12 16 21 24 25 29 33 34 36 38 39 41 42 44 45 49

# Number of spins before total <= 50
length(x[x < 50])
[1] 20

答案 1 :(得分:3)

这是使用递归函数模拟游戏的另一种有趣方式。

spin <- function(outcomes = 1:5, start = 0L, end = 50L)
   if (start <= end)
      c(got <- sample(outcomes, 1), Recall(outcomes, start + got, end))

spin()
# [1] 5 4 4 5 1 5 3 2 3 4 4 1 5 4 3

虽然很优雅,但它不会像@ Simon的解决方案一样快,只需拨打sample,就像@Viktor所建议的那样:

spin <- function(outcomes = 1:5, end = 50L) {
   max.spins <- ceiling(end / min(outcomes))
   x <- sample(outcomes, max.spins, replace = TRUE)
   head(x, match(TRUE, cumsum(x) >= end))
}

spin()
# [1] 3 5 2 3 5 2 2 5 1 2 1 5 5 5 2 4

为了你的最终目标(找到一个人在整个游戏中处于领先地位的概率),while是否会更有效率是有争议的:一个while循环肯定是比较慢,但是当领先者从一个玩家切换到另一个玩家时,你可能会受益于早退出的可能性。这两种方法都值得测试。

答案 2 :(得分:2)

您可以使用while语句和变量 total 来跟踪总和:

total <- 0
while(total <= 50){
   takeaspin<-sample(SpacesOnSpinner,1,replace=TRUE)
   total <- takeaspin + total
} 

print (total)