当前位置:  开发笔记 > 编程语言 > 正文

试图将R中的岩石,纸张,剪刀游戏随机化

如何解决《试图将R中的岩石,纸张,剪刀游戏随机化》经验,为你挑选了3个好方法。

我已经创建了一个RPS函数,可以将计算机的移动随机旋转一圈.例如,如果您键入rps("rock"),该函数将随机吐出岩石,纸张,剪刀以及结果(胜利,损失,平局).

rps = function(move){
  options = c("rock", "paper", "scissors")
  comp.move = sample(options, size = 1)
  if(move == "rock" & comp.move == "rock"){
    names(comp.move) = "tie"
}else
if(move == "rock" & comp.move == "scissors"){
    names(comp.move) = "loss"
}else
if(move == "rock" & comp.move == "paper"){
    names(comp.move) = "win"
}else
if(move == "paper" & comp.move == "paper"){
    names(comp.move) = "tie"
}else
if(move == "paper" & comp.move == "scissors"){
    names(comp.move) = "win"
}else
if(move == "paper" & comp.move == "rock"){
    names(comp.move) = "loss"
}else
if(move == "scissors" & comp.move == "scissors"){
    names(comp.move) = "tie"
}else
if(move == "scissors" & comp.move == "rock"){
    names(comp.move) = "win"
}else
if(move == "scissors" & comp.move == "paper"){
    names(comp.move) = "loss"
}
  return(comp.move)
}

现在,我想玩这个发生50次的游戏版本.我已经创建了一个长度为50的矢量,它具有预先记录的人类移动.

human.move = c("rock", "paper", "scissors", "paper", "paper", "rock", "scissors", "rock", "rock", "paper", "paper", "scissors", "rock", "rock", "paper", "paper", "paper", "scissors", "paper", "rock", "paper", "rock", "rock", "scissors", "scissors", "paper", "rock", "paper", "scissors", "rock", "paper", "paper", "scissors", "rock", "paper", "rock", "paper", "paper", "scissors", "scissors", "paper", "rock", "rock", "scissors", "scissors", "rock", "paper", "scissors", "scissors", "rock")

如何让计算机对此向量中的每个元素运行rps函数,并给我结果?目前我的函数只取我人类移动矢量的第一个元素(这是摇滚)并且仅将其随机移动与之比较.

rps.random=function(move,n=50){
comp.moves = vector("character")

for(i in human.move){
comp.move=rps(move[i])
comp.moves = append(comp.moves,comp.move, after = length(comp.moves))
}
return(comp.moves)
}

Rich Scriven.. 8

以下是一些建议.首先,更新您的功能.您可以if()通过对|运算符使用一些"或"语句来获得胜利或亏损以及identical()并列函数来减少所有这些语句.此外,据我所知,像这样的随机游戏应该一次玩一轮,并复制多轮.因此,此函数检查给定的单长度向量move.

rps <- function (move) {
    opts <- c("rock", "paper", "scissors")
    stopifnot(length(move) == 1L, move %in% opts)
    cpu <- sample(opts, 1)
    names(cpu) <- if (identical(move, cpu)) {
        "tie"
    }
    else if (move == "rock" & cpu == "scissors" | move == "paper" & 
        cpu == "rock" | move == "scissors" & cpu == "paper") {
        "win"
    }
    else {
        "loss"
    }
    cpu
}

以下是几个示例运行 -

rps("paper")
#    win 
# "rock" 
rps("rock")
#    loss 
# "paper" 

现在您不需要手动创建50个项目的向量.我们可以通过在move参数中使用样本来复制该过程50次.

replicate(50, rps(sample(c("rock", "paper", "scissors"), 1)))
#        win        win       loss        win       loss        tie        tie 
# "scissors"    "paper"    "paper"    "paper"     "rock"    "paper" "scissors" 
#        win       loss       loss        tie       loss        win        win 
#     "rock"    "paper"    "paper"    "paper"    "paper" "scissors" "scissors" 
#        tie       loss        tie        win        win        tie       loss 
# "scissors"     "rock" "scissors"    "paper"    "paper" "scissors"     "rock" 
#        tie        tie       loss        tie        win        win        win 
#     "rock" "scissors" "scissors" "scissors"     "rock" "scissors" "scissors" 
#        win        win       loss        win        tie        tie        win 
# "scissors" "scissors"    "paper"    "paper"    "paper"    "paper"    "paper" 
#        win        tie        win        tie        tie        win        win 
#    "paper"     "rock"     "rock"    "paper" "scissors"    "paper" "scissors" 
#       loss        tie        tie       loss        tie        win        win 
#     "rock"     "rock"    "paper" "scissors" "scissors"     "rock"     "rock" 
#        win 
#    "paper" 

当然,如果你确实有一个输入向量,我们可以运行它sapply()来查看与上面相同的结果(在名称中有或没有输入向量).

sapply(c("rock", "paper", "scissors"), rps)
#   rock.loss    paper.win scissors.tie 
#     "paper"       "rock"   "scissors" 
sapply(c("rock", "paper", "scissors"), rps, USE.NAMES = FALSE)
#       tie       loss        win 
#    "rock" "scissors"    "paper" 

更新:我突然意识到你不知道我们得到的上述案例中的输入是什么replicate(),所以这是一个修复.如果我们将函数的最后一行更改为矩阵(或列表),我们还可以包含输入内容.我们可以在最后一行使用这样的东西=

matrix(c(move, cpu), 1, dimnames = list(wlt, c("move", "cpu")))

然后我们会得到以下结果 -

rps("paper")
#      move    cpu       
# loss "paper" "scissors"
rps("paper")
#     move    cpu    
# tie "paper" "paper"

现在我们知道在没有做任何额外工作的情况下输入的内容.我们还可以将复制品与我们的老朋友一起组合成一个矩阵do.call(rbind, ...).



1> Rich Scriven..:

以下是一些建议.首先,更新您的功能.您可以if()通过对|运算符使用一些"或"语句来获得胜利或亏损以及identical()并列函数来减少所有这些语句.此外,据我所知,像这样的随机游戏应该一次玩一轮,并复制多轮.因此,此函数检查给定的单长度向量move.

rps <- function (move) {
    opts <- c("rock", "paper", "scissors")
    stopifnot(length(move) == 1L, move %in% opts)
    cpu <- sample(opts, 1)
    names(cpu) <- if (identical(move, cpu)) {
        "tie"
    }
    else if (move == "rock" & cpu == "scissors" | move == "paper" & 
        cpu == "rock" | move == "scissors" & cpu == "paper") {
        "win"
    }
    else {
        "loss"
    }
    cpu
}

以下是几个示例运行 -

rps("paper")
#    win 
# "rock" 
rps("rock")
#    loss 
# "paper" 

现在您不需要手动创建50个项目的向量.我们可以通过在move参数中使用样本来复制该过程50次.

replicate(50, rps(sample(c("rock", "paper", "scissors"), 1)))
#        win        win       loss        win       loss        tie        tie 
# "scissors"    "paper"    "paper"    "paper"     "rock"    "paper" "scissors" 
#        win       loss       loss        tie       loss        win        win 
#     "rock"    "paper"    "paper"    "paper"    "paper" "scissors" "scissors" 
#        tie       loss        tie        win        win        tie       loss 
# "scissors"     "rock" "scissors"    "paper"    "paper" "scissors"     "rock" 
#        tie        tie       loss        tie        win        win        win 
#     "rock" "scissors" "scissors" "scissors"     "rock" "scissors" "scissors" 
#        win        win       loss        win        tie        tie        win 
# "scissors" "scissors"    "paper"    "paper"    "paper"    "paper"    "paper" 
#        win        tie        win        tie        tie        win        win 
#    "paper"     "rock"     "rock"    "paper" "scissors"    "paper" "scissors" 
#       loss        tie        tie       loss        tie        win        win 
#     "rock"     "rock"    "paper" "scissors" "scissors"     "rock"     "rock" 
#        win 
#    "paper" 

当然,如果你确实有一个输入向量,我们可以运行它sapply()来查看与上面相同的结果(在名称中有或没有输入向量).

sapply(c("rock", "paper", "scissors"), rps)
#   rock.loss    paper.win scissors.tie 
#     "paper"       "rock"   "scissors" 
sapply(c("rock", "paper", "scissors"), rps, USE.NAMES = FALSE)
#       tie       loss        win 
#    "rock" "scissors"    "paper" 

更新:我突然意识到你不知道我们得到的上述案例中的输入是什么replicate(),所以这是一个修复.如果我们将函数的最后一行更改为矩阵(或列表),我们还可以包含输入内容.我们可以在最后一行使用这样的东西=

matrix(c(move, cpu), 1, dimnames = list(wlt, c("move", "cpu")))

然后我们会得到以下结果 -

rps("paper")
#      move    cpu       
# loss "paper" "scissors"
rps("paper")
#     move    cpu    
# tie "paper" "paper"

现在我们知道在没有做任何额外工作的情况下输入的内容.我们还可以将复制品与我们的老朋友一起组合成一个矩阵do.call(rbind, ...).



2> Tommy O'Dell..:

正如加里建议的那样,对于任何适用于"一件事"的功能,你可以使用lapplysapply使其适用于许多事情.

但是我要说这里并不是真的有必要,因为rpsmove时间长于1 时,内部已经处理了这种情况.你只需要sample(options, size = 1)改为sample(options, size = length(move), replace = TRUE).

如果您不确定该replace = TRUE部分,则可以使用"替换品" .

我认为还有一种更简单的方法来判断它是赢,输还还是平局.

rps = function(move){

  # possible selections
  options = c("rock", "paper", "scissors")

  # the sample function is already vectorised, so it will work when
  # move is longer than one
  comp.move = sample(options, size = length(move), replace = TRUE)

  #create a result vector that defaults to 'loss'
  results <- rep('loss', length(move))

  # update the rest of the results (these are vectorised too)
  results[move == comp.move]                             <- 'tie'
  results[move == 'rock'      & comp.move == 'scissors'] <- 'win'
  results[move == 'paper'     & comp.move == 'rock']     <- 'win'
  results[move == 'scissors'  & comp.move == 'paper']    <- 'win'

  # set the names
  names(comp.move) <- results

  # return the vector
  comp.move
}

然后就可以这样使用它

> rps(human.move)
      loss        win        win       loss       loss        win       loss        tie       loss       loss       loss       loss        win        win 
   "paper"     "rock"    "paper" "scissors" "scissors" "scissors"     "rock"     "rock"    "paper" "scissors" "scissors"     "rock" "scissors" "scissors" 
      loss       loss       loss       loss        tie        tie       loss        tie        tie       loss        tie        win        tie        tie 
"scissors" "scissors" "scissors"     "rock"    "paper"     "rock" "scissors"     "rock"     "rock"     "rock" "scissors"     "rock"     "rock"    "paper" 
       tie        win       loss       loss        win       loss       loss        win       loss        tie        tie        tie        win       loss 
"scissors" "scissors" "scissors" "scissors"    "paper"    "paper" "scissors" "scissors" "scissors"    "paper" "scissors" "scissors"     "rock"    "paper" 
       tie        win        tie        tie       loss        tie        tie        tie 
    "rock"    "paper" "scissors"     "rock" "scissors" "scissors" "scissors"     "rock" 



3> rawr..:

KEK

rps <- function(player) {
  p <- c('rock','paper','scissors')
  player <- if (missing(player))
    sample(p, 1) else match.arg(player, p, FALSE)
  computer <- sample(p, 1)
  message(sprintf('Computer picks %s', computer))
  message(sprintf('You chose %s', player))
  plays <- cbind(expand.grid(p = p, c = p),
                 result = I(c('tie','win','loss','loss','tie','win','win','loss','tie')))

  res <- plays[plays$p %in% player & plays$c %in% computer, 'result']
  if (res == 'tie')
    return(res)

  for (ii in 1:10) {
    par(mar = c(0,0,0,0), bg = sample(colors(), 1))
    plot(1:10, ann = FALSE, axes = FALSE, type = 'n')
    text(runif(1, 1, 10), runif(1, 1, 10), toupper(res), srt = sample(0:360, 1),
         font = 3, cex = 4, col = sample(colors(), 1))
    Sys.sleep(.1)
  }
  graphics.off()
  res
}

rps()

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有