JavaScript Simon游戏checkAnswer函数循环逻辑疑问
问题解析:Simon游戏checkAnswer函数的循环逻辑误区
你的疑惑核心在于对checkAnswer函数中循环作用的误解,我们来拆解清楚:
误区所在
你以为进入关卡2后,当userClickedPattern长度(1)小于gamePattern长度(2)时,循环应该判定错误,但实际上循环的逻辑是只检查用户已经输入的元素对应的游戏序列位置,而非整个gamePattern。
看这段循环代码:
for (let i = 0; i < currentLevel.length; i++) if (gamePattern[i] !== currentLevel[i]) { // 游戏结束逻辑 return; }
当关卡2中你只点击了蓝色,currentLevel(即userClickedPattern)的长度是1,循环只会执行1次(i=0),对比gamePattern[0]和currentLevel[0]——两者都是blue,自然不会触发错误。这完全符合Simon游戏的逻辑:用户需要逐步输入序列,每输入一个元素就验证该位置是否正确,只有输入错误才会立即结束游戏,输入正确则等待用户继续完成当前关卡的序列。
你的代码逻辑是正确的
当前代码的流程是:
- 用户每点击一个按钮,就将颜色加入
userClickedPattern,并调用checkAnswer checkAnswer循环验证用户已输入的每一个元素是否和gamePattern对应位置一致- 如果全部输入正确且长度和
gamePattern相等,就进入下一关并清空userClickedPattern - 只要有一个位置输入错误,立即触发游戏结束
这正是Simon游戏的正确逻辑,你之前的误解是误以为循环要一次性验证整个gamePattern,但实际上循环的作用是逐步验证用户的每一步输入。
可选优化建议
checkAnswer函数不需要传入currentLevel参数,直接使用全局的userClickedPattern即可,避免参数冗余:
function checkAnswer() { for (let i = 0; i < userClickedPattern.length; i++) { if (gamePattern[i] !== userClickedPattern[i]) { $("h1").css("color", "red"); $("h1").text("GAME OVER"); return; } } if (userClickedPattern.length === gamePattern.length) { setTimeout(nextSequence, 1000); userClickedPattern = []; } }
- 另外,
animatePress函数定义在点击事件内部会导致每次点击都重新创建函数,建议把它移到全局作用域:
function animatePress(currentColour) { $("#" + currentColour).addClass("pressed"); setTimeout(() => { $("#" + currentColour).removeClass("pressed"); }, 100); } $("div[type='button']").click(function(e) { // ... 其他代码 animatePress(userChosenColour); checkAnswer(); });
内容的提问来源于stack exchange,提问作者LuckyTiger
相关产品推荐
相关产品推荐

