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

如何修复石头剪刀布游戏中isValid()函数的循环异常问题?

石头剪刀布游戏isValid()函数问题修复

问题描述

开发了一款通过prompt交互的石头剪刀布游戏,其余功能正常,但isValid()函数仅执行一次循环,只有输入R能正常进入游戏,输入P或S会触发无效输入提示。尝试将数组转为字符串输出未解决问题,需分析原因并修复。

原游戏代码

var options = ['R','P','S','r','p','s']
var userRes;
var checkVar;
var compChoice;
var checkStat;

var winStat = 0;
var lossStat = 0;
var tieStat = 0;

function isValid() {
    for (var i = 0; i < options.length; i++) {
        const found = options[i];
        if (userRes === found) {
            return checkVar = true;
        } else if (userRes !== found) {
            return checkVar = false;
        }
    }
}

function getCompChoice() {
    let compSet = options[Math.floor(Math.random() * options.length)];
    compChoice = compSet.toUpperCase();
    console.log(compChoice)
    return alert('The computer chose ' + compChoice);
}

function getUserChoice () {
    userSet = prompt('Rock Paper or Scissors?');
    if (userSet === null) {
        return startGame();
    } else {
        userRes = userSet.toUpperCase();
    }
    isValid()
    if (checkVar === true) {

        console.log('continue')
        userRes.toUpperCase();
        console.log(userRes);

        getCompChoice()

        if((userRes === 'R' && compChoice === 'S') ||
        (userRes === 'P' && compChoice === 'R' ||
        (userRes === 'S' && compChoice === 'P'))) {
            console.log('win')
            alert('You Won !')
            checkStat = true
            playAgain()
        } else if (userRes === compChoice) {
            console.log('tie')
            alert('You Tied !')
            checkStat = null
            playAgain()
        } else if (userRes !== compChoice) {
            console.log('loss')
            alert('You Lost !')
            checkStat = false
            playAgain()
        }
    } else if (checkVar === false) {
        console.log('end')
        console.log(userRes);

        alert('Please enter R, P, or S. (Not case sensitive).');
        getUserChoice();
    }

}

function playAgain() {
    if (checkStat) {
        winStat++;
        alert('Your Stats:\nWins: ' + winStat + '\nLosses: ' + lossStat + '\nTies: ' + tieStat)
    } else if (checkStat === null){
        tieStat++;
        alert('Your Stats:\nWins: ' + winStat + '\nLosses: ' + lossStat + '\nTies: ' + tieStat)
    } else if (!checkStat) {
        lossStat++;
        alert('Your Stats:\nWins: ' + winStat + '\nLosses: ' + lossStat + '\nTies: ' + tieStat)
    }

    pAgain = confirm('Play Again ?')
    if (pAgain) {
        getUserChoice();
    }
}

function startGame () {
    askUser = confirm('Would you like to play a game of Rock, Paper, Scissors ?')
    if (askUser) {
        return getUserChoice();
    } else if (!askUser) {
        return alert('Come back next time !')
    }
}

startGame();

问题原因

isValid()函数的循环逻辑错误:

  • 循环第一次执行时,若用户输入的userRes不等于数组第一个元素'R',会直接执行return checkVar = false,终止循环,不会检查后续的'P'、'S'等元素。
  • 只有当用户输入恰好是'R'(或'r')时,才会返回true,其他有效输入都会被误判为无效。

修复方案

方案1:修正循环逻辑

修改isValid()函数,先默认设为无效,遍历所有元素找到匹配项后标记为有效,循环结束后返回结果:

function isValid() {
    checkVar = false; // 默认设为无效
    for (var i = 0; i < options.length; i++) {
        const found = options[i];
        if (userRes === found) {
            checkVar = true; // 找到匹配项,标记为有效
            break; // 找到后跳出循环,无需继续遍历
        }
    }
    return checkVar;
}

方案2:使用数组includes()方法简化代码

由于getUserChoice()中已经将userRes转为大写,options数组可以简化为仅存大写字母,再用includes()直接判断是否包含有效输入,代码更简洁:

// 先简化options数组
var options = ['R','P','S'];

function isValid() {
    return checkVar = options.includes(userRes);
}

额外优化建议

  • 用let或const替代var声明变量,避免全局变量污染(比如userSet、pAgain、askUser这些变量都没声明,会自动成为全局变量)。
  • getUserChoice()中userRes.toUpperCase();这行代码多余,因为之前已经执行过userRes = userSet.toUpperCase();,可以删除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 05:07:23