Пример реализации
Следующий пример кода соединяет различные суждения в функцию стоимости грани для реализации теста:
DWORD SearchGraph::EdgeCost(
// Вычисление функции стоимости
CellRef &crDst, // Выход: ячейка адресат для грани
CellRef crSrc, // Вход: ячейка источник
EdgeDir ed // Вход: направление грани
)
{
// Переход по индексу на ячейку адресат
crDst = crSrc + crWalkEdgeDelta[ed]; // 2d индекс + опреатор
// Модификатор для определения края карты, возвращает бесконечность
// если адресат вне графа
if (IsCellRefValid(crDst)) return infinity;
CellAttr &caSrc = AttributesFor(crSrc);
CellAttr &caDst = AttributesFor(crDst);
DWORD dwCost;
// Применение модификатора дороги
if ((caSrc.cRoadType != noroad) && (caDst.cRoadType != noroad)) {
dwCost = dwRoadEdgeCost[ed&1][caSrc.cRoadType];
} else {
// иначе применение модификатора наклона
if (abs(caSrc.wHeight-caDst.wHeight)
> dwMaxHeightDiff[ed&1])
return infinity;
// иначе вычисление просто стоимости местности
dwCost = dwTerrainHalfEdgeCost[ed&1][caSrc.cTerrainType] +
dwTerrainHalfEdgeCost[ed&1][caDst.cTerrainType];
}
// Применение модификатора врага
if (!caDst.bHaveVisCalc) { // ленивое определение видимости
// Использование DDA трассировки алг.
caDst.bVisible = IsObserved(crDst);
caDst.bHaveVisCalc = true;
}
if (caDst.bVisible) {
dwCost += dwVisibilityCost;
if (dwCost > MAXCOST) dwCost = MAXCOST;
}
// Все
return dwCost;
}
Правила if else данного кода, исполняемые при вызове EdgeCost(), очень короткие. Реальное замедление быстродействия происходит при вызове IsObserved(), то есть определение, может ли враг обнаружить нас в ячейке адресата или нет. Таким образом, если вражеское детектирование не нужно, мы можем сохранить много времени при вычислении.
6