Почему в цикле обновляются все индексы nodejs

Я пытаюсь работать с вложенными массивами для программы космических боев. Для боевых действий флота я пишу это:


//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.info(firstFleet[i]);
    }
    return firstFleet;
}


/**
 * DEBUG
 */

//Building fleets
const attackerFleet = fleetConstructor(fleet1);
const defenderFleet = fleetConstructor(fleet2);


//Acquire targets
const finalCountdown = decideTargets(attackerFleet, defenderFleet);

Моя проблема в том, что функция defineTargets имеет целью каждый раз находить уникальный случайный массив. Но в журнале отображается следующее:

[
  [ 500, 200, 90, 50, [ 3, 4 ], [ 2, 7 ], [ 1, 0 ] ],
  [ 500, 200, 90, 50, [ 3, 4 ], [ 2, 7 ], [ 1, 0 ] ],
  [ 500, 200, 90, 50, [ 3, 4 ], [ 2, 7 ], [ 1, 0 ] ]
]
[
  [ 750, 300, 80, 25, [ 1, 6 ], [ 2, 3 ], [ 2, 4 ] ],
  [ 750, 300, 80, 25, [ 1, 6 ], [ 2, 3 ], [ 2, 4 ] ],
  [ 750, 300, 80, 25, [ 1, 6 ], [ 2, 3 ], [ 2, 4 ] ]
]
[
  [ 1500, 500, 75, 15, [ 3, 8 ], [ 3, 8 ], [ 0, 8 ] ],
  [ 1500, 500, 75, 15, [ 3, 8 ], [ 3, 8 ], [ 0, 8 ] ],
  [ 1500, 500, 75, 15, [ 3, 8 ], [ 3, 8 ], [ 0, 8 ] ]
]
[
  [ 750, 750, 80, 15, [ 0, 0 ], [ 2, 6 ], [ 0, 7 ] ],
  [ 750, 750, 80, 15, [ 0, 0 ], [ 2, 6 ], [ 0, 7 ] ],
  [ 750, 750, 80, 15, [ 0, 0 ], [ 2, 6 ], [ 0, 7 ] ]
]
[
  [ 3000, 1000, 70, 10, [ 1, 4 ], [ 3, 8 ], [ 1, 4 ] ],
  [ 3000, 1000, 70, 10, [ 1, 4 ], [ 3, 8 ], [ 1, 4 ] ],
  [ 3000, 1000, 70, 10, [ 1, 4 ], [ 3, 8 ], [ 1, 4 ] ]
]


Каждый раз во второй итерации он помещает случайный массив для всех значений j.

Я пытаюсь изменить циклы с помощью циклов while, изменить второй цикл for с помощью foreach. Я также попытался отделить оператор arrayArgument.push от другой функции (и вызвать его в двойном цикле for). Я получаю один и тот же результат каждый раз.

Массив, который мне нужен:

[
  [ 500, 200, 90, 50, [ 3, 4 ] ],
  [ 500, 200, 90, 50, [ 2, 7 ] ],
  [ 500, 200, 90, 50, [ 1, 0 ] ]
]
[
  [ 750, 300, 80, 25, [ 1, 6 ] ],
  [ 750, 300, 80, 25, [ 2, 3 ] ],
  [ 750, 300, 80, 25, [ 2, 4 ] ]
]
[
  [ 1500, 500, 75, 15, [ 3, 8 ] ],
  [ 1500, 500, 75, 15, [ 4, 5 ] ],
  [ 1500, 500, 75, 15, [ 0, 8 ] ]
]
[
  [ 750, 750, 80, 15, [ 0, 0 ] ],
  [ 750, 750, 80, 15, [ 2, 6 ] ],
  [ 750, 750, 80, 15, [ 0, 7 ] ]
]
[
  [ 3000, 1000, 70, 10, [ 1, 4 ] ],
  [ 3000, 1000, 70, 10, [ 3, 8 ] ],
  [ 3000, 1000, 70, 10, [ 1, 4 ] ]
]

РЕДАКТИРОВАТЬ (Ответ): в FleetConstructor() я создаю массив, используя в основном эту строку: array1 = array2. В Javascript это означает, что изменения в массиве1 влияют также и на массив2. поэтому мне нужно преобразовать каждый оператор for в:

    for (let f = 0; f < fleet[0]; f++) {
        finalFleetArray[0][f] = vaisseaux.frigate.slice();
    }

Это решает проблему как срез, создает новый массив, а не просто копирует его.

Вы, наверное, хотите push(randomNumber(10), randomNumber(10)), а не push([randomNumber(10), randomNumber(10)])? Пожалуйста, покажите, какой результат вы надеетесь получить, а не только тот результат, который вы получаете. Тем не менее, помещение значений в массив в место, до которого ваш итератор еще не добрался, почти гарантированно приведет к ошибкам, поскольку добавление новых данных делает недействительным то, на что указывал бы счетчик цикла до того, как вы это сделали.

Mike 'Pomax' Kamermans 26.09.2023 19:36

В идеале я хочу сохранить два числа в массиве. я редактирую то, что хочу! Спасибо

WinryAlchemist 26.09.2023 19:41

Меня немного смущает ваш вопрос: я превратил ваш код в работоспособный фрагмент, и он уже генерирует нужный вам результат, учитывая входной массив, который вы показываете?

Mike 'Pomax' Kamermans 26.09.2023 19:47

Я очень смущен тем, что ты прав. Просто укажите в моем коде имя переменной, отличное от оригинала. все еще не работает в исходном коде. Как вы думаете, я могу связать здесь файл .js?

WinryAlchemist 26.09.2023 20:23

Возьмите исходный код, который не работает, и сократите его до минимально воспроизводимого примера формы. Затем отредактируйте свое сообщение, вставив в него этот код, добавив ровно столько кода, чтобы вызвать его с некоторыми входными данными и показать выходные данные.

Mike 'Pomax' Kamermans 26.09.2023 20:25

Просто обновите мой пост. Мне очень жаль, что я не проверил свой код вопроса раньше.

WinryAlchemist 26.09.2023 20:44

Обратите внимание, что вы оба превратили это обратно в неисполняемый код, а также оставили в нем кучу вещей, которые можно жестко запрограммировать. Статья минимальный воспроизводимый пример весьма полезна, научит вас, как преобразовать ваш код в его минимальную форму, что в данном случае означает наличие двух переменных, содержащих готовый ввод, с помощью которого вы вызываете decideTargets, а также регистрацию результат вызова этой функции. И еще раз убедитесь, что это работоспособный фрагмент, поскольку это обычный JS.

Mike 'Pomax' Kamermans 26.09.2023 20:50
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
7
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я бы не советовал мутировать исходную 3D-матрицу.

Вместо этого вы можете сопоставить каждую плоскость, строку и столбец с новой копией с измененными столбцами.

Примечание. Я изменил функцию randomNumber, чтобы она принимала min и max.

const originalMatrix3d = [
  [[1,  2,  3,  4] , [1,  2,  3,  4] , [1,  2,  3,  4]],
  [[5,  6,  7,  8] , [5,  6,  7,  8] , [5,  6,  7,  8]],
  [[9, 10, 11, 12] , [9, 10, 11, 12] , [9, 10, 11, 12]]
];

const updatedMatrix3d = decideTargets(originalMatrix3d);

console.info(updatedMatrix3d.map(JSON.stringify));

function decideTargets(matrix3d) {
  return matrix3d.map(function(plane) {
    return plane.map(function(row) {
      return [...row, [randomNumber(1, 20), randomNumber(1, 20)]]
    });
  })
}

// Roll a dice function
function randomNumber(min, max) {
  if (arguments.length === 0) {
    throw new Error('You must supply a value');
  }
  if (arguments.length === 1) {
    max = min;
    min = 0;
  }
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

Я не понимаю, что [... ряд] делать.

WinryAlchemist 26.09.2023 20:27

Я распределяю row (массив столбцов) в новый массив «строки» и добавляю к нему дополнительный кортеж (пару случайных целых чисел) случайных рулонов.

Mr. Polywhirl 26.09.2023 20:52

Спасибо, теперь вы можете увидеть весь мой код (исходный вопрос был задан неправильно), но именно вы подсказали мне идею ответа.

WinryAlchemist 27.09.2023 00:15

Другие вопросы по теме