mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-29 06:55:41 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2834974f27 |
@@ -115,6 +115,33 @@ struct PreCachedAPDs {
|
||||
return battalionTypes[battTypeId];
|
||||
}
|
||||
};
|
||||
|
||||
// Cached game data structure to avoid redundant calculations
|
||||
struct CachedGameData {
|
||||
std::vector<const Unit *> occupants;
|
||||
std::vector<const Unit *> attackerUnits;
|
||||
std::vector<const Unit *> defenderUnits;
|
||||
|
||||
CachedGameData(const GameState *gameState) {
|
||||
const auto rc = gameState->hex_map()->row_count();
|
||||
const auto cc = gameState->hex_map()->column_count();
|
||||
|
||||
occupants = Occupants(*gameState->units(), rc, cc);
|
||||
|
||||
for (const Unit *unit : *gameState->units()) {
|
||||
const auto *pi = PlayerInfoForPid(gameState, unit->player_id());
|
||||
if (pi == nullptr) continue;
|
||||
|
||||
if (unit->status() == net::eagle0::shardok::storage::fb::UnitStatus_NORMAL_UNIT) {
|
||||
if (pi->is_defender()) {
|
||||
defenderUnits.push_back(unit);
|
||||
} else {
|
||||
attackerUnits.push_back(unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#define MULTITHREAD true
|
||||
|
||||
constexpr double UNITS_BASE_MULTIPLIER = 0.05;
|
||||
@@ -271,16 +298,12 @@ auto AttackerUnitsScore(
|
||||
// Pre-cache all ActionPointDistances for all battalion types once
|
||||
PreCachedAPDs cachedAPDs(gameState, settings, apdCache, mapId);
|
||||
|
||||
std::vector<const Unit *> attackerUnits{};
|
||||
std::vector<const Unit *> defenderUnits{};
|
||||
// Create cached game data once to avoid redundant calculations
|
||||
CachedGameData cached(gameState);
|
||||
|
||||
double attackerUnitsValue = 0;
|
||||
double defenderUnitsValue = 0;
|
||||
|
||||
auto occupants = Occupants(
|
||||
*gameState->units(),
|
||||
gameState->hex_map()->row_count(),
|
||||
gameState->hex_map()->column_count());
|
||||
ActionPoints braveWaterCost = settings.Backing().brave_water_action_point_cost();
|
||||
|
||||
for (const Unit *unit : *gameState->units()) {
|
||||
@@ -289,11 +312,7 @@ auto AttackerUnitsScore(
|
||||
|
||||
switch (unit->status()) {
|
||||
case net::eagle0::shardok::storage::fb::UnitStatus_NORMAL_UNIT: {
|
||||
if (pi->is_defender()) {
|
||||
defenderUnits.push_back(unit);
|
||||
} else {
|
||||
attackerUnits.push_back(unit);
|
||||
}
|
||||
// Units already cached in CachedGameData
|
||||
break;
|
||||
}
|
||||
case net::eagle0::shardok::storage::fb::UnitStatus_CAPTURED_UNIT: {
|
||||
@@ -323,11 +342,11 @@ auto AttackerUnitsScore(
|
||||
double defenderAdvantage = 1.0 + static_cast<double>(gameState->current_round()) / 31.0;
|
||||
|
||||
// Can we cache this somehow, it won't usually change within your turn
|
||||
auto attackLocationsForAttacker = alCache->CachedLocations(defenderUnits, isLateGame);
|
||||
auto attackLocationsForAttacker = alCache->CachedLocations(cached.defenderUnits, isLateGame);
|
||||
const auto &locationsCausingDanger = attackLocationsForAttacker.AllLocations();
|
||||
|
||||
// Process attacker units using cached ActionPointDistances
|
||||
for (const Unit *unit : attackerUnits) {
|
||||
for (const Unit *unit : cached.attackerUnits) {
|
||||
const int battTypeId = unit->battalion().type();
|
||||
|
||||
const auto &priorityList = std::ranges::find_if(
|
||||
@@ -343,7 +362,7 @@ auto AttackerUnitsScore(
|
||||
: AttackerMultiplierForTargetDistance(
|
||||
unit,
|
||||
priorityList->priorityOrder,
|
||||
occupants,
|
||||
cached.occupants,
|
||||
gameState->hex_map(),
|
||||
cachedAPDs.GetBattalionType(battTypeId),
|
||||
cachedAPDs.GetRegular(battTypeId),
|
||||
@@ -353,10 +372,10 @@ auto AttackerUnitsScore(
|
||||
auto uv = UnitValue(
|
||||
unit,
|
||||
true,
|
||||
attackerUnits,
|
||||
cached.attackerUnits,
|
||||
attackerWantsCastles,
|
||||
/* includeCastleBonus=*/true,
|
||||
defenderUnits,
|
||||
cached.defenderUnits,
|
||||
gameState->hex_map(),
|
||||
roundsRemaining,
|
||||
attackLocationsForAttacker,
|
||||
@@ -367,20 +386,20 @@ auto AttackerUnitsScore(
|
||||
attackerUnitsValue += distanceMultiplier * uv;
|
||||
}
|
||||
|
||||
auto attackLocationsForDefender = alCache->CachedLocations(attackerUnits, isLateGame);
|
||||
auto attackLocationsForDefender = alCache->CachedLocations(cached.attackerUnits, isLateGame);
|
||||
const auto &locationsCausingDangerForAttacker = attackLocationsForDefender.AllLocations();
|
||||
|
||||
for (const Unit *unit : defenderUnits) {
|
||||
for (const Unit *unit : cached.defenderUnits) {
|
||||
auto defenderUnitId = unit->unit_id();
|
||||
const int battTypeId = unit->battalion().type();
|
||||
|
||||
auto dv = UnitValue(
|
||||
unit,
|
||||
false,
|
||||
attackerUnits,
|
||||
cached.attackerUnits,
|
||||
attackerWantsCastles,
|
||||
/* includeCastleBonus=*/!defenderShouldScatter,
|
||||
defenderUnits,
|
||||
cached.defenderUnits,
|
||||
gameState->hex_map(),
|
||||
roundsRemaining,
|
||||
attackLocationsForDefender,
|
||||
@@ -397,7 +416,7 @@ auto AttackerUnitsScore(
|
||||
myLocationSet.Add(unit->location());
|
||||
|
||||
DIST_T closestDistanceToEnemy = 999;
|
||||
for (const auto &attackerUnit : attackerUnits) {
|
||||
for (const auto &attackerUnit : cached.attackerUnits) {
|
||||
if (const DIST_T thisDistance = EffectiveDistance(
|
||||
attackerUnit,
|
||||
gameState->hex_map(),
|
||||
@@ -419,8 +438,8 @@ auto AttackerUnitsScore(
|
||||
distanceMultiplier = -1;
|
||||
} else {
|
||||
DIST_T closestDistanceToFriendly = 1;
|
||||
if (defenderUnits.size() > 1) {
|
||||
for (const auto &defenderUnit : defenderUnits) {
|
||||
if (cached.defenderUnits.size() > 1) {
|
||||
for (const auto &defenderUnit : cached.defenderUnits) {
|
||||
if (defenderUnit->unit_id() != defenderUnitId) {
|
||||
if (const DIST_T thisDistance = EffectiveDistance(
|
||||
defenderUnit,
|
||||
|
||||
Reference in New Issue
Block a user