JS石头剪刀布游戏alert与console输出不一致、计分异常问题
石头剪刀布游戏异常修复
预设计分规则
- 用户获胜:计分变量
winCounter加1 - 双方平局:
winCounter加0.5 - 用户失败:
winCounter分数保持不变
异常表现
- 结果输出不一致:alert弹窗展示的单局对局结果,和console控制台打印的结果不匹配,有时弹窗提示用户获胜,控制台却显示对局失败或平局
- 计分逻辑错误:例如对局结果为3胜、1平、1负时,按照规则应累计得分为3.5,但实际显示为5.5,总对局数仅5局的情况下分数最高为5分,数值明显不符合逻辑

问题复现代码
let winCounter = 0; // playRound 函数执行单轮石头剪刀布逻辑并返回结果 function playRound(playerSelection, computerSelection) { let getPlayerInsensitive = playerSelection.toLowerCase(); if (getPlayerInsensitive === "rock" && computerSelection === "Rock") { winCounter+=0.5; return "It's a tie, both are Rock"; } else if (getPlayerInsensitive === "rock" && computerSelection === "Paper") { winCounter = winCounter; return "You Lose! Paper beats Rock"; } else if (getPlayerInsensitive === "rock" && computerSelection === "Scissors") { winCounter+=1; return "You win! Rock beats Scissors"; } else if (getPlayerInsensitive === "paper" && computerSelection === "Rock") { winCounter+=1; return "You win! Paper beats Rock"; } else if (getPlayerInsensitive === "paper" && computerSelection === "Paper") { winCounter+=0.5; return "It's a tie! Both are Paper"; } else if (getPlayerInsensitive === "paper" && computerSelection === "Scissors") { winCounter = winCounter; return "You lose! Scissors beats Paper"; } else if (getPlayerInsensitive === "scissors" && computerSelection === "Rock") { winCounter = winCounter; return "You lose! Rock beats Scissors"; } else if (getPlayerInsensitive === "scissors" && computerSelection === "Scissors") { winCounter=0.5; return "It's a tie! Both are Scissors"; } else if (getPlayerInsensitive === "scissors" && computerSelection === "Paper") { winCounter+=1; return "You win! Scissors beat Paper"; } else { return "Check your spelling!"; } } // game 函数执行5轮对局后返回最终胜负结果 function game() { for (let i = 0; i < 5; i++) { let getSelect = prompt("Choose Rock, Paper, or Scissors", ""); if (getSelect === null || getSelect === "") { alert("You clicked Cancel!"); } alert(playRound(getSelect, computerPlay())); if (i < 5) { console.log(playRound(getSelect, computerPlay())); } if (i === 4) { alert("You've played 5 games"); if (winCounter >= 3) { alert(`You've won ${winCounter} out of 5 games. You win!`); return `You've won ${winCounter} out of 5 games. You win!`; } else if (winCounter === 2.5) { alert(`You've won 2.5 out of 5 games. It's a tie!`); return `You've won 2.5 out of 5 games. It's a tie!`; } else if (winCounter < 2.5) { alert(`You've won ${winCounter} out of 5 games. You lost!`); return `You've won ${winCounter} out of 5 games. You lost!`; } } } } console.log(game());
问题根因
- 单轮重复执行对局逻辑:循环内分别在alert和console.log语句处两次调用
playRound,且每次调用都重新执行computerPlay()生成随机的电脑出拳,等于每轮实际进行了两局对局:第一局结果用于弹窗展示,第二局重新随机出拳的结果用于控制台打印,两次调用都会修改winCounter分数,直接导致结果不匹配、分数虚高 - 平局分支计分逻辑错误:剪刀对剪刀的平局判断分支中,代码写为
winCounter=0.5,是直接把总分赋值为0.5,而非累加0.5,会直接覆盖之前所有轮次的累计得分 - 无效输入无中断处理:用户点击取消或者输入空内容时,仅弹出提示,没有跳过本轮逻辑,空值传入对局函数后会触发拼写错误提示,同时干扰正常计分
修复方法
- 每轮只生成一次电脑出拳、只调用一次
playRound,将返回的对局结果存在变量中,复用于弹窗和控制台打印,避免重复执行计分逻辑、重复随机出拳 - 修正剪刀平局分支的计分代码,将直接赋值改为
winCounter += 0.5,和其他平局分支逻辑保持一致 - 检测到空输入/取消操作时,回退轮次计数并跳过本轮逻辑,不执行后续对局计分
修复后核心代码示例
let winCounter = 0; function playRound(playerSelection, computerSelection) { let getPlayerInsensitive = playerSelection.toLowerCase(); if (getPlayerInsensitive === "rock" && computerSelection === "Rock") { winCounter+=0.5; return "It's a tie, both are Rock"; } else if (getPlayerInsensitive === "rock" && computerSelection === "Paper") { return "You Lose! Paper beats Rock"; } else if (getPlayerInsensitive === "rock" && computerSelection === "Scissors") { winCounter+=1; return "You win! Rock beats Scissors"; } else if (getPlayerInsensitive === "paper" && computerSelection === "Rock") { winCounter+=1; return "You win! Paper beats Rock"; } else if (getPlayerInsensitive === "paper" && computerSelection === "Paper") { winCounter+=0.5; return "It's a tie! Both are Paper"; } else if (getPlayerInsensitive === "paper" && computerSelection === "Scissors") { return "You lose! Scissors beats Paper"; } else if (getPlayerInsensitive === "scissors" && computerSelection === "Rock") { return "You lose! Rock beats Scissors"; } else if (getPlayerInsensitive === "scissors" && computerSelection === "Scissors") { // 修正赋值逻辑为累加 winCounter += 0.5; return "It's a tie! Both are Scissors"; } else if (getPlayerInsensitive === "scissors" && computerSelection === "Paper") { winCounter+=1; return "You win! Scissors beat Paper"; } else { return "Check your spelling!"; } } function game() { // 对局开始前重置计分,避免多次启动游戏分数累加 winCounter = 0; for (let i = 0; i < 5; i++) { let getSelect = prompt("Choose Rock, Paper, or Scissors", ""); if (getSelect === null || getSelect.trim() === "") { alert("Invalid input, please try again"); // 输入无效时回退轮次,不占用对局次数 i--; continue; } // 单次生成电脑出拳,单次执行对局逻辑 const computerChoice = computerPlay(); const roundResult = playRound(getSelect, computerChoice); alert(roundResult); console.log(roundResult); if (i === 4) { alert("You've played 5 games"); let finalMsg; if (winCounter >= 3) { finalMsg = `You've won ${winCounter} out of 5 games. You win!`; } else if (winCounter === 2.5) { finalMsg = `You've won 2.5 out of 5 games. It's a tie!`; } else { finalMsg = `You've won ${winCounter} out of 5 games. You lost!`; } alert(finalMsg); return finalMsg; } } } console.log(game());
内容的提问来源于stack exchange,提问作者jared-dev
相关产品推荐
相关产品推荐

