|
@@ -55,42 +55,11 @@ BattleHex BattleHexArray::getClosestTile(BattleSide side, BattleHex initialPos)
|
|
|
|
|
|
auto bestTile = std::min_element(closestTiles.begin(), closestTiles.end(), compareHorizontal);
|
|
|
return (bestTile != closestTiles.end()) ? *bestTile : BattleHex();
|
|
|
-
|
|
|
- //BattleHex initialHex = BattleHex(initialPos);
|
|
|
- //auto compareDistance = [initialHex](const BattleHex left, const BattleHex right) -> bool
|
|
|
- //{
|
|
|
- // return initialHex.getDistance(initialHex, left) < initialHex.getDistance(initialHex, right);
|
|
|
- //};
|
|
|
- //BattleHexArray sortedTiles(*this);
|
|
|
- //boost::sort(sortedTiles, compareDistance); //closest tiles at front
|
|
|
- //int closestDistance = initialHex.getDistance(initialPos, sortedTiles.front()); //sometimes closest tiles can be many hexes away
|
|
|
- //auto notClosest = [closestDistance, initialPos](const BattleHex here) -> bool
|
|
|
- //{
|
|
|
- // return closestDistance < here.getDistance(initialPos, here);
|
|
|
- //};
|
|
|
- //vstd::erase_if(sortedTiles, notClosest); //only closest tiles are interesting
|
|
|
- //auto compareHorizontal = [side, initialPos](const BattleHex left, const BattleHex right) -> bool
|
|
|
- //{
|
|
|
- // if(left.getX() != right.getX())
|
|
|
- // {
|
|
|
- // if(side == BattleSide::ATTACKER)
|
|
|
- // return left.getX() > right.getX(); //find furthest right
|
|
|
- // else
|
|
|
- // return left.getX() < right.getX(); //find furthest left
|
|
|
- // }
|
|
|
- // else
|
|
|
- // {
|
|
|
- // //Prefer tiles in the same row.
|
|
|
- // return std::abs(left.getY() - initialPos.getY()) < std::abs(right.getY() - initialPos.getY());
|
|
|
- // }
|
|
|
- //};
|
|
|
- //boost::sort(sortedTiles, compareHorizontal);
|
|
|
- //return sortedTiles.front();
|
|
|
}
|
|
|
|
|
|
-BattleHexArray::NeighbouringTilesCache BattleHexArray::calculateNeighbouringTiles()
|
|
|
+BattleHexArray::ArrayOfBattleHexArrays BattleHexArray::calculateNeighbouringTiles()
|
|
|
{
|
|
|
- BattleHexArray::NeighbouringTilesCache ret;
|
|
|
+ BattleHexArray::ArrayOfBattleHexArrays ret;
|
|
|
|
|
|
for(si16 hex = 0; hex < GameConstants::BFIELD_SIZE; hex++)
|
|
|
{
|
|
@@ -110,50 +79,75 @@ BattleHexArray BattleHexArray::generateNeighbouringTiles(BattleHex hex)
|
|
|
BattleHexArray ret;
|
|
|
for(auto dir : BattleHex::hexagonalDirections())
|
|
|
ret.checkAndPush(hex.cloneInDirection(dir, false));
|
|
|
-
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-BattleHexArray BattleHexArray::generateAttackerClosestTilesCache()
|
|
|
+const BattleHexArray & BattleHexArray::getNeighbouringTilesDblWide(BattleHex pos, BattleSide side)
|
|
|
{
|
|
|
- assert(!neighbouringTilesCache.empty());
|
|
|
+ static std::array<ArrayOfBattleHexArrays, 2> ret; // 2 -> only two valid sides: ATTACKER and DEFENDER
|
|
|
+ size_t sideIdx = static_cast<size_t>(side);
|
|
|
+ static bool initialized[2] = { false, false };
|
|
|
|
|
|
- BattleHexArray ret;
|
|
|
+ if(!initialized[sideIdx])
|
|
|
+ {
|
|
|
+ // first run, need to initialize
|
|
|
|
|
|
- ret.resize(GameConstants::BFIELD_SIZE);
|
|
|
+ for(BattleHex hex = 0; hex < GameConstants::BFIELD_SIZE; hex.hex++)
|
|
|
+ {
|
|
|
+ BattleHexArray hexes;
|
|
|
|
|
|
- for(si16 hex = 0; hex < GameConstants::BFIELD_SIZE; hex++)
|
|
|
- {
|
|
|
- ret.set(hex, neighbouringTilesCache[hex].getClosestTile(BattleSide::ATTACKER, hex));
|
|
|
+ if(side == BattleSide::ATTACKER)
|
|
|
+ {
|
|
|
+ const BattleHex otherHex = hex - 1;
|
|
|
+
|
|
|
+ for(auto dir = static_cast<BattleHex::EDir>(0); dir <= static_cast<BattleHex::EDir>(4); dir = static_cast<BattleHex::EDir>(dir + 1))
|
|
|
+ hexes.checkAndPush(hex.cloneInDirection(dir, false));
|
|
|
+
|
|
|
+ hexes.checkAndPush(otherHex.cloneInDirection(BattleHex::EDir::BOTTOM_LEFT, false));
|
|
|
+ hexes.checkAndPush(otherHex.cloneInDirection(BattleHex::EDir::LEFT, false));
|
|
|
+ hexes.checkAndPush(otherHex.cloneInDirection(BattleHex::EDir::TOP_LEFT, false));
|
|
|
+ }
|
|
|
+ else if(side == BattleSide::DEFENDER)
|
|
|
+ {
|
|
|
+ const BattleHex otherHex = hex + 1;
|
|
|
+
|
|
|
+ hexes.checkAndPush(hex.cloneInDirection(BattleHex::EDir::TOP_LEFT, false));
|
|
|
+
|
|
|
+ for(auto dir = static_cast<BattleHex::EDir>(0); dir <= static_cast<BattleHex::EDir>(4); dir = static_cast<BattleHex::EDir>(dir + 1))
|
|
|
+ hexes.checkAndPush(otherHex.cloneInDirection(dir, false));
|
|
|
+
|
|
|
+ hexes.checkAndPush(hex.cloneInDirection(BattleHex::EDir::BOTTOM_LEFT, false));
|
|
|
+ hexes.checkAndPush(hex.cloneInDirection(BattleHex::EDir::LEFT, false));
|
|
|
+ }
|
|
|
+ ret[sideIdx][hex.hex] = std::move(hexes);
|
|
|
+ }
|
|
|
+ initialized[sideIdx] = true;
|
|
|
}
|
|
|
|
|
|
- return ret;
|
|
|
+ return ret[sideIdx][pos.hex];
|
|
|
}
|
|
|
|
|
|
-BattleHexArray BattleHexArray::generateDefenderClosestTilesCache()
|
|
|
+const BattleHexArray & BattleHexArray::getClosestTilesCache(BattleHex pos, BattleSide side)
|
|
|
{
|
|
|
assert(!neighbouringTilesCache.empty());
|
|
|
|
|
|
- BattleHexArray ret;
|
|
|
-
|
|
|
- ret.resize(GameConstants::BFIELD_SIZE);
|
|
|
+ static std::array<BattleHexArray, 2> ret;
|
|
|
+ static bool initialized = false;
|
|
|
+ size_t sideIdx = static_cast<size_t>(side);
|
|
|
|
|
|
- for(si16 hex = 0; hex < GameConstants::BFIELD_SIZE; hex++)
|
|
|
+ if(!initialized)
|
|
|
{
|
|
|
- ret.set(hex, neighbouringTilesCache[hex].getClosestTile(BattleSide::DEFENDER, hex));
|
|
|
- }
|
|
|
+ ret[sideIdx].resize(GameConstants::BFIELD_SIZE);
|
|
|
|
|
|
- return ret;
|
|
|
-}
|
|
|
+ for(si16 hex = 0; hex < GameConstants::BFIELD_SIZE; hex++)
|
|
|
+ {
|
|
|
+ ret[sideIdx].set(hex, neighbouringTilesCache[hex].getClosestTile(BattleSide::ATTACKER, hex));
|
|
|
+ }
|
|
|
+ initialized = true;
|
|
|
+ }
|
|
|
|
|
|
-BattleHex BattleHexArray::getClosestTileFromAllPossibleNeighbours(BattleSide side, BattleHex pos)
|
|
|
-{
|
|
|
- if(side == BattleSide::ATTACKER)
|
|
|
- return closestTilesCacheForAttacker[pos.hex];
|
|
|
- else if(side == BattleSide::DEFENDER)
|
|
|
- return closestTilesCacheForDefender[pos.hex];
|
|
|
- else
|
|
|
- assert(false); // we should never be here
|
|
|
+ return ret[sideIdx];
|
|
|
}
|
|
|
|
|
|
void BattleHexArray::merge(const BattleHexArray & other) noexcept
|
|
@@ -182,9 +176,6 @@ void BattleHexArray::clear() noexcept
|
|
|
internalStorage.clear();
|
|
|
}
|
|
|
|
|
|
-const BattleHexArray::NeighbouringTilesCache BattleHexArray::neighbouringTilesCache = calculateNeighbouringTiles();
|
|
|
-
|
|
|
-const BattleHexArray BattleHexArray::closestTilesCacheForAttacker = generateAttackerClosestTilesCache();
|
|
|
-const BattleHexArray BattleHexArray::closestTilesCacheForDefender = generateDefenderClosestTilesCache();
|
|
|
+const BattleHexArray::ArrayOfBattleHexArrays BattleHexArray::neighbouringTilesCache = calculateNeighbouringTiles();
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|