Альтернативный алгоритм 4, написанный подробно и рождённый быть верным.Клетки гексагонального поля можно представить в виде квадратов. Само поле можно представить как таблицу (набор строк и столбцов), каждый элемент которой имеет координаты "x" и "y". Самый первый элемент имеет координаты (0;0). Отличие такого поля от строгой таблицы в том, что нечётные строки в нём смещены на пол клетки вправо:

Наша первая задача - определить координаты x/y элемента таблицы с указанным порядковым номером. Говоря проще - координаты нужного квадратика, в котором в игре будет стоять монстрик.
Для строгой таблицы формулы следующие:
Код
х = ОстатокОтДеления (НомерКлетки : ДлинаСтроки)
у = ЦелаяЧастьОт (НомерКлетки : ДлинаСтроки)
Вычислим, например, координаты клетки №5.
Код
х = ОстатокОтДеления (5 : 3) = 2 (напомню, координаты считаются от нуля: 0, 1, 2).
у = ЦелаяЧастьОт (5 : 3) = 1
Отличие нашей нестрогой таблицы от строгой в том, что элементы нечётных строк сдвинуты на 0.5 клетки по оси "х" вправо. Поэтому необходимо проверить, является ли строка нечётной, и если да, то прибавить к координате "х" 0.5.
Код
ЕСЛИ ОстатокОтДеления (у : 2) = 0 ТО х:=х+0.5
Теперь мы можем вычислить строгие координаты любой клетки. Осталось определиться с алгоритмом вычисления расстояния между ними. Чисто математически мы можем найти разницу по модулю координат обоих клеток. Теперь нужно решить, как монстр из точки А будет двигаться в точку Б, например из Клетки(8) в Клетку(0). Вполне логично предположить, что он будет двигаться по y-координате, пока не дойдёт до линии цели, а потом пойдёт прямо по "х". Маршрут для нашего примера: 8->5->1->0. Очень важно заметить, что за один шаг по "у" координате монстр пройдёт пол шага по "х", при условии, что ему нужно двигаться по х.
Пример: монстр (путь это будет гном) хочет попасть из Клетки(7) в Клетку(0)
Расчитаем координаты клеток и найдём разницу по модулю оных в обоих случаях.
Код
Маршрут №1: Клетка(7) в Клетку (0)
х1 = (7 % 3) = 1 + 0.5 (нечётная строка) = 1.5.
у1 = (7 : 3) = 2.
х2 = (0 % 3) = 0 + 0.5 (нечётная строка) = 0.5.
у2 = (0 : 3) = 0.
дх = |х2-х1| = 1.
ду = |у2-у1| = 2.
Итак, по "х" расстояние до цели - 1 клетка, по "у" - две. Помните, я говорил, что за один шаг по "у" монстр пройдёт пол клетки по "х"? В итоге события происходят так:
Код
дх = 1
ду = 2
шаги = 0
1) Монстр делает шаг из (7) в (4)
ду - 1 = 1
дх - 0.5 = 0.5
шаги = 1
2) Монстр делает шаг из (4) в (0)
ду - 1 = 0
дх - 0.5 = 0
шаги = 2
Как видите, по "х"-у отдельно даже не пришлось идти, а расстояние до цели - два шага. Поэтому нарисовывается следующий алгоритм:
Код
дх:=дх-(ду:2)
ЕСЛИ дх < 0 То дх = 0
Шаги = дх + ду
Первая строчка понятна, шаг по "у" даёт нам пол клетки по "х". А что за условие? Дело в том, что пол клетки по "х" нужно не всегда. Посмотрите на клетки (7) и (1). "х"-координаты у них одинаковые, поэтому то, что мы движемся по "у" никак не влияет на финальное кол-во шагов. Математически проще подсчитать эффект, а потом проверить, не ушли ли мы в глубокий нуль. Если ушли, то исправляемся, а если нет, то монстр прошёл несколько клеток по вертикали и будет ещё несколько клеток двигаться по горизонтали.
Реализация алгоритма на ЕРМ с оптимизацией.Код
!?FU@CalculateHexDistance@;
; PARAMS (HexSource, HexDest, ?Res)
!!VRy1:Sx1:17*2;
!!VRy5:Sy1:2&1X1;
!!VRy2:Sx1%17*2+y5;
!!VRy3:Sx2:17*2;
!!VRy5:Sy3:2&1X1;
!!VRy4:Sx2%17*2+y5;
!!VRy6:Sy4-y2;
!!VRy6&y6<0:*-1;
!!VRy7:Sy3-y1:2;
!!VRy7&y7<0:*-1;
!!VRy8:Sy7:2;
!!VRy6:-y8;
!!VRy6&y6<0:S0;
!!VRx3:Sy6+y7:2;