#javascript #arrays #dictionary #functional-programming
Вопрос:
Для контекста, это для классической игры в линкоры.
У меня есть массив сетки игровой доски, такой:
[[null, null, null, null, null],
[null, null, null, null, null],
[null, null, null, null, null],
[null, null, null, null, null],
[null, null, null, null, null]],
Я пытаюсь поместить ship
объект в массив. Объект состоит из некоторых свойств, таких как корабль name
, это length
и это index
(так что положение, в которое попал корабль, может быть отмечено на объекте корабля). Например, корабль, помещенный в первый ряд, может выглядеть так:
[null, {name: 'boat' , index: 0 }, {name: 'boat' , index: 1 }, null, null]
Я хочу добиться этого, используя принципы функционального программирования, и избежать изменения массива, что я сейчас и делаю (т. Е. Использую для циклов и настроек array[x][y] = {ship}
).
Я понимаю, что лучший способ достичь этого-использовать map()
.
Поскольку массив 2-мерный, я вкладываю две карты вместе. Моя функция до сих пор выглядит так:
const placeShip = (ship, x, y) => {
if (grid[x][y] !== null) return;
const newGrid = grid.map((row, indexX) => row.map((element, indexY) => {
if (indexX === x amp;amp; indexY === y) {
{
name: ship.name,
index: XXX
} // how to insert the index position?
}
}
return newGrid
}
Проблема, которую я испытываю, двояка. Во-первых, я не могу понять, как я могу правильно вставить положение индекса корабля в объект, используя вложенную карту. Это было достаточно просто, используя for
циклы, когда они начинаются 0
и заканчиваются ship.length
.
Во-вторых, я где-то ошибаюсь, и моя функция не возвращает 2d-массив с какими-либо объектами в нем, я просто получаю undefined
.
Где я ошибаюсь?
Спасибо
Комментарии:
1.
return
Вот и все.2. Не могли бы вы поподробнее, пожалуйста? Мне кажется, я слишком долго на это смотрел
3. Когда вы говорите
how to insert the index position?
, что неясно, какой индекс вы имеете в виду. Какой должна быть эта ценность? Один-единственный номер? массив с координатами x, y?4. @LearningPython вы ничего не возвращаете со своей внутренней карты row .map, поэтому в итоге вы получите сетку из
undefined
s. Что также приведет к тому, что ваша условная проверка в начале будет иметь ложные срабатывания при последующих вызовах.5. @Mark Я пытаюсь включить положение индекса длины судна. Возможно, это было неясно в примере, который я привожу в начале своего вопроса. В принципе, когда попадание помещается в сетку и попадает в корабль, мне нужно записать на объекте корабля, в какое положение был поражен корабль. Например, если он был длиной 4 клетки, был ли он поражен в 1-й, 2-й, 3-й или 4-й части его длины. Имеет ли это смысл?
Ответ №1:
Если вы рассматриваете только горизонтально расположенные корабли, вы можете проверить, отображается ли корабль на плитке следующим образом:
ri === r amp;amp; // The ship sails on the current row
ci >= c amp;amp; // The start of the ship lies left of this column
ci < c size // The end of the ship lies right of this column
Затем индекс между 0
и shipSize
может быть рассчитан с использованием: ci - c
Вот упрощенный пример:
const grid = Array.from(Array(4), () => Array(4).fill("~~"));
const placeShipH = (r, c, size, name, grid) => grid.map(
(row, ri) => row.map(
(col, ci) => ri === r amp;amp; ci >= c amp;amp; ci < c size
? `${name}${ci - c 1}`
: col
)
);
const placeShipV = (r, c, size, name, grid) => grid.map(
(row, ri) => row.map(
(col, ci) => ci === c amp;amp; ri >= r amp;amp; ri < r size
? `${name}${ri - r 1}`
: col
)
);
const gridToString = grid => grid.map(row => row.join(" ")).join("n");
const afterShipA = placeShipH(1, 1, 2, "A", grid);
const afterShipB = placeShipH(3, 0, 3, "B", afterShipA);
const afterShipC = placeShipV(0, 3, 3, "C", afterShipB)
console.log(gridToString(afterShipC));
Комментарии:
1. Спасибо, это именно то, что я искал. Я также собираюсь адаптировать его для вертикальных компоновок, что, как я полагаю, не должно быть слишком сложно.
2. Думаю, я заговорил слишком рано. Есть ли какие-либо существенные изменения в вышеизложенном для реализации вертикального размещения? Я использую
(columnIndex === column amp;amp; rowIndex >= row amp;amp; rowIndex < row ship.length)
, однако мне кажется, что я получаю бесконечно длинные колонные корабли.3. Код, который вы показали, мне нравится… Я добавил вертикальный пример в приведенном выше примере, и, похоже, он работает. Может
.length
быть, свойство не определено?