Я пытаюсь работать с вложенными массивами для программы космических боев. Для боевых действий флота я пишу это:
//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();
}
Это решает проблему как срез, создает новый массив, а не просто копирует его.
В идеале я хочу сохранить два числа в массиве. я редактирую то, что хочу! Спасибо
Меня немного смущает ваш вопрос: я превратил ваш код в работоспособный фрагмент, и он уже генерирует нужный вам результат, учитывая входной массив, который вы показываете?
Я очень смущен тем, что ты прав. Просто укажите в моем коде имя переменной, отличное от оригинала. все еще не работает в исходном коде. Как вы думаете, я могу связать здесь файл .js?
Возьмите исходный код, который не работает, и сократите его до минимально воспроизводимого примера формы. Затем отредактируйте свое сообщение, вставив в него этот код, добавив ровно столько кода, чтобы вызвать его с некоторыми входными данными и показать выходные данные.
Просто обновите мой пост. Мне очень жаль, что я не проверил свой код вопроса раньше.
Обратите внимание, что вы оба превратили это обратно в неисполняемый код, а также оставили в нем кучу вещей, которые можно жестко запрограммировать. Статья минимальный воспроизводимый пример весьма полезна, научит вас, как преобразовать ваш код в его минимальную форму, что в данном случае означает наличие двух переменных, содержащих готовый ввод, с помощью которого вы вызываете decideTargets, а также регистрацию результат вызова этой функции. И еще раз убедитесь, что это работоспособный фрагмент, поскольку это обычный JS.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я бы не советовал мутировать исходную 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; }Я не понимаю, что [... ряд] делать.
Я распределяю row (массив столбцов) в новый массив «строки» и добавляю к нему дополнительный кортеж (пару случайных целых чисел) случайных рулонов.
Спасибо, теперь вы можете увидеть весь мой код (исходный вопрос был задан неправильно), но именно вы подсказали мне идею ответа.
Вы, наверное, хотите
push(randomNumber(10), randomNumber(10)), а неpush([randomNumber(10), randomNumber(10)])? Пожалуйста, покажите, какой результат вы надеетесь получить, а не только тот результат, который вы получаете. Тем не менее, помещение значений в массив в место, до которого ваш итератор еще не добрался, почти гарантированно приведет к ошибкам, поскольку добавление новых данных делает недействительным то, на что указывал бы счетчик цикла до того, как вы это сделали.