mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-28 21:55:42 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ab9332d21 | ||
|
|
c380d167ca |
@@ -91,15 +91,15 @@ auto AICommandEvaluator::PerformLookahead(
|
||||
const ScoreValue currentUtility,
|
||||
const AIStrategy& attackerStrategy,
|
||||
const CoordsSet& allCastleCoords,
|
||||
std::chrono::steady_clock::time_point deadline) const -> std::future<ScoreValue> {
|
||||
std::chrono::steady_clock::time_point deadline) const -> std::future<EvaluationResult> {
|
||||
// Check transposition table before expensive computation
|
||||
auto cachedScore =
|
||||
g_transpositionTable.probe(innerEngine->GetCurrentGameState(), remainingLookahead, pid);
|
||||
|
||||
if (cachedScore.has_value()) {
|
||||
// Return cached result immediately
|
||||
std::promise<ScoreValue> p;
|
||||
p.set_value(*cachedScore);
|
||||
std::promise<EvaluationResult> p;
|
||||
p.set_value(EvaluationResult{.score = *cachedScore, .completed = true});
|
||||
return p.get_future();
|
||||
}
|
||||
const auto nextUtility = currentUtility;
|
||||
@@ -111,8 +111,8 @@ auto AICommandEvaluator::PerformLookahead(
|
||||
// table
|
||||
g_transpositionTable.store(innerEngine->GetCurrentGameState(), 1, pid, nextUtility);
|
||||
|
||||
std::promise<ScoreValue> p;
|
||||
p.set_value(nextUtility);
|
||||
std::promise<EvaluationResult> p;
|
||||
p.set_value(EvaluationResult{.score = nextUtility, .completed = true});
|
||||
return p.get_future();
|
||||
}
|
||||
|
||||
@@ -137,16 +137,18 @@ auto AICommandEvaluator::PerformLookahead(
|
||||
innerEngine,
|
||||
pid,
|
||||
nextUtility,
|
||||
remainingLookahead]() mutable -> ScoreValue {
|
||||
const auto [index, type, lookaheadScore, immediateScore] =
|
||||
bestCommandFuture.get();
|
||||
remainingLookahead]() mutable -> EvaluationResult {
|
||||
const auto bestCommand = bestCommandFuture.get();
|
||||
if (!bestCommand.completed) {
|
||||
return EvaluationResult{.score = nextUtility, .completed = false};
|
||||
}
|
||||
|
||||
ScoreValue resultScore;
|
||||
if (auto& nextCommand =
|
||||
innerEngine->GetAvailableCommandsForAIPlayer(pid)->at(index);
|
||||
if (auto& nextCommand = innerEngine->GetAvailableCommandsForAIPlayer(pid)->at(
|
||||
bestCommand.index);
|
||||
nextCommand->GetCommandType() !=
|
||||
net::eagle0::shardok::common::END_TURN_COMMAND) {
|
||||
resultScore = immediateScore;
|
||||
resultScore = bestCommand.immediateScore;
|
||||
} else {
|
||||
resultScore = nextUtility;
|
||||
}
|
||||
@@ -158,7 +160,7 @@ auto AICommandEvaluator::PerformLookahead(
|
||||
pid,
|
||||
resultScore);
|
||||
|
||||
return resultScore;
|
||||
return EvaluationResult{.score = resultScore, .completed = true};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -166,8 +168,8 @@ auto AICommandEvaluator::PerformLookahead(
|
||||
g_transpositionTable
|
||||
.store(innerEngine->GetCurrentGameState(), remainingLookahead, pid, nextUtility);
|
||||
|
||||
std::promise<ScoreValue> p;
|
||||
p.set_value(nextUtility);
|
||||
std::promise<EvaluationResult> p;
|
||||
p.set_value(EvaluationResult{.score = nextUtility, .completed = true});
|
||||
return p.get_future();
|
||||
}
|
||||
|
||||
@@ -186,10 +188,10 @@ auto AICommandEvaluator::EvaluateWithRandomness(
|
||||
|
||||
// Check if we've exceeded the deadline
|
||||
if (std::chrono::steady_clock::now() > deadline) {
|
||||
// Return with a default score and an empty future that resolves immediately
|
||||
std::promise<ScoreValue> p;
|
||||
p.set_value(0.0); // Default timeout score
|
||||
std::promise<EvaluationResult> p;
|
||||
p.set_value(EvaluationResult{.score = 0.0, .completed = false});
|
||||
returnValue.immediateScore = 0.0;
|
||||
returnValue.completed = false;
|
||||
returnValue.lookaheadScore = p.get_future();
|
||||
return returnValue;
|
||||
}
|
||||
@@ -204,11 +206,12 @@ auto AICommandEvaluator::EvaluateWithRandomness(
|
||||
allCastleCoords);
|
||||
|
||||
returnValue.immediateScore = innerUtility;
|
||||
returnValue.completed = true;
|
||||
|
||||
if (remainingLookahead <= 0) {
|
||||
std::promise<ScoreValue> p;
|
||||
std::promise<EvaluationResult> p;
|
||||
returnValue.lookaheadScore = p.get_future();
|
||||
p.set_value(innerUtility);
|
||||
p.set_value(EvaluationResult{.score = innerUtility, .completed = true});
|
||||
} else {
|
||||
auto lookaheadLambda = [this,
|
||||
pid,
|
||||
@@ -219,7 +222,7 @@ auto AICommandEvaluator::EvaluateWithRandomness(
|
||||
attackerStrategy,
|
||||
innerUtility,
|
||||
&allCastleCoords,
|
||||
deadline]() -> ScoreValue {
|
||||
deadline]() -> EvaluationResult {
|
||||
auto lookaheadFuture = PerformLookahead(
|
||||
pid,
|
||||
isDefender,
|
||||
@@ -237,7 +240,7 @@ auto AICommandEvaluator::EvaluateWithRandomness(
|
||||
auto launchPolicy = remainingLookahead == 1 ? std::launch::async : std::launch::deferred;
|
||||
returnValue.lookaheadScore = std::async(launchPolicy, lookaheadLambda);
|
||||
#else
|
||||
std::promise<ScoreValue> p;
|
||||
std::promise<EvaluationResult> p;
|
||||
returnValue.lookaheadScore = p.get_future();
|
||||
auto lambdaResult = lookaheadLambda();
|
||||
p.set_value(lambdaResult);
|
||||
@@ -322,7 +325,8 @@ auto AICommandEvaluator::FindBestCommand(
|
||||
size_t index;
|
||||
CommandType type;
|
||||
ScoreValue immediateScore;
|
||||
std::vector<std::future<ScoreValue>> lookaheadFutures;
|
||||
bool immediateCompleted = true;
|
||||
std::vector<std::future<EvaluationResult>> lookaheadFutures;
|
||||
};
|
||||
|
||||
std::vector<CommandEvaluation> commandEvaluations(commandCount);
|
||||
@@ -336,12 +340,12 @@ auto AICommandEvaluator::FindBestCommand(
|
||||
commandEvaluations[index].type = guessedCommandType;
|
||||
|
||||
if (guessedCommandType == net::eagle0::shardok::common::END_TURN_COMMAND) {
|
||||
std::promise<ScoreValue> p;
|
||||
std::promise<EvaluationResult> p;
|
||||
commandEvaluations[index].lookaheadFutures.push_back(p.get_future());
|
||||
p.set_value(currentUtility);
|
||||
p.set_value(EvaluationResult{.score = currentUtility, .completed = true});
|
||||
commandEvaluations[index].immediateScore = currentUtility;
|
||||
} else if (IsDeterministic(guessedCommandType)) {
|
||||
auto [immediateScore, lookaheadScore] = EvaluateWithRandomness(
|
||||
auto evaluation = EvaluateWithRandomness(
|
||||
pid,
|
||||
isDefender,
|
||||
originalIndex,
|
||||
@@ -353,14 +357,16 @@ auto AICommandEvaluator::FindBestCommand(
|
||||
allCastleCoords,
|
||||
deadline);
|
||||
|
||||
commandEvaluations[index].immediateScore = immediateScore;
|
||||
commandEvaluations[index].lookaheadFutures.push_back(std::move(lookaheadScore));
|
||||
commandEvaluations[index].immediateScore = evaluation.immediateScore;
|
||||
commandEvaluations[index].immediateCompleted = evaluation.completed;
|
||||
commandEvaluations[index].lookaheadFutures.push_back(
|
||||
std::move(evaluation.lookaheadScore));
|
||||
} else if (guessedDescriptor->HasOdds()) {
|
||||
const auto successChancePercentile = guessedDescriptor->GetOddsPercentile();
|
||||
const double successChance = static_cast<double>(successChancePercentile) / 100.0;
|
||||
|
||||
// Success attempt uses 1.0 - (successChance / 2) as the roll
|
||||
auto [successImmediateScore, successLookaheadScore] = EvaluateWithRandomness(
|
||||
auto successEvaluation = EvaluateWithRandomness(
|
||||
pid,
|
||||
isDefender,
|
||||
originalIndex,
|
||||
@@ -374,7 +380,7 @@ auto AICommandEvaluator::FindBestCommand(
|
||||
deadline);
|
||||
|
||||
// Failure attempt uses the average of (1 - successChance) and 0 as the roll
|
||||
auto [failureImmediateScore, failureLookaheadScore] = EvaluateWithRandomness(
|
||||
auto failureEvaluation = EvaluateWithRandomness(
|
||||
pid,
|
||||
isDefender,
|
||||
originalIndex,
|
||||
@@ -387,15 +393,26 @@ auto AICommandEvaluator::FindBestCommand(
|
||||
allCastleCoords,
|
||||
deadline);
|
||||
|
||||
commandEvaluations[index].immediateScore =
|
||||
std::lerp(failureImmediateScore, successImmediateScore, successChance);
|
||||
commandEvaluations[index].immediateCompleted =
|
||||
failureEvaluation.completed && successEvaluation.completed;
|
||||
commandEvaluations[index].immediateScore = std::lerp(
|
||||
failureEvaluation.immediateScore,
|
||||
successEvaluation.immediateScore,
|
||||
successChance);
|
||||
|
||||
auto successSF = successLookaheadScore.share();
|
||||
auto failureSF = failureLookaheadScore.share();
|
||||
auto successSF = successEvaluation.lookaheadScore.share();
|
||||
auto failureSF = failureEvaluation.lookaheadScore.share();
|
||||
commandEvaluations[index].lookaheadFutures.push_back(std::async(
|
||||
std::launch::deferred,
|
||||
[successSF, failureSF, successChance]() -> double {
|
||||
return std::lerp(failureSF.get(), successSF.get(), successChance);
|
||||
[successSF, failureSF, successChance]() -> EvaluationResult {
|
||||
const auto failure = failureSF.get();
|
||||
const auto success = successSF.get();
|
||||
if (!failure.completed || !success.completed) {
|
||||
return EvaluationResult{.score = 0.0, .completed = false};
|
||||
}
|
||||
return EvaluationResult{
|
||||
.score = std::lerp(failure.score, success.score, successChance),
|
||||
.completed = true};
|
||||
}));
|
||||
} else {
|
||||
ScoreValue sum = 0.0;
|
||||
@@ -404,7 +421,7 @@ auto AICommandEvaluator::FindBestCommand(
|
||||
// In each iteration, use a double from [0, 1] as the random roll
|
||||
auto sequence =
|
||||
std::vector{RandomnessSampleForRepeat(repeatIteration, sampleCount)};
|
||||
auto [immediateScore, lookaheadScore] = EvaluateWithRandomness(
|
||||
auto evaluation = EvaluateWithRandomness(
|
||||
pid,
|
||||
isDefender,
|
||||
originalIndex,
|
||||
@@ -416,8 +433,10 @@ auto AICommandEvaluator::FindBestCommand(
|
||||
allCastleCoords,
|
||||
deadline);
|
||||
|
||||
sum += immediateScore;
|
||||
commandEvaluations[index].lookaheadFutures.push_back(std::move(lookaheadScore));
|
||||
if (!evaluation.completed) { commandEvaluations[index].immediateCompleted = false; }
|
||||
sum += evaluation.immediateScore;
|
||||
commandEvaluations[index].lookaheadFutures.push_back(
|
||||
std::move(evaluation.lookaheadScore));
|
||||
}
|
||||
commandEvaluations[index].immediateScore = sum / sampleCount;
|
||||
}
|
||||
@@ -433,19 +452,33 @@ auto AICommandEvaluator::FindBestCommand(
|
||||
// Wait for all futures and compute final scores
|
||||
for (auto& eval : evals) {
|
||||
ScoreValue totalLookaheadScore = 0.0;
|
||||
bool completed = eval.immediateCompleted;
|
||||
for (auto& future : eval.lookaheadFutures) {
|
||||
totalLookaheadScore += future.get();
|
||||
const auto lookahead = future.get();
|
||||
if (!lookahead.completed) { completed = false; }
|
||||
totalLookaheadScore += lookahead.score;
|
||||
}
|
||||
ScoreValue avgLookaheadScore =
|
||||
eval.lookaheadFutures.empty()
|
||||
? eval.immediateScore
|
||||
: totalLookaheadScore / eval.lookaheadFutures.size();
|
||||
|
||||
if (!completed) { continue; }
|
||||
|
||||
allResults.push_back(IndexAndScore{
|
||||
.index = eval.index,
|
||||
.type = eval.type,
|
||||
.lookaheadScore = avgLookaheadScore,
|
||||
.immediateScore = eval.immediateScore});
|
||||
.immediateScore = eval.immediateScore,
|
||||
.completed = true});
|
||||
}
|
||||
if (allResults.empty()) {
|
||||
return IndexAndScore{
|
||||
.index = 0,
|
||||
.type = net::eagle0::shardok::common::UNKNOWN_COMMAND,
|
||||
.lookaheadScore = 0.0,
|
||||
.immediateScore = 0.0,
|
||||
.completed = false};
|
||||
}
|
||||
// Find the best command using the existing sorter
|
||||
auto bestIt = std::ranges::max_element(allResults, CommandSorter);
|
||||
@@ -463,12 +496,12 @@ auto AICommandEvaluator::EvaluateCommand(
|
||||
const ScoreValue currentUtility,
|
||||
const CoordsSet& allCastleCoords,
|
||||
const size_t commandIndex,
|
||||
std::chrono::steady_clock::time_point deadline) const -> std::future<ScoreValue> {
|
||||
std::chrono::steady_clock::time_point deadline) const -> std::future<EvaluationResult> {
|
||||
const CommandListSPtr guessedDescriptors = guessedEngine.GetAvailableCommandsForAIPlayer(pid);
|
||||
|
||||
if (commandIndex >= guessedDescriptors->size()) {
|
||||
std::promise<ScoreValue> p;
|
||||
p.set_value(currentUtility);
|
||||
std::promise<EvaluationResult> p;
|
||||
p.set_value(EvaluationResult{.score = currentUtility, .completed = true});
|
||||
return p.get_future();
|
||||
}
|
||||
|
||||
@@ -476,11 +509,11 @@ auto AICommandEvaluator::EvaluateCommand(
|
||||
|
||||
if (const auto guessedCommandType = guessedDescriptor->GetCommandType();
|
||||
guessedCommandType == net::eagle0::shardok::common::END_TURN_COMMAND) {
|
||||
std::promise<ScoreValue> p;
|
||||
p.set_value(currentUtility);
|
||||
std::promise<EvaluationResult> p;
|
||||
p.set_value(EvaluationResult{.score = currentUtility, .completed = true});
|
||||
return p.get_future();
|
||||
} else if (IsDeterministic(guessedCommandType)) {
|
||||
auto [immediateScore, lookaheadScore] = EvaluateWithRandomness(
|
||||
auto evaluation = EvaluateWithRandomness(
|
||||
pid,
|
||||
isDefender,
|
||||
commandIndex,
|
||||
@@ -491,13 +524,13 @@ auto AICommandEvaluator::EvaluateCommand(
|
||||
attackerStrategy,
|
||||
allCastleCoords,
|
||||
deadline);
|
||||
return std::move(lookaheadScore);
|
||||
return std::move(evaluation.lookaheadScore);
|
||||
} else if (guessedDescriptor->HasOdds()) {
|
||||
const auto successChancePercentile = guessedDescriptor->GetOddsPercentile();
|
||||
const double successChance = static_cast<double>(successChancePercentile) / 100.0;
|
||||
|
||||
// Success attempt
|
||||
auto [successImmediateScore, successLookaheadScore] = EvaluateWithRandomness(
|
||||
auto successEvaluation = EvaluateWithRandomness(
|
||||
pid,
|
||||
isDefender,
|
||||
commandIndex,
|
||||
@@ -510,7 +543,7 @@ auto AICommandEvaluator::EvaluateCommand(
|
||||
deadline);
|
||||
|
||||
// Failure attempt
|
||||
auto [failureImmediateScore, failureLookaheadScore] = EvaluateWithRandomness(
|
||||
auto failureEvaluation = EvaluateWithRandomness(
|
||||
pid,
|
||||
isDefender,
|
||||
commandIndex,
|
||||
@@ -523,20 +556,29 @@ auto AICommandEvaluator::EvaluateCommand(
|
||||
deadline);
|
||||
|
||||
// Return weighted average of success and failure
|
||||
auto successSF = successLookaheadScore.share();
|
||||
auto failureSF = failureLookaheadScore.share();
|
||||
return std::async(std::launch::deferred, [successSF, failureSF, successChance]() -> double {
|
||||
return std::lerp(failureSF.get(), successSF.get(), successChance);
|
||||
});
|
||||
auto successSF = successEvaluation.lookaheadScore.share();
|
||||
auto failureSF = failureEvaluation.lookaheadScore.share();
|
||||
return std::async(
|
||||
std::launch::deferred,
|
||||
[successSF, failureSF, successChance]() -> EvaluationResult {
|
||||
const auto failure = failureSF.get();
|
||||
const auto success = successSF.get();
|
||||
if (!failure.completed || !success.completed) {
|
||||
return EvaluationResult{.score = 0.0, .completed = false};
|
||||
}
|
||||
return EvaluationResult{
|
||||
.score = std::lerp(failure.score, success.score, successChance),
|
||||
.completed = true};
|
||||
});
|
||||
} else {
|
||||
// For non-deterministic commands without odds, use multiple attempts
|
||||
std::vector<std::future<ScoreValue>> lookaheadFutures;
|
||||
std::vector<std::future<EvaluationResult>> lookaheadFutures;
|
||||
const int sampleCount = std::max(1, maxRepeatCount);
|
||||
lookaheadFutures.reserve(sampleCount);
|
||||
|
||||
for (int repeatIteration = 0; repeatIteration < sampleCount; repeatIteration++) {
|
||||
auto sequence = std::vector{RandomnessSampleForRepeat(repeatIteration, sampleCount)};
|
||||
auto [immediateScore, lookaheadScore] = EvaluateWithRandomness(
|
||||
auto evaluation = EvaluateWithRandomness(
|
||||
pid,
|
||||
isDefender,
|
||||
commandIndex,
|
||||
@@ -548,16 +590,25 @@ auto AICommandEvaluator::EvaluateCommand(
|
||||
allCastleCoords,
|
||||
deadline);
|
||||
|
||||
lookaheadFutures.push_back(std::move(lookaheadScore));
|
||||
lookaheadFutures.push_back(std::move(evaluation.lookaheadScore));
|
||||
}
|
||||
|
||||
// Return a future that computes the average when needed
|
||||
return std::async(
|
||||
std::launch::deferred,
|
||||
[lookaheadFutures = std::move(lookaheadFutures), sampleCount]() mutable -> double {
|
||||
[lookaheadFutures = std::move(lookaheadFutures),
|
||||
sampleCount]() mutable -> EvaluationResult {
|
||||
ScoreValue total = 0.0;
|
||||
for (auto& future : lookaheadFutures) { total += future.get(); }
|
||||
return total / sampleCount;
|
||||
bool completed = true;
|
||||
for (auto& future : lookaheadFutures) {
|
||||
const auto result = future.get();
|
||||
if (!result.completed) { completed = false; }
|
||||
total += result.score;
|
||||
}
|
||||
if (!completed) { return EvaluationResult{.score = 0.0, .completed = false}; }
|
||||
return EvaluationResult{
|
||||
.score = total / static_cast<ScoreValue>(sampleCount),
|
||||
.completed = true};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,11 @@ public:
|
||||
BattalionTypeGetter battalionTypeGetter); // Pass by value
|
||||
|
||||
/// Evaluates the score for a particular command index with lookahead.
|
||||
struct EvaluationResult {
|
||||
ScoreValue score;
|
||||
bool completed;
|
||||
};
|
||||
|
||||
[[nodiscard]] auto EvaluateCommand(
|
||||
PlayerId pid,
|
||||
bool isDefender,
|
||||
@@ -48,7 +53,7 @@ public:
|
||||
ScoreValue currentUtility,
|
||||
const CoordsSet& allCastleCoords,
|
||||
size_t commandIndex,
|
||||
std::chrono::steady_clock::time_point deadline) const -> std::future<ScoreValue>;
|
||||
std::chrono::steady_clock::time_point deadline) const -> std::future<EvaluationResult>;
|
||||
|
||||
/// Find the best command among all available commands at the given depth.
|
||||
struct IndexAndScore {
|
||||
@@ -56,6 +61,7 @@ public:
|
||||
CommandType type;
|
||||
ScoreValue lookaheadScore;
|
||||
ScoreValue immediateScore;
|
||||
bool completed;
|
||||
};
|
||||
|
||||
[[nodiscard]] auto FindBestCommand(
|
||||
@@ -76,7 +82,8 @@ private:
|
||||
|
||||
struct ImmediateAndLookaheadScore {
|
||||
ScoreValue immediateScore;
|
||||
std::future<ScoreValue> lookaheadScore;
|
||||
bool completed;
|
||||
std::future<EvaluationResult> lookaheadScore;
|
||||
};
|
||||
|
||||
/// Recursive lookahead calculator
|
||||
@@ -89,7 +96,7 @@ private:
|
||||
ScoreValue currentUtility,
|
||||
const AIStrategy& attackerStrategy,
|
||||
const CoordsSet& allCastleCoords,
|
||||
std::chrono::steady_clock::time_point deadline) const -> std::future<ScoreValue>;
|
||||
std::chrono::steady_clock::time_point deadline) const -> std::future<EvaluationResult>;
|
||||
|
||||
/// Evaluate single command execution with randomness handling
|
||||
[[nodiscard]] auto EvaluateWithRandomness(
|
||||
|
||||
@@ -131,6 +131,10 @@ auto IterativeDeepeningAI::IterativeSearch(
|
||||
// Now wait for all futures and collect results
|
||||
for (auto& [cmdIndex, future] : futures) {
|
||||
auto cmdResult = future.get();
|
||||
if (!cmdResult.searchCompleted) {
|
||||
allEvaluated = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ensure scoresByDepth[cmdIndex] has enough space
|
||||
if (scoresByDepth[cmdIndex].size() <= currentDepth) {
|
||||
@@ -252,7 +256,9 @@ auto IterativeDeepeningAI::IterativeSearch(
|
||||
completionReason = EvaluationCompletionReason::RAN_OUT_OF_COMMANDS;
|
||||
}
|
||||
|
||||
// Select best result from highest depth achieved for each command
|
||||
// Select best result from the highest completed depth achieved for each command. Commands that
|
||||
// timed out at a depth are not recorded for that depth, so partial deeper work can help without
|
||||
// letting timeout fallback scores compete.
|
||||
result = SelectBestResult(scoresByDepth, highestDepthCompleted);
|
||||
result.minimumDepthCompleted = result.depthAchieved >= timeBudget.minDepthRequired;
|
||||
result.searchCompleted = result.minimumDepthCompleted;
|
||||
@@ -343,7 +349,9 @@ auto IterativeDeepeningAI::SearchCommandAtDepthWithEngine(
|
||||
// Deduct adjusted time from remaining budget
|
||||
timeBudget.remainingBudget -= adjustedElapsedMs;
|
||||
|
||||
result.bestScore = commandScore;
|
||||
result.bestScore = commandScore.score;
|
||||
result.searchCompleted = commandScore.completed;
|
||||
result.minimumDepthCompleted = commandScore.completed;
|
||||
|
||||
std::promise<SearchResult> p;
|
||||
p.set_value(result);
|
||||
@@ -356,7 +364,7 @@ auto IterativeDeepeningAI::GetCommandsSortedByPreviousDepth(
|
||||
const std::vector<size_t>& highestDepthCompleted,
|
||||
const std::vector<size_t>& filteredIndices) -> std::vector<size_t> {
|
||||
if (currentDepth == 1) {
|
||||
// For depth 1, return filtered indices in natural order
|
||||
// For depth 1, preserve the upstream command-factory priority order.
|
||||
return filteredIndices;
|
||||
}
|
||||
|
||||
|
||||
@@ -111,4 +111,4 @@ private:
|
||||
|
||||
} // namespace shardok
|
||||
|
||||
#endif // EAGLE0_ITERATIVEDEEPENINGAI_HPP
|
||||
#endif // EAGLE0_ITERATIVEDEEPENINGAI_HPP
|
||||
|
||||
+13
-13
@@ -1,32 +1,32 @@
|
||||
action_seq,shardok_game_id,attacker_factions,defender_factions,real_winner,sim_winner,winner_match,real_round,sim_round,real_attacker_troops,real_defender_troops,sim_attacker_troops,sim_defender_troops
|
||||
306,389ffb1901903118_1_b3e7d8ab,1,2,attacker,attacker,true,0,17,1454,0,1343,0
|
||||
306,389ffb1901903118_1_b3e7d8ab,1,2,attacker,attacker,true,0,19,1454,0,1388,0
|
||||
307,389ffb1901903118_2_bf499d3c,2,1,defender,defender,true,0,16,0,699,0,648
|
||||
399,389ffb1901903118_3_cd9141a,2,1,defender,defender,true,0,6,0,1310,0,1315
|
||||
631,389ffb1901903118_4_6e7b9b,1,2,defender,defender,true,0,5,0,3766,0,3654
|
||||
1326,389ffb1901903118_5_8a57255a,9,6,attacker,attacker,true,0,11,1715,0,1701,0
|
||||
2437,389ffb1901903118_7_5cf74e0,2,1,attacker,attacker,true,0,15,3146,0,3219,0
|
||||
2584,389ffb1901903118_8_41ce0ebd,1,2,defender,defender,true,0,30,0,2028,0,174
|
||||
2437,389ffb1901903118_7_5cf74e0,2,1,attacker,attacker,true,0,16,3146,0,3247,0
|
||||
2584,389ffb1901903118_8_41ce0ebd,1,2,defender,defender,true,0,31,0,2028,0,168
|
||||
2654,389ffb1901903118_9_eb43d421,2,1,defender,defender,true,0,28,0,335,0,467
|
||||
3536,389ffb1901903118_a_950de1c1,1,2,attacker,attacker,true,0,16,2172,0,1596,0
|
||||
3701,389ffb1901903118_b_5d1d76e0,8,2,defender,defender,true,0,30,0,2819,0,1344
|
||||
3536,389ffb1901903118_a_950de1c1,1,2,attacker,attacker,true,0,12,2172,0,2528,0
|
||||
3701,389ffb1901903118_b_5d1d76e0,8,2,defender,defender,true,0,30,0,2819,0,1348
|
||||
4298,389ffb1901903118_c_7bdb54dd,2,1,defender,defender,true,0,3,0,3514,0,1977
|
||||
4576,389ffb1901903118_d_689ee2fa,2,1,defender,defender,true,0,5,0,2028,0,1920
|
||||
6014,389ffb1901903118_e_89c90dc6,2,8,defender,defender,true,0,12,0,1942,0,1474
|
||||
4576,389ffb1901903118_d_689ee2fa,2,1,defender,defender,true,0,4,0,2028,0,1986
|
||||
6014,389ffb1901903118_e_89c90dc6,2,8,defender,defender,true,0,6,0,1942,0,2252
|
||||
6248,389ffb1901903118_f_3a9d9136,7,9,attacker,attacker,true,0,25,520,0,676,0
|
||||
6705,389ffb1901903118_11_e0611233,1,2,defender,defender,true,0,31,0,3316,0,702
|
||||
6705,389ffb1901903118_11_e0611233,1,2,defender,defender,true,0,31,0,3316,0,535
|
||||
7212,389ffb1901903118_12_84a36154,2,8,defender,defender,true,0,8,0,1253,0,1273
|
||||
8217,389ffb1901903118_13_2e98b1cf,8,2,attacker,attacker,true,0,29,920,0,1892,0
|
||||
8217,389ffb1901903118_13_2e98b1cf,8,2,attacker,attacker,true,0,22,920,0,2167,0
|
||||
8394,389ffb1901903118_14_b5570863,2,8,attacker,attacker,true,0,9,2449,0,3186,0
|
||||
9975,389ffb1901903118_16_3d6ec341,2,1,defender,defender,true,0,5,0,7420,0,7437
|
||||
9975,389ffb1901903118_16_3d6ec341,2,1,defender,defender,true,0,4,0,7420,0,7840
|
||||
10229,389ffb1901903118_17_3ba689e3,5,7,attacker,attacker,true,0,23,2135,0,1816,0
|
||||
10631,389ffb1901903118_18_9e463db3,1,2,attacker,attacker,true,0,1,4000,0,4000,0
|
||||
11011,389ffb1901903118_19_239725d3,2,1,defender,defender,true,0,4,0,3532,0,3593
|
||||
11011,389ffb1901903118_19_239725d3,2,1,defender,defender,true,0,5,0,3532,0,3658
|
||||
11012,389ffb1901903118_1a_16e1ebf,9,6,defender,defender,true,0,30,0,846,0,1347
|
||||
11297,389ffb1901903118_1c_529ba6e5,1,2,attacker,attacker,true,0,1,2400,0,2400,0
|
||||
11469,389ffb1901903118_1d_49993012,5,9,defender,defender,true,0,8,0,787,0,1489
|
||||
11470,389ffb1901903118_1e_fd8c60a8,7,5,attacker,attacker,true,0,12,3220,0,3400,0
|
||||
11470,389ffb1901903118_1e_fd8c60a8,7,5,attacker,attacker,true,0,17,3220,0,3425,0
|
||||
11565,389ffb1901903118_1f_53309484,5,7,defender,defender,true,0,31,190,3420,78,3600
|
||||
12136,389ffb1901903118_24_f0d61a5a,9,7,attacker,attacker,true,0,21,1829,0,1581,0
|
||||
12137,389ffb1901903118_25_a19c4d87,2,1,defender,defender,true,0,8,0,1894,0,1892
|
||||
12765,389ffb1901903118_27_c008989b,6,9,defender,defender,true,0,9,0,1773,0,1747
|
||||
12765,389ffb1901903118_27_c008989b,6,9,defender,defender,true,0,11,0,1773,0,1763
|
||||
13752,389ffb1901903118_28_b33e2868,2,1,defender,defender,true,0,7,0,943,0,932
|
||||
|
||||
|
+13
-13
@@ -12,34 +12,34 @@ than an exact replay assertion.
|
||||
|
||||
| Action seq | Factions | Real winner | Sim winner | Real troops | Sim troops |
|
||||
| ---: | --- | --- | --- | ---: | ---: |
|
||||
| 306 | 1 vs 2 | attacker | attacker | 1454 vs 0 | 1343 vs 0 |
|
||||
| 306 | 1 vs 2 | attacker | attacker | 1454 vs 0 | 1388 vs 0 |
|
||||
| 307 | 2 vs 1 | defender | defender | 0 vs 699 | 0 vs 648 |
|
||||
| 399 | 2 vs 1 | defender | defender | 0 vs 1310 | 0 vs 1315 |
|
||||
| 631 | 1 vs 2 | defender | defender | 0 vs 3766 | 0 vs 3654 |
|
||||
| 1326 | 9 vs 6 | attacker | attacker | 1715 vs 0 | 1701 vs 0 |
|
||||
| 2437 | 2 vs 1 | attacker | attacker | 3146 vs 0 | 3219 vs 0 |
|
||||
| 2584 | 1 vs 2 | defender | defender | 0 vs 2028 | 0 vs 174 |
|
||||
| 2437 | 2 vs 1 | attacker | attacker | 3146 vs 0 | 3247 vs 0 |
|
||||
| 2584 | 1 vs 2 | defender | defender | 0 vs 2028 | 0 vs 168 |
|
||||
| 2654 | 2 vs 1 | defender | defender | 0 vs 335 | 0 vs 467 |
|
||||
| 3536 | 1 vs 2 | attacker | attacker | 2172 vs 0 | 1596 vs 0 |
|
||||
| 3701 | 8 vs 2 | defender | defender | 0 vs 2819 | 0 vs 1344 |
|
||||
| 3536 | 1 vs 2 | attacker | attacker | 2172 vs 0 | 2528 vs 0 |
|
||||
| 3701 | 8 vs 2 | defender | defender | 0 vs 2819 | 0 vs 1348 |
|
||||
| 4298 | 2 vs 1 | defender | defender | 0 vs 3514 | 0 vs 1977 |
|
||||
| 4576 | 2 vs 1 | defender | defender | 0 vs 2028 | 0 vs 1920 |
|
||||
| 6014 | 2 vs 8 | defender | defender | 0 vs 1942 | 0 vs 1474 |
|
||||
| 4576 | 2 vs 1 | defender | defender | 0 vs 2028 | 0 vs 1986 |
|
||||
| 6014 | 2 vs 8 | defender | defender | 0 vs 1942 | 0 vs 2252 |
|
||||
| 6248 | 7 vs 9 | attacker | attacker | 520 vs 0 | 676 vs 0 |
|
||||
| 6705 | 1 vs 2 | defender | defender | 0 vs 3316 | 0 vs 702 |
|
||||
| 6705 | 1 vs 2 | defender | defender | 0 vs 3316 | 0 vs 535 |
|
||||
| 7212 | 2 vs 8 | defender | defender | 0 vs 1253 | 0 vs 1273 |
|
||||
| 8217 | 8 vs 2 | attacker | attacker | 920 vs 0 | 1892 vs 0 |
|
||||
| 8217 | 8 vs 2 | attacker | attacker | 920 vs 0 | 2167 vs 0 |
|
||||
| 8394 | 2 vs 8 | attacker | attacker | 2449 vs 0 | 3186 vs 0 |
|
||||
| 9975 | 2 vs 1 | defender | defender | 0 vs 7420 | 0 vs 7437 |
|
||||
| 9975 | 2 vs 1 | defender | defender | 0 vs 7420 | 0 vs 7840 |
|
||||
| 10229 | 5 vs 7 | attacker | attacker | 2135 vs 0 | 1816 vs 0 |
|
||||
| 10631 | 1 vs 2 | attacker | attacker | 4000 vs 0 | 4000 vs 0 |
|
||||
| 11011 | 2 vs 1 | defender | defender | 0 vs 3532 | 0 vs 3593 |
|
||||
| 11011 | 2 vs 1 | defender | defender | 0 vs 3532 | 0 vs 3658 |
|
||||
| 11012 | 9 vs 6 | defender | defender | 0 vs 846 | 0 vs 1347 |
|
||||
| 11297 | 1 vs 2 | attacker | attacker | 2400 vs 0 | 2400 vs 0 |
|
||||
| 11469 | 5 vs 9 | defender | defender | 0 vs 787 | 0 vs 1489 |
|
||||
| 11470 | 7 vs 5 | attacker | attacker | 3220 vs 0 | 3400 vs 0 |
|
||||
| 11470 | 7 vs 5 | attacker | attacker | 3220 vs 0 | 3425 vs 0 |
|
||||
| 11565 | 5 vs 7 | defender | defender | 190 vs 3420 | 78 vs 3600 |
|
||||
| 12136 | 9 vs 7 | attacker | attacker | 1829 vs 0 | 1581 vs 0 |
|
||||
| 12137 | 2 vs 1 | defender | defender | 0 vs 1894 | 0 vs 1892 |
|
||||
| 12765 | 6 vs 9 | defender | defender | 0 vs 1773 | 0 vs 1747 |
|
||||
| 12765 | 6 vs 9 | defender | defender | 0 vs 1773 | 0 vs 1763 |
|
||||
| 13752 | 2 vs 1 | defender | defender | 0 vs 943 | 0 vs 932 |
|
||||
|
||||
+36
-36
@@ -1,41 +1,41 @@
|
||||
variant,action_seq,config,winner,end_reason,result,total_rounds,total_commands,attacker_ai_commands,defender_ai_commands,attacker_avg_depth,defender_avg_depth,attacker_surviving_units,defender_surviving_units,attacker_surviving_troops,defender_surviving_troops,elapsed_seconds
|
||||
expected_impact_archery_standard_baseline,306,/private/tmp/eagle0-standard-baselines/configs/306_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,17,85,38,23,4.57895,3.30435,2,0,1343,0,
|
||||
expected_impact_archery_standard_baseline,307,/private/tmp/eagle0-standard-baselines/configs/307_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,16,74,36,15,3.55556,2.86667,0,1,0,648,
|
||||
expected_impact_archery_standard_baseline,306,/private/tmp/eagle0-standard-baselines/configs/306_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,19,99,41,32,4.04878,3.65625,2,0,1388,0,
|
||||
expected_impact_archery_standard_baseline,307,/private/tmp/eagle0-standard-baselines/configs/307_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,16,75,37,15,3.54054,2.86667,0,1,0,648,
|
||||
expected_impact_archery_standard_baseline,399,/private/tmp/eagle0-standard-baselines/configs/399_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,6,30,7,14,3,3.85714,0,3,0,1315,
|
||||
expected_impact_archery_standard_baseline,631,/private/tmp/eagle0-standard-baselines/configs/631_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,5,38,12,14,3.58333,3.85714,0,5,0,3654,
|
||||
expected_impact_archery_standard_baseline,1326,/private/tmp/eagle0-standard-baselines/configs/1326_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,11,72,34,19,3.35294,3.63158,2,0,1701,0,
|
||||
expected_impact_archery_standard_baseline,1472,/private/tmp/eagle0-standard-baselines/configs/1472_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,31,143,59,67,3.27119,3.50746,0,2,0,944,
|
||||
expected_impact_archery_standard_baseline,2437,/private/tmp/eagle0-standard-baselines/configs/2437_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,15,141,86,38,3.2093,3.18421,5,0,3219,0,
|
||||
expected_impact_archery_standard_baseline,2584,/private/tmp/eagle0-standard-baselines/configs/2584_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,30,183,45,78,3.6,3.34615,0,1,0,174,
|
||||
expected_impact_archery_standard_baseline,2654,/private/tmp/eagle0-standard-baselines/configs/2654_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,28,198,78,72,3.21795,4.02778,0,2,0,467,
|
||||
expected_impact_archery_standard_baseline,3536,/private/tmp/eagle0-standard-baselines/configs/3536_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,16,155,78,42,3.5641,2.95238,3,0,1596,0,
|
||||
expected_impact_archery_standard_baseline,3701,/private/tmp/eagle0-standard-baselines/configs/3701_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,30,152,57,71,3.33333,3.11268,0,4,0,1344,
|
||||
expected_impact_archery_standard_baseline,4298,/private/tmp/eagle0-standard-baselines/configs/4298_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,3,39,14,11,3,3,0,6,0,1977,
|
||||
expected_impact_archery_standard_baseline,4576,/private/tmp/eagle0-standard-baselines/configs/4576_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,5,52,31,9,3.16129,3,0,3,0,1920,
|
||||
expected_impact_archery_standard_baseline,6014,/private/tmp/eagle0-standard-baselines/configs/6014_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,12,67,35,17,3.31429,3.52941,0,2,0,1474,
|
||||
expected_impact_archery_standard_baseline,6248,/private/tmp/eagle0-standard-baselines/configs/6248_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,25,153,75,46,3.68,2.86957,2,0,676,0,
|
||||
expected_impact_archery_standard_baseline,6408,/private/tmp/eagle0-standard-baselines/configs/6408_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,10,103,67,17,3.49254,3.88235,5,0,4022,0,
|
||||
expected_impact_archery_standard_baseline,6705,/private/tmp/eagle0-standard-baselines/configs/6705_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,31,188,75,82,3.09333,3.53659,0,3,0,702,
|
||||
expected_impact_archery_standard_baseline,631,/private/tmp/eagle0-standard-baselines/configs/631_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,5,38,12,14,3.58333,4.14286,0,5,0,3654,
|
||||
expected_impact_archery_standard_baseline,1326,/private/tmp/eagle0-standard-baselines/configs/1326_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,11,72,34,19,3.26471,3.63158,2,0,1701,0,
|
||||
expected_impact_archery_standard_baseline,1472,/private/tmp/eagle0-standard-baselines/configs/1472_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,31,143,59,67,3.25424,3.46269,0,2,0,944,
|
||||
expected_impact_archery_standard_baseline,2437,/private/tmp/eagle0-standard-baselines/configs/2437_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,16,148,89,43,3.37079,3.32558,5,0,3247,0,
|
||||
expected_impact_archery_standard_baseline,2584,/private/tmp/eagle0-standard-baselines/configs/2584_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,31,190,48,85,3.45833,3.16471,0,1,0,168,
|
||||
expected_impact_archery_standard_baseline,2654,/private/tmp/eagle0-standard-baselines/configs/2654_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,28,198,78,72,3.19231,4.04167,0,2,0,467,
|
||||
expected_impact_archery_standard_baseline,3536,/private/tmp/eagle0-standard-baselines/configs/3536_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,12,120,57,36,3.40351,2.88889,4,0,2528,0,
|
||||
expected_impact_archery_standard_baseline,3701,/private/tmp/eagle0-standard-baselines/configs/3701_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,30,155,62,70,3.5,3.24286,0,4,0,1348,
|
||||
expected_impact_archery_standard_baseline,4298,/private/tmp/eagle0-standard-baselines/configs/4298_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,3,38,13,11,3.07692,2.90909,0,6,0,1977,
|
||||
expected_impact_archery_standard_baseline,4576,/private/tmp/eagle0-standard-baselines/configs/4576_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,4,35,17,7,3,3.28571,0,3,0,1986,
|
||||
expected_impact_archery_standard_baseline,6014,/private/tmp/eagle0-standard-baselines/configs/6014_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,6,39,20,7,3.15,3.42857,0,3,0,2252,
|
||||
expected_impact_archery_standard_baseline,6248,/private/tmp/eagle0-standard-baselines/configs/6248_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,25,153,75,46,3.65333,2.8913,2,0,676,0,
|
||||
expected_impact_archery_standard_baseline,6408,/private/tmp/eagle0-standard-baselines/configs/6408_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,11,107,68,18,3.5,3.33333,5,0,4020,0,
|
||||
expected_impact_archery_standard_baseline,6705,/private/tmp/eagle0-standard-baselines/configs/6705_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,31,205,87,86,3.01149,3.74419,0,2,0,535,
|
||||
expected_impact_archery_standard_baseline,7212,/private/tmp/eagle0-standard-baselines/configs/7212_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,8,39,18,11,3.38889,3.63636,0,2,0,1273,
|
||||
expected_impact_archery_standard_baseline,8217,/private/tmp/eagle0-standard-baselines/configs/8217_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,29,197,97,58,3.42268,3.44828,3,0,1892,0,
|
||||
expected_impact_archery_standard_baseline,8394,/private/tmp/eagle0-standard-baselines/configs/8394_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,9,81,48,17,3.29167,2.64706,4,0,3186,0,
|
||||
expected_impact_archery_standard_baseline,8628,/private/tmp/eagle0-standard-baselines/configs/8628_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,5,41,27,3,3,2.33333,4,0,2760,0,
|
||||
expected_impact_archery_standard_baseline,9975,/private/tmp/eagle0-standard-baselines/configs/9975_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,5,80,24,35,2.79167,2.22857,0,10,0,7437,
|
||||
expected_impact_archery_standard_baseline,10229,/private/tmp/eagle0-standard-baselines/configs/10229_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,23,105,58,4,3.63793,3,3,0,1816,0,
|
||||
expected_impact_archery_standard_baseline,10631,/private/tmp/eagle0-standard-baselines/configs/10631_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,1,16,7,1,2.85714,3,5,1,4000,0,
|
||||
expected_impact_archery_standard_baseline,11011,/private/tmp/eagle0-standard-baselines/configs/11011_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,4,47,16,18,3.4375,3.22222,0,5,0,3593,
|
||||
expected_impact_archery_standard_baseline,11012,/private/tmp/eagle0-standard-baselines/configs/11012_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,30,146,47,67,3.44681,3.64179,0,3,0,1347,
|
||||
expected_impact_archery_standard_baseline,11112,/private/tmp/eagle0-standard-baselines/configs/11112_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,3,31,7,8,3.14286,2,0,11,0,7595,
|
||||
expected_impact_archery_standard_baseline,8217,/private/tmp/eagle0-standard-baselines/configs/8217_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,22,164,79,49,3.35443,3.08163,3,0,2167,0,
|
||||
expected_impact_archery_standard_baseline,8394,/private/tmp/eagle0-standard-baselines/configs/8394_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,9,81,48,17,3.25,2.64706,4,0,3186,0,
|
||||
expected_impact_archery_standard_baseline,8628,/private/tmp/eagle0-standard-baselines/configs/8628_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,5,41,27,3,2.96296,2,4,0,2760,0,
|
||||
expected_impact_archery_standard_baseline,9975,/private/tmp/eagle0-standard-baselines/configs/9975_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,4,70,23,27,2.65217,2.40741,0,10,0,7840,
|
||||
expected_impact_archery_standard_baseline,10229,/private/tmp/eagle0-standard-baselines/configs/10229_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,23,104,57,4,3.77193,3,3,0,1816,0,
|
||||
expected_impact_archery_standard_baseline,10631,/private/tmp/eagle0-standard-baselines/configs/10631_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,1,16,7,1,3,3,5,1,4000,0,
|
||||
expected_impact_archery_standard_baseline,11011,/private/tmp/eagle0-standard-baselines/configs/11011_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,5,51,22,18,3.5,3,0,5,0,3658,
|
||||
expected_impact_archery_standard_baseline,11012,/private/tmp/eagle0-standard-baselines/configs/11012_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,30,146,47,67,3.40426,3.62687,0,3,0,1347,
|
||||
expected_impact_archery_standard_baseline,11112,/private/tmp/eagle0-standard-baselines/configs/11112_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,3,31,7,8,3.42857,2,0,11,0,7595,
|
||||
expected_impact_archery_standard_baseline,11297,/private/tmp/eagle0-standard-baselines/configs/11297_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,1,13,5,1,3,3,3,1,2400,0,
|
||||
expected_impact_archery_standard_baseline,11469,/private/tmp/eagle0-standard-baselines/configs/11469_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,8,58,30,12,3.2,3.16667,0,2,0,1489,
|
||||
expected_impact_archery_standard_baseline,11470,/private/tmp/eagle0-standard-baselines/configs/11470_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,12,104,68,20,3.44118,3,4,0,3400,0,
|
||||
expected_impact_archery_standard_baseline,11565,/private/tmp/eagle0-standard-baselines/configs/11565_standard.json,defender,max_rounds_reached,Defender won by surviving maximum rounds,31,103,30,34,4.26667,3.61765,1,4,78,3600,
|
||||
expected_impact_archery_standard_baseline,11662,/private/tmp/eagle0-standard-baselines/configs/11662_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,9,133,98,18,2.86735,3.61111,9,0,6627,0,
|
||||
expected_impact_archery_standard_baseline,11754,/private/tmp/eagle0-standard-baselines/configs/11754_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,30,163,72,76,3.22222,3.26316,0,3,0,1000,
|
||||
expected_impact_archery_standard_baseline,11941,/private/tmp/eagle0-standard-baselines/configs/11941_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,6,64,44,7,3.11364,3,6,0,4777,0,
|
||||
expected_impact_archery_standard_baseline,11942,/private/tmp/eagle0-standard-baselines/configs/11942_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,5,91,59,16,2.61017,3.375,12,0,8572,0,
|
||||
expected_impact_archery_standard_baseline,12136,/private/tmp/eagle0-standard-baselines/configs/12136_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,21,141,79,34,3.72152,4.52941,3,0,1581,0,
|
||||
expected_impact_archery_standard_baseline,12137,/private/tmp/eagle0-standard-baselines/configs/12137_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,8,50,19,17,3.21053,3.11765,0,3,0,1892,
|
||||
expected_impact_archery_standard_baseline,12138,/private/tmp/eagle0-standard-baselines/configs/12138_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,13,98,68,16,3.45588,2.875,2,0,1758,0,
|
||||
expected_impact_archery_standard_baseline,12765,/private/tmp/eagle0-standard-baselines/configs/12765_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,9,40,21,10,3.66667,3.2,0,2,0,1747,
|
||||
expected_impact_archery_standard_baseline,11469,/private/tmp/eagle0-standard-baselines/configs/11469_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,8,58,30,12,3.16667,3.16667,0,2,0,1489,
|
||||
expected_impact_archery_standard_baseline,11470,/private/tmp/eagle0-standard-baselines/configs/11470_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,17,99,65,22,3.50769,2.68182,4,0,3425,0,
|
||||
expected_impact_archery_standard_baseline,11565,/private/tmp/eagle0-standard-baselines/configs/11565_standard.json,defender,max_rounds_reached,Defender won by surviving maximum rounds,31,103,30,34,4.26667,3.91176,1,4,78,3600,
|
||||
expected_impact_archery_standard_baseline,11662,/private/tmp/eagle0-standard-baselines/configs/11662_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,8,120,85,17,2.85882,3.23529,9,0,6624,0,
|
||||
expected_impact_archery_standard_baseline,11754,/private/tmp/eagle0-standard-baselines/configs/11754_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,30,163,72,76,3.31944,3.28947,0,3,0,1000,
|
||||
expected_impact_archery_standard_baseline,11941,/private/tmp/eagle0-standard-baselines/configs/11941_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,6,64,44,7,3.25,3,6,0,4777,0,
|
||||
expected_impact_archery_standard_baseline,11942,/private/tmp/eagle0-standard-baselines/configs/11942_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,5,91,59,16,2.64407,3.375,12,0,8572,0,
|
||||
expected_impact_archery_standard_baseline,12136,/private/tmp/eagle0-standard-baselines/configs/12136_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,21,141,79,34,3.70886,4.52941,3,0,1581,0,
|
||||
expected_impact_archery_standard_baseline,12137,/private/tmp/eagle0-standard-baselines/configs/12137_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,8,50,19,17,3.21053,3.29412,0,3,0,1892,
|
||||
expected_impact_archery_standard_baseline,12138,/private/tmp/eagle0-standard-baselines/configs/12138_standard.json,attacker,last_player_standing,Attacker won by eliminating all defenders,14,102,69,16,3.43478,2.9375,3,0,2512,0,
|
||||
expected_impact_archery_standard_baseline,12765,/private/tmp/eagle0-standard-baselines/configs/12765_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,11,46,26,11,3.61538,3.09091,0,2,0,1763,
|
||||
expected_impact_archery_standard_baseline,13752,/private/tmp/eagle0-standard-baselines/configs/13752_standard.json,defender,last_player_standing,Defender won by eliminating all attackers,7,38,16,10,3.5,3.3,0,2,0,932,
|
||||
|
||||
|
+4
-4
@@ -25,15 +25,15 @@ Survivor margin is `attacker_surviving_troops - defender_surviving_troops`.
|
||||
|
||||
| Action seq | Winner | End reason | Attacker troops | Defender troops | Margin |
|
||||
| ---: | --- | --- | ---: | ---: | ---: |
|
||||
| 2584 | defender | last_player_standing | 0 | 174 | -174 |
|
||||
| 2584 | defender | last_player_standing | 0 | 168 | -168 |
|
||||
| 2654 | defender | last_player_standing | 0 | 467 | -467 |
|
||||
| 6705 | defender | last_player_standing | 0 | 535 | -535 |
|
||||
| 307 | defender | last_player_standing | 0 | 648 | -648 |
|
||||
| 6248 | attacker | last_player_standing | 676 | 0 | +676 |
|
||||
| 6705 | defender | last_player_standing | 0 | 702 | -702 |
|
||||
| 13752 | defender | last_player_standing | 0 | 932 | -932 |
|
||||
| 1472 | defender | last_player_standing | 0 | 944 | -944 |
|
||||
| 11754 | defender | last_player_standing | 0 | 1000 | -1000 |
|
||||
| 7212 | defender | last_player_standing | 0 | 1273 | -1273 |
|
||||
| 399 | defender | last_player_standing | 0 | 1315 | -1315 |
|
||||
| 306 | attacker | last_player_standing | 1343 | 0 | +1343 |
|
||||
| 3701 | defender | last_player_standing | 0 | 1344 | -1344 |
|
||||
| 11012 | defender | last_player_standing | 0 | 1347 | -1347 |
|
||||
| 3701 | defender | last_player_standing | 0 | 1348 | -1348 |
|
||||
|
||||
+16
-16
@@ -1,41 +1,41 @@
|
||||
action_seq,attacker_factions,attacker_player,defender_factions,defender_player,ai_vs_ai,real_winner,sim_winner,winner_match,real_round,sim_round,real_attacker_troops,real_defender_troops,sim_attacker_troops,sim_defender_troops
|
||||
306,1,AI,2,AI,true,attacker,attacker,true,0,17,1454,0,1343,0
|
||||
306,1,AI,2,AI,true,attacker,attacker,true,0,19,1454,0,1388,0
|
||||
307,2,AI,1,AI,true,defender,defender,true,0,16,0,699,0,648
|
||||
399,2,AI,1,AI,true,defender,defender,true,0,6,0,1310,0,1315
|
||||
631,1,AI,2,AI,true,defender,defender,true,0,5,0,3766,0,3654
|
||||
1326,9,AI,6,AI,true,attacker,attacker,true,0,11,1715,0,1701,0
|
||||
1472,8,AI,3,human,false,defender,defender,true,0,31,0,1593,0,944
|
||||
2437,2,AI,1,AI,true,attacker,attacker,true,0,15,3146,0,3219,0
|
||||
2584,1,AI,2,AI,true,defender,defender,true,0,30,0,2028,0,174
|
||||
2437,2,AI,1,AI,true,attacker,attacker,true,0,16,3146,0,3247,0
|
||||
2584,1,AI,2,AI,true,defender,defender,true,0,31,0,2028,0,168
|
||||
2654,2,AI,1,AI,true,defender,defender,true,0,28,0,335,0,467
|
||||
3536,1,AI,2,AI,true,attacker,attacker,true,0,16,2172,0,1596,0
|
||||
3701,8,AI,2,AI,true,defender,defender,true,0,30,0,2819,0,1344
|
||||
3536,1,AI,2,AI,true,attacker,attacker,true,0,12,2172,0,2528,0
|
||||
3701,8,AI,2,AI,true,defender,defender,true,0,30,0,2819,0,1348
|
||||
4298,2,AI,1,AI,true,defender,defender,true,0,3,0,3514,0,1977
|
||||
4576,2,AI,1,AI,true,defender,defender,true,0,5,0,2028,0,1920
|
||||
6014,2,AI,8,AI,true,defender,defender,true,0,12,0,1942,0,1474
|
||||
4576,2,AI,1,AI,true,defender,defender,true,0,4,0,2028,0,1986
|
||||
6014,2,AI,8,AI,true,defender,defender,true,0,6,0,1942,0,2252
|
||||
6248,7,AI,9,AI,true,attacker,attacker,true,0,25,520,0,676,0
|
||||
6408,4,human,7,AI,false,attacker,attacker,true,0,10,4156,0,4022,0
|
||||
6705,1,AI,2,AI,true,defender,defender,true,0,31,0,3316,0,702
|
||||
6408,4,human,7,AI,false,attacker,attacker,true,0,11,4156,0,4020,0
|
||||
6705,1,AI,2,AI,true,defender,defender,true,0,31,0,3316,0,535
|
||||
7212,2,AI,8,AI,true,defender,defender,true,0,8,0,1253,0,1273
|
||||
8217,8,AI,2,AI,true,attacker,attacker,true,0,29,920,0,1892,0
|
||||
8217,8,AI,2,AI,true,attacker,attacker,true,0,22,920,0,2167,0
|
||||
8394,2,AI,8,AI,true,attacker,attacker,true,0,9,2449,0,3186,0
|
||||
8628,3,human,8,AI,false,attacker,attacker,true,0,5,2874,0,2760,0
|
||||
9975,2,AI,1,AI,true,defender,defender,true,0,5,0,7420,0,7437
|
||||
9975,2,AI,1,AI,true,defender,defender,true,0,4,0,7420,0,7840
|
||||
10229,5,AI,7,AI,true,attacker,attacker,true,0,23,2135,0,1816,0
|
||||
10631,1,AI,2,AI,true,attacker,attacker,true,0,1,4000,0,4000,0
|
||||
11011,2,AI,1,AI,true,defender,defender,true,0,4,0,3532,0,3593
|
||||
11011,2,AI,1,AI,true,defender,defender,true,0,5,0,3532,0,3658
|
||||
11012,9,AI,6,AI,true,defender,defender,true,0,30,0,846,0,1347
|
||||
11112,5,AI,4,human,false,defender,defender,true,0,3,0,7595,0,7595
|
||||
11297,1,AI,2,AI,true,attacker,attacker,true,0,1,2400,0,2400,0
|
||||
11469,5,AI,9,AI,true,defender,defender,true,0,8,0,787,0,1489
|
||||
11470,7,AI,5,AI,true,attacker,attacker,true,0,12,3220,0,3400,0
|
||||
11470,7,AI,5,AI,true,attacker,attacker,true,0,17,3220,0,3425,0
|
||||
11565,5,AI,7,AI,true,defender,defender,true,0,31,190,3420,78,3600
|
||||
11662,4,human,9,AI,false,attacker,attacker,true,0,9,7326,0,6627,0
|
||||
11662,4,human,9,AI,false,attacker,attacker,true,0,8,7326,0,6624,0
|
||||
11754,7,AI,4,human,false,attacker,defender,false,0,30,2119,0,0,1000
|
||||
11941,3,human,5,AI,false,attacker,attacker,true,0,6,4901,0,4777,0
|
||||
11942,4,human,7,AI,false,attacker,attacker,true,0,5,8840,0,8572,0
|
||||
12136,9,AI,7,AI,true,attacker,attacker,true,0,21,1829,0,1581,0
|
||||
12137,2,AI,1,AI,true,defender,defender,true,0,8,0,1894,0,1892
|
||||
12138,3,human,5,AI,false,attacker,attacker,true,0,13,2960,0,1758,0
|
||||
12765,6,AI,9,AI,true,defender,defender,true,0,9,0,1773,0,1747
|
||||
12138,3,human,5,AI,false,attacker,attacker,true,0,14,2960,0,2512,0
|
||||
12765,6,AI,9,AI,true,defender,defender,true,0,11,0,1773,0,1763
|
||||
13752,2,AI,1,AI,true,defender,defender,true,0,7,0,943,0,932
|
||||
|
||||
|
+16
-16
@@ -14,43 +14,43 @@ factions are marked as AI players.
|
||||
|
||||
| Action seq | Attacker | Defender | Real winner | Sim winner | Match | Real troops | Sim troops |
|
||||
| ---: | --- | --- | --- | --- | --- | ---: | ---: |
|
||||
| 306 | 1 (AI) | 2 (AI) | attacker | attacker | yes | 1454 vs 0 | 1343 vs 0 |
|
||||
| 306 | 1 (AI) | 2 (AI) | attacker | attacker | yes | 1454 vs 0 | 1388 vs 0 |
|
||||
| 307 | 2 (AI) | 1 (AI) | defender | defender | yes | 0 vs 699 | 0 vs 648 |
|
||||
| 399 | 2 (AI) | 1 (AI) | defender | defender | yes | 0 vs 1310 | 0 vs 1315 |
|
||||
| 631 | 1 (AI) | 2 (AI) | defender | defender | yes | 0 vs 3766 | 0 vs 3654 |
|
||||
| 1326 | 9 (AI) | 6 (AI) | attacker | attacker | yes | 1715 vs 0 | 1701 vs 0 |
|
||||
| 1472 | 8 (AI) | 3 (human) | defender | defender | yes | 0 vs 1593 | 0 vs 944 |
|
||||
| 2437 | 2 (AI) | 1 (AI) | attacker | attacker | yes | 3146 vs 0 | 3219 vs 0 |
|
||||
| 2584 | 1 (AI) | 2 (AI) | defender | defender | yes | 0 vs 2028 | 0 vs 174 |
|
||||
| 2437 | 2 (AI) | 1 (AI) | attacker | attacker | yes | 3146 vs 0 | 3247 vs 0 |
|
||||
| 2584 | 1 (AI) | 2 (AI) | defender | defender | yes | 0 vs 2028 | 0 vs 168 |
|
||||
| 2654 | 2 (AI) | 1 (AI) | defender | defender | yes | 0 vs 335 | 0 vs 467 |
|
||||
| 3536 | 1 (AI) | 2 (AI) | attacker | attacker | yes | 2172 vs 0 | 1596 vs 0 |
|
||||
| 3701 | 8 (AI) | 2 (AI) | defender | defender | yes | 0 vs 2819 | 0 vs 1344 |
|
||||
| 3536 | 1 (AI) | 2 (AI) | attacker | attacker | yes | 2172 vs 0 | 2528 vs 0 |
|
||||
| 3701 | 8 (AI) | 2 (AI) | defender | defender | yes | 0 vs 2819 | 0 vs 1348 |
|
||||
| 4298 | 2 (AI) | 1 (AI) | defender | defender | yes | 0 vs 3514 | 0 vs 1977 |
|
||||
| 4576 | 2 (AI) | 1 (AI) | defender | defender | yes | 0 vs 2028 | 0 vs 1920 |
|
||||
| 6014 | 2 (AI) | 8 (AI) | defender | defender | yes | 0 vs 1942 | 0 vs 1474 |
|
||||
| 4576 | 2 (AI) | 1 (AI) | defender | defender | yes | 0 vs 2028 | 0 vs 1986 |
|
||||
| 6014 | 2 (AI) | 8 (AI) | defender | defender | yes | 0 vs 1942 | 0 vs 2252 |
|
||||
| 6248 | 7 (AI) | 9 (AI) | attacker | attacker | yes | 520 vs 0 | 676 vs 0 |
|
||||
| 6408 | 4 (human) | 7 (AI) | attacker | attacker | yes | 4156 vs 0 | 4022 vs 0 |
|
||||
| 6705 | 1 (AI) | 2 (AI) | defender | defender | yes | 0 vs 3316 | 0 vs 702 |
|
||||
| 6408 | 4 (human) | 7 (AI) | attacker | attacker | yes | 4156 vs 0 | 4020 vs 0 |
|
||||
| 6705 | 1 (AI) | 2 (AI) | defender | defender | yes | 0 vs 3316 | 0 vs 535 |
|
||||
| 7212 | 2 (AI) | 8 (AI) | defender | defender | yes | 0 vs 1253 | 0 vs 1273 |
|
||||
| 8217 | 8 (AI) | 2 (AI) | attacker | attacker | yes | 920 vs 0 | 1892 vs 0 |
|
||||
| 8217 | 8 (AI) | 2 (AI) | attacker | attacker | yes | 920 vs 0 | 2167 vs 0 |
|
||||
| 8394 | 2 (AI) | 8 (AI) | attacker | attacker | yes | 2449 vs 0 | 3186 vs 0 |
|
||||
| 8628 | 3 (human) | 8 (AI) | attacker | attacker | yes | 2874 vs 0 | 2760 vs 0 |
|
||||
| 9975 | 2 (AI) | 1 (AI) | defender | defender | yes | 0 vs 7420 | 0 vs 7437 |
|
||||
| 9975 | 2 (AI) | 1 (AI) | defender | defender | yes | 0 vs 7420 | 0 vs 7840 |
|
||||
| 10229 | 5 (AI) | 7 (AI) | attacker | attacker | yes | 2135 vs 0 | 1816 vs 0 |
|
||||
| 10631 | 1 (AI) | 2 (AI) | attacker | attacker | yes | 4000 vs 0 | 4000 vs 0 |
|
||||
| 11011 | 2 (AI) | 1 (AI) | defender | defender | yes | 0 vs 3532 | 0 vs 3593 |
|
||||
| 11011 | 2 (AI) | 1 (AI) | defender | defender | yes | 0 vs 3532 | 0 vs 3658 |
|
||||
| 11012 | 9 (AI) | 6 (AI) | defender | defender | yes | 0 vs 846 | 0 vs 1347 |
|
||||
| 11112 | 5 (AI) | 4 (human) | defender | defender | yes | 0 vs 7595 | 0 vs 7595 |
|
||||
| 11297 | 1 (AI) | 2 (AI) | attacker | attacker | yes | 2400 vs 0 | 2400 vs 0 |
|
||||
| 11469 | 5 (AI) | 9 (AI) | defender | defender | yes | 0 vs 787 | 0 vs 1489 |
|
||||
| 11470 | 7 (AI) | 5 (AI) | attacker | attacker | yes | 3220 vs 0 | 3400 vs 0 |
|
||||
| 11470 | 7 (AI) | 5 (AI) | attacker | attacker | yes | 3220 vs 0 | 3425 vs 0 |
|
||||
| 11565 | 5 (AI) | 7 (AI) | defender | defender | yes | 190 vs 3420 | 78 vs 3600 |
|
||||
| 11662 | 4 (human) | 9 (AI) | attacker | attacker | yes | 7326 vs 0 | 6627 vs 0 |
|
||||
| 11662 | 4 (human) | 9 (AI) | attacker | attacker | yes | 7326 vs 0 | 6624 vs 0 |
|
||||
| 11754 | 7 (AI) | 4 (human) | attacker | defender | no | 2119 vs 0 | 0 vs 1000 |
|
||||
| 11941 | 3 (human) | 5 (AI) | attacker | attacker | yes | 4901 vs 0 | 4777 vs 0 |
|
||||
| 11942 | 4 (human) | 7 (AI) | attacker | attacker | yes | 8840 vs 0 | 8572 vs 0 |
|
||||
| 12136 | 9 (AI) | 7 (AI) | attacker | attacker | yes | 1829 vs 0 | 1581 vs 0 |
|
||||
| 12137 | 2 (AI) | 1 (AI) | defender | defender | yes | 0 vs 1894 | 0 vs 1892 |
|
||||
| 12138 | 3 (human) | 5 (AI) | attacker | attacker | yes | 2960 vs 0 | 1758 vs 0 |
|
||||
| 12765 | 6 (AI) | 9 (AI) | defender | defender | yes | 0 vs 1773 | 0 vs 1747 |
|
||||
| 12138 | 3 (human) | 5 (AI) | attacker | attacker | yes | 2960 vs 0 | 2512 vs 0 |
|
||||
| 12765 | 6 (AI) | 9 (AI) | defender | defender | yes | 0 vs 1773 | 0 vs 1763 |
|
||||
| 13752 | 2 (AI) | 1 (AI) | defender | defender | yes | 0 vs 943 | 0 vs 932 |
|
||||
|
||||
@@ -1143,32 +1143,36 @@ TEST_F(AIIntegrationTest, StandardScorer_ArcheryEvaluationBeatsEndTurnWithSingle
|
||||
const double currentScore = scorer->GuessedStateScore(false, gameState, strategy, castleCoords);
|
||||
AICommandEvaluator evaluator(*scorer, apdCache, battalionTypeGetter);
|
||||
const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(10);
|
||||
const double archeryScore = evaluator
|
||||
.EvaluateCommand(
|
||||
0,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
engine,
|
||||
strategy,
|
||||
currentScore,
|
||||
castleCoords,
|
||||
std::distance(commands->begin(), archeryCommand),
|
||||
deadline)
|
||||
.get();
|
||||
const double endTurnScore = evaluator
|
||||
.EvaluateCommand(
|
||||
0,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
engine,
|
||||
strategy,
|
||||
currentScore,
|
||||
castleCoords,
|
||||
std::distance(commands->begin(), endTurnCommand),
|
||||
deadline)
|
||||
.get();
|
||||
const auto archeryResult = evaluator
|
||||
.EvaluateCommand(
|
||||
0,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
engine,
|
||||
strategy,
|
||||
currentScore,
|
||||
castleCoords,
|
||||
std::distance(commands->begin(), archeryCommand),
|
||||
deadline)
|
||||
.get();
|
||||
const auto endTurnResult = evaluator
|
||||
.EvaluateCommand(
|
||||
0,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
engine,
|
||||
strategy,
|
||||
currentScore,
|
||||
castleCoords,
|
||||
std::distance(commands->begin(), endTurnCommand),
|
||||
deadline)
|
||||
.get();
|
||||
ASSERT_TRUE(archeryResult.completed);
|
||||
ASSERT_TRUE(endTurnResult.completed);
|
||||
const double archeryScore = archeryResult.score;
|
||||
const double endTurnScore = endTurnResult.score;
|
||||
|
||||
EXPECT_TRUE(std::isfinite(archeryScore));
|
||||
EXPECT_GT(archeryScore, endTurnScore)
|
||||
|
||||
@@ -215,3 +215,30 @@ cc_test(
|
||||
"@googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "real_battle_decision_regression_test",
|
||||
size = "large",
|
||||
srcs = ["RealBattleDecisionRegressionTest.cpp"],
|
||||
copts = TEST_COPTS,
|
||||
data = [
|
||||
"testdata/kings_loyalists_before_mage_fire.fb",
|
||||
"//src/main/resources/net/eagle0/shardok:battalion_types",
|
||||
"//src/main/resources/net/eagle0/shardok:settings",
|
||||
],
|
||||
linkstatic = True,
|
||||
tags = ["exclusive"],
|
||||
deps = [
|
||||
"//src/main/cpp/net/eagle0/common:filesystem_utils",
|
||||
"//src/main/cpp/net/eagle0/common:random_generator",
|
||||
"//src/main/cpp/net/eagle0/shardok/ai:shardok_ai_client",
|
||||
"//src/main/cpp/net/eagle0/shardok/ai:transposition_table",
|
||||
"//src/main/cpp/net/eagle0/shardok/ai_testing_common:ai_client_factory",
|
||||
"//src/main/cpp/net/eagle0/shardok/ai_testing_common:game_settings_factory",
|
||||
"//src/main/cpp/net/eagle0/shardok/library:engine",
|
||||
"//src/main/cpp/net/eagle0/shardok/library:game_state_w",
|
||||
"//src/main/cpp/net/eagle0/shardok/library/action_point_distances:action_point_distances_cache",
|
||||
"@googletest//:gtest",
|
||||
"@googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include "src/main/cpp/net/eagle0/common/FilesystemUtils.hpp"
|
||||
#include "src/main/cpp/net/eagle0/common/RandomGenerator.hpp"
|
||||
#include "src/main/cpp/net/eagle0/shardok/ai/AIConfig.hpp"
|
||||
#include "src/main/cpp/net/eagle0/shardok/ai/ShardokAIClient.hpp"
|
||||
#include "src/main/cpp/net/eagle0/shardok/ai/TranspositionTable.hpp"
|
||||
#include "src/main/cpp/net/eagle0/shardok/ai_testing_common/AIClientFactory.hpp"
|
||||
#include "src/main/cpp/net/eagle0/shardok/ai_testing_common/GameSettingsFactory.hpp"
|
||||
#include "src/main/cpp/net/eagle0/shardok/library/GameStateW.hpp"
|
||||
#include "src/main/cpp/net/eagle0/shardok/library/ShardokEngine.hpp"
|
||||
#include "src/main/cpp/net/eagle0/shardok/library/action_point_distances/ActionPointDistancesCache.hpp"
|
||||
|
||||
namespace shardok {
|
||||
|
||||
extern TranspositionTable g_transpositionTable;
|
||||
|
||||
namespace {
|
||||
|
||||
using net::eagle0::shardok::common::START_FIRE_COMMAND;
|
||||
|
||||
constexpr PlayerId kAttackerPlayerId = 0;
|
||||
|
||||
class RealBattleDecisionRegressionTest : public testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
auto path = std::filesystem::current_path();
|
||||
path.append(
|
||||
"bazel-bin/src/test/cpp/net/eagle0/shardok/ai/"
|
||||
"real_battle_decision_regression_test");
|
||||
FilesystemUtils::SetExecPath(path);
|
||||
|
||||
g_transpositionTable.clear();
|
||||
ActionPointDistancesCache::ClearThreadLocalCache();
|
||||
|
||||
settings = ai_testing_common::GameSettingsFactory::CreateDefault();
|
||||
auto setter = settings->GetSetter();
|
||||
setter.SetInt("maxRounds", 31);
|
||||
setter.SetInt("minLookaheadTurns", 1);
|
||||
setter.SetDouble("allAiBattleTimeBudgetMaximum", 0.2);
|
||||
setter.SetRandomGenerator(std::make_shared<StdLibraryGenerator>(1));
|
||||
}
|
||||
|
||||
GameSettingsSPtr settings;
|
||||
};
|
||||
|
||||
TEST_F(RealBattleDecisionRegressionTest, DoesNotChooseKingsLoyalistsMageDistantFire) {
|
||||
// Real battle 68f300179888acd7_52_2add2586 immediately before recorded action 70.
|
||||
// The live stream chose START_FIRE with this mage at (5, 0); the current deterministic
|
||||
// test budget reproduces the same bad class of choice at a nearby distant tile.
|
||||
const auto fixturePath =
|
||||
std::filesystem::current_path() /
|
||||
"src/test/cpp/net/eagle0/shardok/ai/testdata/kings_loyalists_before_mage_fire.fb";
|
||||
const auto state = GameStateW::LoadFrom(fixturePath.string());
|
||||
const ShardokEngine engine(settings, state);
|
||||
const auto commands = engine.GetAvailableCommandsForAIPlayer(kAttackerPlayerId);
|
||||
const auto ai = ai_testing_common::AIClientFactory::Create(
|
||||
kAttackerPlayerId,
|
||||
false,
|
||||
state->hex_map(),
|
||||
settings->GetGetter(),
|
||||
AIAlgorithmType::ITERATIVE_DEEPENING,
|
||||
ScoringCalculatorType::STANDARD,
|
||||
true);
|
||||
|
||||
const auto choice = ai->ChooseCommandIndex(engine);
|
||||
|
||||
ASSERT_LT(choice.chosenIndex, commands->size());
|
||||
const auto& chosenCommand = commands->at(choice.chosenIndex);
|
||||
EXPECT_FALSE(
|
||||
chosenCommand->GetCommandType() == START_FIRE_COMMAND &&
|
||||
chosenCommand->GetActorUnitId() == 3);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace shardok
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user