Node.js中循环为何更新所有数组索引?太空战舰程序问题
问题:太空战舰对战程序中同类型战舰共享目标的问题及解决方法
我正在开发一款太空战舰对战程序,使用嵌套数组实现舰队战斗逻辑,编写的代码如下:
//Roll a dice function const randomNumber = (number) => { return Math.floor(Math.random() * number); } //Here we declare ships stats // - 0 : Health // - 1 : Damages // - 2 : Chances to hit // - 3 : Chances to be hit // - 4 (add by decideTargets function (line 100)) : Position of the target in enemy fleet const vaisseaux = { frigate : [500, 200, 90, 50], heavyFrigate : [750, 300, 80, 25], cruiser : [1500, 500, 75, 15], attackCruiser : [750, 750, 80, 15], battleship : [3000, 1000, 70, 10] } /** * Here we declare the composition of the fleet * - 0 : Friates * - 1 : Heavy Frigates * - 2 : Cruisers * - 3 : Attack Cruisers * - 4 : Battleships */ const fleet1 = [3, 3, 3, 3, 3]; const fleet2 = [10, 10, 10, 10, 10]; function fleetConstructor(fleet) { /** * Here, we build an array of ships in fleets. * It'll be a 2 dimentions array * ___________________________________________________________ * |Frigates | HFrigates | Cruisers | ACruisers | BShip | * |---------|-----------|-----------|------------|-----------| * |stats F1 | stats HF1 | stats C1 | stats AC1 | stats BS1 | * |stats F2 | stats HF2 | stats C2 | stats AC2 | stats BS2 | * |etc ... | etc ... | etc ... | etc ... | etc ... | * */ const finalFleetArray = [[], [], [], [], []]; for (let f = 0; f < fleet[0]; f++) { finalFleetArray[0].push(vaisseaux.frigate); } for (let f = 0; f < fleet[0]; f++) { finalFleetArray[1].push(vaisseaux.heavyFrigate); } for (let f = 0; f < fleet[0]; f++) { finalFleetArray[2].push(vaisseaux.cruiser); } for (let f = 0; f < fleet[0]; f++) { finalFleetArray[3].push(vaisseaux.attackCruiser); } for (let f = 0; f < fleet[0]; f++) { finalFleetArray[4].push(vaisseaux.battleship); } return finalFleetArray; } function decideTargets(firstFleet, secondFleet) { /** * Here we need to find distint target to every ships in fleets * Return fleet array */ // i go throught ship types for(let i = 0; i < firstFleet.length; i++) { // j go throught each ship for (let j = 0; j < firstFleet[i].length; j++) { firstFleet[i][j].push([ randomNumber(secondFleet.length - 1), randomNumber(secondFleet[i].length - 1) ]); } console.log(firstFleet[i]); } return firstFleet; } /** * DEBUG */ //Building fleets const attackerFleet = fleetConstructor(fleet1); const defenderFleet = fleetConstructor(fleet2); //Acquire targets const finalCountdown = decideTargets(attackerFleet, defenderFleet);
遇到的问题
decideTargets函数本应为每艘战舰分配唯一的随机目标数组,但日志输出显示同类型的所有战舰都被添加了相同的多组目标值,每次内层循环迭代时,所有j对应的元素都会被更新。尝试过将for循环改为while循环、forEach,也尝试过将push操作拆分到单独函数中调用,结果始终一致。
期望的数组格式
[ [ 500, 200, 90, 50, [ 3, 4 ] ], [ 500, 200, 90, 50, [ 2, 7 ] ], [ 500, 200, 90, 50, [ 1, 0 ] ] ] [...其余期望输出省略]
解决方案
问题根源在于fleetConstructor函数中直接进行数组赋值(array1 = array2),在JavaScript中这种操作会导致两个变量引用同一数组,修改其中一个数组会影响另一个。
需要使用slice()方法创建数组的新副本,而非直接复制引用。将fleetConstructor中的每个for循环修改为如下形式:
for (let f = 0; f < fleet[0]; f++) { finalFleetArray[0][f] = vaisseaux.frigate.slice(); }
对其他战舰类型的循环做同样修改后,每艘战舰都会拥有独立的数组实例,decideTargets函数就能为每艘战舰分配唯一的随机目标了。
内容的提问来源于stack exchange,提问作者WinryAlchemist
相关产品推荐
相关产品推荐

