Odin Project石头剪刀布JS游戏循环与逻辑实现问题咨询
现有代码问题汇总
- 条件判断运算符错误:所有分支判断用了单
&(按位与运算符),应该替换为&&(逻辑与运算符),部分判断逻辑重复,比如剪刀对纸的情况同时写了给电脑加分和给玩家加分的分支,会导致计分错误 - 缺少平局处理逻辑:双方出相同选项时没有任何提示,也不会重开本轮
- 无取消操作适配:玩家点击prompt的取消按钮时会返回
null,现有代码没有对应判断,会直接进入无效逻辑 - 无输入校验:玩家输入非
rock/paper/scissors的内容时,没有错误提示也不会要求重新输入 - 变量泄漏:
game函数的for循环中i没有用let声明,会成为全局变量 - 获胜判定逻辑耦合:把全局获胜判断放在
round函数里,职责拆分不合理 - 未实现5轮制规则:现有逻辑是先到3胜直接结束,没有按照5轮制统计最终得分
优化后代码
// 生成电脑随机选择 function computerPlay() { const choice = ['rock', 'paper', 'scissors']; const randomPlay = Math.floor(Math.random() * choice.length); return choice[randomPlay]; } // 处理单轮对局 function round() { const computerChoice = computerPlay(); let playerChoice = prompt('请输入你的选择:rock/paper/scissors,点击取消可结束游戏'); // 处理玩家取消操作 if (playerChoice === null) { return 'cancel'; } // 统一转小写,兼容大小写输入 playerChoice = playerChoice.trim().toLowerCase(); // 输入合法性校验 if (!['rock', 'paper', 'scissors'].includes(playerChoice)) { alert('输入无效,请输入rock、paper、scissors其中一个'); return 'retry'; } // 平局判断 if (playerChoice === computerChoice) { alert(`平局!你们都出了${playerChoice}`); return 'draw'; } // 用对象映射简化输赢判断逻辑,避免冗余if else const winMap = { rock: 'scissors', paper: 'rock', scissors: 'paper' }; if (winMap[playerChoice] === computerChoice) { alert(`你赢了!${playerChoice} beats ${computerChoice}`); return 'player'; } else { alert(`你输了!${computerChoice} beats ${playerChoice}`); return 'computer'; } } // 游戏主流程控制 function game() { let playerScore = 0; let computerScore = 0; let roundCount = 0; const maxRound = 5; // 标准5轮制配置 const winThreshold = 3; // 提前获胜阈值,先到3胜直接结束 while (roundCount < maxRound && playerScore < winThreshold && computerScore < winThreshold) { const result = round(); // 玩家取消直接结束游戏 if (result === 'cancel') { alert('游戏已取消'); return; } // 输入错误、平局不计入回合数,重开本轮 if (result === 'retry' || result === 'draw') { continue; } // 正常对局计分 result === 'player' ? playerScore++ : computerScore++; roundCount++; // 每轮结束提示当前比分 alert(`第${roundCount}轮结束,当前比分:你 ${playerScore} - ${computerScore} 电脑`); } // 最终结果判定 if (playerScore > computerScore) { alert(`游戏结束,你赢了!最终比分:你 ${playerScore} - ${computerScore} 电脑`); } else if (computerScore > playerScore) { alert(`游戏结束,电脑赢了!最终比分:你 ${playerScore} - ${computerScore} 电脑`); } else { alert(`游戏结束,平局!最终比分:你 ${playerScore} - ${computerScore} 电脑`); } } game();
优化点说明
- 支持取消游戏:判断prompt返回
null直接终止游戏流程 - 实现标准5轮制:同时满足「未到5轮」和「没人先到3胜」才继续对局,同时兼容提前获胜的规则
- 新增平局处理:平局不计入回合数,自动重开本轮
- 新增输入校验:输入错误时提示重新输入,不计入回合
- 简化判断逻辑:用对象映射输赢关系,不用写长串if else,后续维护修改更方便
- 避免全局变量污染:把计分变量放在game函数内部,不需要占用全局变量
- 职责拆分清晰:round函数只负责单轮对局返回结果,game函数负责流程控制、计分、结果判定,逻辑更清晰
内容的提问来源于stack exchange,提问作者user16880853
相关产品推荐
相关产品推荐

