You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 00:47:02