Поиск всех координат вокруг игрока в диапазоне

#javascript

Вопрос:

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

Мой код до сих пор таков:

 const generateMoveableAreas = (playerX, playerY, range) => {
  const moveableAreas = [];
  for (let i = range; i > 0; i--) {
    moveableAreas.push(
      { x: playerX   i, y: playerY },
      { x: playerX   i, y: playerY   i },
      { x: playerX, y: playerY   i },
      { x: playerX - i, y: playerY   i },
      { x: playerX - i, y: playerY },
      { x: playerX - i, y: playerY - i },
      { x: playerX, y: playerY - i },
      { x: playerX   i, y: playerY - i },
    );
  }
  return moveableAreas;
};
 

Это работает правильно, если диапазон равен 1, но если диапазон равен 2 или более, возникает проблема.
Вот пример того, как выглядит сетка — 0 недоступен, R доступен, U должен быть доступен, но его нет, а P-игрок. У игрока есть диапазон 2.

 0 0 0 0 0 0 0 
0 R U R U R 0 
0 U R R R U 0 
0 R R P R R 0 
0 U R R R U 0 
0 R U R U R 0 
0 0 0 0 0 0 0 
 

Что мне нужно, так это чтобы все эти точки U были R.

Комментарии:

1. Должны ли места, отмеченные как U доступные, быть доступны с текущей позиции игроков? Если да, то они точно недоступны, так как они не имеют диапазона в 2 хода, или я что-то упускаю?

2. Ваш код добавляет только ортогональные и диагональные ходы, поэтому ваши «достижимые области» — это ход шахматной королевы в пределах досягаемости.

3. @эмпирик Да, они должны быть доступны, но текущий код не позволяет им быть доступными.

4. @NiettheDarkAbsol Да, я знаю это, я пытаюсь сделать доступными и другие места, отмеченные U, но у меня возникли проблемы.

5. Определить «достижимый»? Может ли игрок двигаться по диагонали, или, другими словами, считается ли движение по диагонали 1 «шагом»?

Ответ №1:

Я думаю, что вы можете значительно упростить свой код.
Видя, что все точки в пределах <диапазона> доступны, вы можете просто использовать диапазон в качестве смещения для некоторых циклов, зацикливаясь на всех доступных координатах x/y:

 const generateMoveableAreas = (playerX, playerY, range) => {
  const moveableAreas = [];
  for (let x = -range; x <= range; x  ) {
    for (let y = -range; y <= range; y  ) {
      moveableAreas.push({ x: playerX   x, y: playerY   y })
    }
  }
  
  return moveableAreas;
};

const movable = generateMoveableAreas(0, 0, 2);
console.log(movable); 

Ответ №2:

Пройдитесь по всем точкам в радиусе действия:

 const generateMoveableAreas = (playerX, playerY, range) => {
  const moveableAreas = [];
  for (let i = Math.max(0, playerX - range); i <= playerX   range; i  ) {
    for (let j = Math.max(0, playerY - range);  j <= playerY   range; j  ) {
      moveableAreas.push(
        { x: i, y: j },
      );
    }
  }
  return moveableAreas;
};
 

Я добавил проверку, чтобы убедиться, что он не пытается добавлять ходы, которые находятся вне зоны досягаемости (

Ответ №3:

Доступные квадраты в основном представляют собой квадрат диапазона x 2 1. Это означает, что вы могли бы сделать что-то вроде :

 for (let i = playerX - range; i <= playerX   range; i  ) {
  for (let j = playerY - range; j <= playerY   range; j  ) {
    moveableAreas.push({ x: i, y: j });
  }
}