我已经创建了一个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, ...)
.
以下是一些建议.首先,更新您的功能.您可以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, ...)
.
正如加里建议的那样,对于任何适用于"一件事"的功能,你可以使用lapply
或sapply
使其适用于许多事情.
但是我要说这里并不是真的有必要,因为rps
当move
时间长于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"
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()