如何通过递归等方法精简游戏胜利条件生成的JavaScript代码
游戏胜利条件生成逻辑重构方案
原代码问题
- 硬编码了
currDiff=4场景下的4段重复条件判断,调整参数时需要全量修改分支逻辑,维护成本高 - 通过数值差值间接判断组内位置是否重复,逻辑绕且易出错
- 存在隐式全局变量
winCond,易造成全局命名空间污染 - 逐个数入组再判断长度的分组写法冗余
核心优化思路
- 抽象通用选数规则:每
currDiff个分组组成一个校验块(对应16个数字),块内从每个分组选取的元素,组内位置不得重复,每结束一个块重置校验状态 - 用
Set结构存储当前块已使用的组内位置,校验时直接判断位置是否存在,替代原有的多段数值对比逻辑 - 直接按步长切片生成数字分组,替代逐个数入组的冗余写法
- 所有变量限定在函数作用域内,最终返回生成的胜利条件数组,避免全局污染
- 逻辑天然支持
currDiff参数调整,无需修改核心代码即可适配不同尺寸的规则
重构后实现代码
// 假设已有shuffle函数:输入数组返回打乱后的新数组 let currDiff = 4; function createWinCond() { const totalLength = currDiff ** 3; // 生成0~63的完整数字数组 const totalNums = Array.from({ length: totalLength }, (_, idx) => idx); const groups = []; // 每currDiff个数字切分为一组,每组单独打乱 for (let i = 0; i < totalLength; i += currDiff) { groups.push(shuffle(totalNums.slice(i, i + currDiff))); } const winCond = []; let usedPositions = new Set(); // 遍历所有分组选数 for (let groupIdx = 0; groupIdx < groups.length; groupIdx++) { // 每currDiff个分组为一个校验块,重置已用位置记录 if (groupIdx % currDiff === 0) { usedPositions = new Set(); } const currentGroup = groups[groupIdx]; // 找到当前分组内第一个位置未被占用的元素 for (let pos = 0; pos < currentGroup.length; pos++) { if (!usedPositions.has(pos)) { winCond.push(currentGroup[pos]); usedPositions.add(pos); break; } } } return winCond; }
逻辑匹配说明
- 首个分组进入新块,已用位置为空,直接选取组内第一个元素,符合规则
- 块内第二个分组选数时,已用位置仅包含首个元素的位置,自动跳过该位置选取下一个合法元素,符合规则
- 块内第三、第四个分组选数时,自动校验所有已用位置,选取第一个未被占用位置的元素,符合规则
- 每处理完4个分组(16个数字)自动重置已用位置记录,开启下一个块的校验,符合规则
- 因分组提前打乱,选数时会自动匹配示例中跳过冲突位置、选取非连续下标的场景,最终生成16个元素的胜利条件数组
内容的提问来源于stack exchange,提问作者Alex Bird
相关产品推荐
相关产品推荐

