R语言使用%in%匹配列表异常:石头剪刀蜥蜴史波克游戏问题排查
石头剪刀布蜥蜴史波克游戏函数的胜负判定问题
我编写了一个用于玩“石头、剪刀、布、蜥蜴、史波克”的函数,通过menu()让用户选择选项,sample()生成电脑的选择,并预设10种获胜配对来判定胜负。代码运行无报错,但输出不符合预期,怀疑问题出在%in%的使用或list的特性上。
原代码
choices <- c("rock", "paper", "scissors", "lizard", "spock") # Scissors [3] beats paper [2], # paper [2] beats rock [1], # rock [1] beats lizard [4], # lizard [4] beats Spock [5], # Spock [5] beats scissors [3], # scissors [3] beats lizard [4], # lizard [4] beats paper [2], # paper [2] beats Spock [5], # Spock [5] beats rock [1], # rock [1] beats scissors [3]. wins <- list(c(3, 2), c(2, 1), c(1, 4), c(4, 5), c(5, 3), c(3, 4), c(4, 2), c(2, 5), c(5, 1), c(1, 3)) fun <- function(){ input <- menu(choices, title="Choose one:") if (input == 0){ message("You have to pick a valid choice to play this. Try again.") } if (input >= 1 && input <= 5){ comp_choice <- sample(1:5, 1) message(paste0("you chose ", choices[input])) message(paste0("computer chose ", choices[comp_choice])) print(list(c(input, comp_choice)) %in% wins) if (input != comp_choice){ if (list(c(input, comp_choice)) %in% wins) { message("you won") } else message("you lost") } else message("it's a draw") } } fun()
异常输出示例(本应判定为胜利)
Selection: 3 you chose scissors computer chose lizard [1] FALSE you lost
问题原因
%in%在处理list元素时,无法直接正确匹配两个长度相同的向量。当你用list(c(input, comp_choice)) %in% wins时,R并不会逐个比较向量内的元素是否完全一致,而是做了更高层级的list元素匹配,导致明明存在的配对被判定为不存在。
解决方法
替换胜负判定的逻辑,使用sapply()遍历wins列表,检查是否有任何一个配对与c(input, comp_choice)完全相等。
修改后的代码
choices <- c("rock", "paper", "scissors", "lizard", "spock") wins <- list(c(3, 2), c(2, 1), c(1, 4), c(4, 5), c(5, 3), c(3, 4), c(4, 2), c(2, 5), c(5, 1), c(1, 3)) fun <- function(){ input <- menu(choices, title="Choose one:") if (input == 0){ message("You have to pick a valid choice to play this. Try again.") } if (input >= 1 && input <= 5){ comp_choice <- sample(1:5, 1) message(paste0("you chose ", choices[input])) message(paste0("computer chose ", choices[comp_choice])) # 替换判定逻辑 user_wins <- any(sapply(wins, function(pair) all(pair == c(input, comp_choice)))) print(user_wins) if (input != comp_choice){ if (user_wins) { message("you won") } else message("you lost") } else message("it's a draw") } } fun()
验证效果
当选择剪刀(3)、电脑选蜥蜴(4)时,c(3,4)是wins中的配对,此时user_wins会返回TRUE,正确判定为胜利。
内容的提问来源于stack exchange,提问作者FB001
相关产品推荐
相关产品推荐

