У меня есть игра, состоящая из кораблей, которые летают по двумерной сетке. Я пишу функцию, которая берет местоположение и выясняет, можно ли оттуда попасть (предопределенную) цель. Это просто требует проверки всех квадратов сетки на линии огня потенциального агрессора.
В большинстве случаев это крест, сформированный так:
(currX +/- SHOT_RANGE, currY) and (currX, currY +/- SHOT_RANGE)
Где SHOT_RANGE
- максимальное расстояние, на которое может пройти выстрел, и в настоящее время стреляющий корабль находится на (currX, currY)
.
Код для проверки этих двух строк довольно прост:
for (int i = x - SHOT_RANGE; i < x + SHOT_RANGE; i++) {
if (target.TileX == i && target.TileY == y) {
return true;
}
}
for (int j = y - SHOT_RANGE; j < y + SHOT_RANGE; j++) {
if (target.TileX == x && target.TileY == j) {
return true;
}
}
Однако на некоторых «силовых клетках» корабль также может стрелять по диагонали. Все эти квадраты тоже должны быть проверены. Вот где приходит повторение. Можете ли вы найти способ сделать это с меньшим количеством кода?
/// <param name="x">Current x-coord of the potential ship</param>
/// <param name="y">Current y-coord of the potential ship</param>
private bool CanShootTargetFrom(int x, int y) {
if ((target.TileX == x && Math.Abs(target.TileY - y) <= SHOT_RANGE) || (target.TileY == y && Math.Abs(target.TileX - x) <= SHOT_RANGE)) {
return true;
}
if (board.IsPowerTileAt(x, y)) {
int i = x - SHOT_RANGE;
int j = y - SHOT_RANGE;
while (i != x + SHOT_RANGE && j != y + SHOT_RANGE) {
if (target.TileX == i && target.TileY == j) {
return true;
}
i++;
j++;
}
i = x - SHOT_RANGE;
j = y + SHOT_RANGE;
while (i != x + SHOT_RANGE && j != y - SHOT_RANGE) {
if (target.TileX == i && target.TileY == j) {
return true;
}
i++;
j--;
}
}
return false;
}
Обновлен, чтобы использовать предложение Карры, и я понял, что могу устранить две петли, проверяющие диагонали, увеличив верхние границы.