Web俄罗斯方块:else if与while条件相同时while语句报错致网站失效求助
Web版俄罗斯方块随机不重复方块生成异常问题分析
问题背景
开发Web版俄罗斯方块时,期望实现方块随机生成且无重复的功能:当所有7种方块类型都已生成后,重置存储已生成方块ID的block列表。但网站无法正常运行,问题出在playerReset函数的逻辑错误上。
错误代码分析
原代码片段中,else if分支与内部while循环的条件完全一致,导致逻辑矛盾:
function playerReset(){ const pieces = "TJLOSZI"; let randomNum = (pieces.length * Math.random()) | 0 if ((block.indexOf(0) !== -1) && (block.indexOf(1) !== -1) && (block.indexOf(2) !== -1) && (block.indexOf(3) !== -1) && (block.indexOf(4) !== -1) && (block.indexOf(5) !== -1) && (block.indexOf(6) !== -1)) { block = []; block.push(randomNum); } else if(block.indexOf(randomNum) === -1){ // 此处条件与while循环条件完全相同,逻辑彻底反转 while(block.indexOf(randomNum) === -1){ randomNum = (pieces.length * Math.random()) | 0 }; block.push(randomNum); } else{ block.push(randomNum); } // 后续代码... }
核心错误原因
- 逻辑反转导致死循环:
else if的条件是「当前生成的randomNum不在block列表中」,但内部while循环的条件也是「randomNum不在block列表中」,这意味着循环会持续生成新的随机数,直到得到一个已经存在于block中的值才会停止。这不仅完全违背了「无重复存入」的需求,还会在block未填满时,大概率陷入长时间循环,占用大量CPU资源,导致页面卡顿甚至无响应。 - 分支逻辑混乱:
最后的else分支会直接将已存在于block中的randomNum再次存入,进一步导致重复数据,破坏了无重复的核心需求。
修正后的代码方案
简化逻辑,确保每次存入block的都是未出现过的方块ID,当所有方块都出现后重置列表:
function playerReset(){ const pieces = "TJLOSZI"; let randomNum = (pieces.length * Math.random()) | 0; // 简化判断:检查所有7种方块是否都已生成 const allPiecesGenerated = [0,1,2,3,4,5,6].every(num => block.includes(num)); if (allPiecesGenerated) { // 所有方块都已生成,重置列表并加入当前随机数 block = []; block.push(randomNum); } else { // 生成一个未在block中出现过的随机数 while(block.includes(randomNum)){ randomNum = (pieces.length * Math.random()) | 0; } block.push(randomNum); } // 后续代码... }
修正逻辑说明
- 用
every+includes简化了所有方块生成的判断,代码更简洁易维护。 - 去掉了混乱的分支,仅保留两种核心场景:重置列表/生成不重复的随机数。
while循环条件改为「randomNum已存在于block中」,确保循环会持续生成新值,直到得到未出现过的方块ID,完全符合需求。
内容的提问来源于stack exchange,提问作者KDYa08
相关产品推荐
相关产品推荐

