You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odin Project石头剪刀布JS游戏循环问题:为何结果重复?

解决你的石头剪刀布游戏循环问题

嘿,作为编程新手遇到这种问题太正常啦!我帮你拆解一下问题出在哪,一步一步来解决~

问题1:电脑选择从头到尾没变化

你看哦,你在全局作用域里写了 const computerSelection = computerPlay(); —— 这行代码只会在程序一开始执行一次,也就是说电脑从始至终只会出同一个手势!比如第一次随机到了paper,那5次循环里电脑全出paper,和你固定的rock比,自然每次都是输,结果就全是"You lose"啦。

问题2:循环里重复调用playRound还传参错误

在game()的循环里,你做了三件事:

  • console.log(playRound(playerSelection, computerSelection)); —— 这里正确传了参数,得到一次结果
  • if(playRound()==win) —— 这里没传参数!函数里的playerSelection和computerSelection会变成undefined,导致round也是undefined
  • 后面的else if和else又各调用了一次playRound

这就导致:

  • 每次循环你其实计算了3次结果,但后两次都是无效的
  • 你的计数逻辑完全错了,因为后两次调用的结果根本不是这次循环的真实结果

修正方案

我们来一步步改代码:

第一步:把电脑选择的生成放到循环里

每次循环都让电脑重新出一次手势,而不是只出一次。

第二步:只调用一次playRound并保存结果

把每次循环的结果存到变量里,然后用这个变量去输出和计数,避免重复调用导致的混乱。

修正后的完整代码

/*variable declarations*/
var result = {win:0, tie:0, loss:0};
let playerChoice= "rock";
//let playerChoice = prompt("Rock, Paper, or Scissors");
// 这里不要提前初始化computerSelection和playerSelection,放到需要的地方再处理
let win = "You win";
let tie = "tie";
let loss = "You lose";

function computerPlay(){
 let a = Math.floor(Math.random() * 11);
 switch (a){
 case 0:
 case 1:
 case 2:
 case 3:
 return "rock";
 case 4:
 case 5:
 case 6:
 case 7:
 return "paper";
 default:
 return "scissors";
 }
}

function caseInsensitive(){
 return playerChoice.toLowerCase();
}

function playRound(playerSelection, computerSelection){
 let round;
 if(playerSelection==="rock"){
 switch(computerSelection){
 case "paper":
 round= loss;
 break;
 case "rock":
 round =tie;
 break;
 case "scissors":
 round= win;
 break;
 }
 }
 if(playerSelection=="paper"){
 switch(computerSelection){
 case "scissors":
 round= loss;
 break;
 case "paper":
 round = tie;
 break;
 case "rock":
 round = win;
 break;
 }
 }
 if(playerSelection=="scissors"){
 switch(computerSelection){
 case "rock":
 round= loss;
 break;
 case "scissors":
 round= tie;
 break;
 case "paper":
 round= win;
 break;
 }
 }
 return round;
}

function game(){
 for(let i=0;i<5;i++){ // 加let声明i,避免全局变量污染
    const computerSelection = computerPlay(); // 每次循环重新生成电脑选择
    const playerSelection = caseInsensitive(); // 每次循环重新处理玩家选择(以后改prompt也能生效)
    const roundResult = playRound(playerSelection, computerSelection); // 只调用一次,保存结果
    console.log(roundResult);
    
    // 用保存的结果来计数
    if(roundResult === win){
        result.win++;
    }else if(roundResult === tie){
        result.tie++;
    }else{
        result.loss++;
    }
 }
 console.log("Wins: " +result.win);
 console.log("Losses: " +result.loss);
 console.log("Ties: " +result.tie);
}

game();

额外小建议

  • 循环里的i要加let声明,不然会变成全局变量,可能导致其他地方出问题
  • 以后如果把playerChoice改回prompt,现在的代码也能正常工作,因为每次循环都会重新处理玩家输入的大小写

这样改完之后,你再运行代码,就能看到5次不同的结果,计数也会准确啦!

内容的提问来源于stack exchange,提问作者EveG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 00:17:51