我想用R编写一个程序来修改俄罗斯轮盘赌。 第一个玩家有一把带有1颗子弹的左轮手枪。如果他活下来,我们将一颗子弹加入一个腔室并旋转枪管。等等,直到第六个玩家(如果其他人存活下来)。我想知道一个概率,左轮手枪会来到第六个玩家,我想让它像模拟一样。 我知道如何为古典俄罗斯轮盘制作节目
roulette <- function(numshots)
{
killed = 6
killshots = 0
won = 0
i = 0
while (killshots < numshots){
shot = sample(1:6, size=1, replace=T)
i = i + 1
if (shot == killed)
{
killshots = killshots + 1
if (i%%2 == 1)
{
won = won + 1
}
}
}
return(data.frame(A = won, B = numshots-won))
}
roulette(numshots)
以及其他一些修改,它们也在Creating a Russian roulette game in R 但我不知道它对我来说是否对我来说是古典俄罗斯轮盘游戏的代码。任何人都可以用R中的代码帮助我吗?
答案 0 :(得分:1)
我建议这个功能比必要的更麻烦。
roulette1 <- function(bullets = 6L) {
chamber <- sample(bullets)
pick <- sample(bullets, replace=TRUE)
for (i in 1:bullets) if (pick[i] %in% chamber[1:i]) break
return(i)
}
说明:
i
pick
的房间 1到i
,在找到匹配时突然退出循环; < / LI>
for
循环后,i
始终表示第一个&#34;成功&#34; (保证,因为到最后,所有的房间都满了)附注:
我们可以稍微优化一下,因为在bullets
循环中,我们知道我们将获得成功。没有必要进行测试......但它现在已经足够便宜了。
我的函数和你的函数之间的差异(性能方面)之一就是你一次拉出一个随机数,这会使事情变慢一些;在我的情况下,我立刻拉出所有的房间......这将(大约一半的时间)过度拉动随机数据,但它会使运行时间(经验)快34%。
示例运行:
sample(6) # chamber
# [1] 4 2 1 3 5 6
sample(6) # pick, with possibly-repeated values
# [1] 1 3 2 5 2 2
i <- 1
1 %in% c(4) # FALSE
i <- 2
3 %in% c(4,2) # FALSE
i <- 3
2 %in% c(4,2,1) # TRUE
break
因此,在此示例中,for
循环将在i
为3时中断,表示&#34;游戏&#34;达到了3次扳机拉动。
返回值仅仅是单次成功之前的步骤数。根据这一点计算A
和B
非常容易。确定经验概率也是微不足道的:
set.seed(6)
roulettes <- replicate(1e6, roulette1())
# table(roulettes) / length(roulettes)
# str(data.frame(A = roulettes, B = 6L - roulettes))
# roulettes
# 1 2 3 4 5 6
# 0.166374 0.278005 0.277309 0.185644 0.077301 0.015367
'data.frame': 1000000 obs. of 2 variables:
# $ A: int 2 1 3 5 6 5 4 3 4 1 ...
# $ B: int 4 5 3 1 0 1 2 3 2 5 ...
(更新以修复pick
的抽样问题,现在经验概率与Ell provided的预期概率结合起来。)
答案 1 :(得分:-1)
您可以看到my answer to a simple Russian Roulette game here。除此之外,我们还可以制作一个播放俄罗斯轮盘的功能,每次转弯后,都会添加一个子弹并将枪管旋转。
我已经从我的原始脚本中修改了一下(我意识到它随机化了腔室中子弹的顺序 - 好像玩家移除了所有子弹并且每回合重新加载它们:新版本保持结构,玩家添加了每次非致命射击后,子弹到测试室)。
函数中的 S
设置了腔室的容量,6射手是我的默认值。所有的功能都需要P
,一个玩家的矢量(或者P1 - P6,因为我用来表示游戏顺序中的位置)。
RR <- function(P, S = 6){
D <- 0
i <- 1
B <- 1
# First player goes
C <- sample(c(rep(1, times = B), rep(0, times = S-B)))
# Did the first player die?
if(C[1] == 1){
D <- 1
}
# If player 1 survived...
while(D != 1){
i <- i + 1
# Next player adds a bullet to the 1st empty chamber...
C[1] <- 1
# ...Spins the cylinder...
R <- sample(seq(1,S))[1]
C <- rep(C[c(R:S, 1:(R-1))], length.out = S)
# ...Pulls the trigger
if(C[1] == 1){
D <- 1
# If they survive, the gun goes to the next player (D remains 0, and until D = 1 the 'while' part will keep cycling through)
}
}
# The name/id of the loser is recorded
L <- rep(P, length.out = i)[i]
L
}
这里有效,模拟了一百万次:
# "Players"
P <- c("P1", "P2", "P3", "P4", "P5", "P6")
# Repeated simulations
n <- 1000000
RRres <- rep(NA, n)
for(i in 1:n){
RRres[i]<- RR(P, S = 6)
}
# Observed frequencies
table(RRres)/n
观察到的频率是:
> table(RRres)/n
RRres
P1 P2 P3 P4 P5 P6
0.166530 0.278042 0.277899 0.184914 0.077097 0.015518
非常类似于预期的频率:
# Expected frequencies:
# first term = probability of spinning on to a loaded chamber
# second term = probability of having to play
(P.P1 <- (1/6) * (6/6))
(P.P2 <- (2/6) * (6/6 * 5/6))
(P.P3 <- (3/6) * (6/6 * 5/6 * 4/6))
(P.P4 <- (4/6) * (6/6 * 5/6 * 4/6 * 3/6))
(P.P5 <- (5/6) * (6/6 * 5/6 * 4/6 * 3/6 * 2/6))
(P.P6 <- (6/6) * (6/6 * 5/6 * 4/6 * 3/6 * 2/6 * 1/6))
> P.P1
[1] 0.1666667
> P.P2
[1] 0.2777778
> P.P3
[1] 0.2777778
> P.P4
[1] 0.1851852
> P.P5
[1] 0.07716049
> P.P6
[1] 0.0154321