俄罗斯轮盘赌与R中添加新子弹

时间:2018-04-01 05:52:27

标签: r probability

我想用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中的代码帮助我吗?

2 个答案:

答案 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次扳机拉动。

返回值仅仅是单次成功之前的步骤数。根据这一点计算AB非常容易。确定经验概率也是微不足道的:

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