JavaScript开发扫雷游戏如何解决随机地雷位置重复问题?
问题原因
你当前的代码没有做随机索引去重逻辑,多次调用Math.random()生成索引时,很可能多次命中同一个tile元素。同一个div多次设置红色背景,最终也只会被识别为1个地雷,所以实际生成的地雷数会低于你设定的numMines值。
修复后可直接使用的代码
// 将类数组转为真实数组方便后续操作 const tiles = Array.from(document.getElementsByClassName('tile')); // 自定义地雷数量 const numMines = 8; // Set自带去重特性,用来存地雷索引不会出现重复 const mineIndexes = new Set(); // 直到索引集合的长度达到设定的地雷数,才停止生成随机索引 while (mineIndexes.size < numMines) { const randomIndex = Math.floor(Math.random() * tiles.length); mineIndexes.add(randomIndex); } // 统一给地雷元素设置样式和标记 mineIndexes.forEach(index => { // 建议后续改用加CSS类的方式控制样式,不要直接改style tiles[index].style.backgroundColor = 'red'; // 加自定义属性标记地雷,后续点击判断、计算周边地雷数时直接读取即可 tiles[index].dataset.isMine = 'true'; });
代码优化建议
- 不要硬编码重复逻辑:原来的代码写了25次重复的随机取值、25次样式设置,后续要调整地雷数量需要改多处代码,用循环或者遍历逻辑可以实现一处修改全局生效
- 所有变量都要加声明关键字:原来的
i、bomb变量没有加let/const声明,会自动变为全局变量,很容易引发变量污染导致未知bug - 删除无意义的循环逻辑:原来写的
for (i = 0; i < 1; i++)只会执行1次,完全没有存在必要,可以直接删掉 - 用合适的数据结构简化逻辑:Set自带去重特性,非常适合生成不重复随机值的场景,不需要自己写重复判断逻辑
- 用CSS类控制元素样式:不要直接在JS里修改
style属性,建议先在CSS里定义.mine { background-color: red; }类,给地雷元素加这个类即可,后续要调整地雷样式直接改CSS就行,不需要动JS代码 - 提前给元素加业务标记:给地雷元素加
data-is-mine这类自定义属性,后续做点击判断、计算周边地雷数量时,直接读取元素属性即可,不需要再遍历地雷数组比对
内容的提问来源于stack exchange,提问作者user16391464
相关产品推荐
相关产品推荐

