mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-28 20:55:44 +00:00
Add AI follow-up scoring experiment switch
This commit is contained in:
@@ -155,10 +155,12 @@ static auto LeafMoveFollowUpScoreBonus(
|
||||
AICommandEvaluator::AICommandEvaluator(
|
||||
const AIScoreCalculator& scorer,
|
||||
const APDCache& apdCache,
|
||||
BattalionTypeGetter battalionTypeGetter)
|
||||
BattalionTypeGetter battalionTypeGetter,
|
||||
const bool scoreMoveFollowUps)
|
||||
: scorer_(scorer),
|
||||
apdCache_(apdCache),
|
||||
battalionTypeGetter_(std::move(battalionTypeGetter)) {}
|
||||
battalionTypeGetter_(std::move(battalionTypeGetter)),
|
||||
scoreMoveFollowUps_(scoreMoveFollowUps) {}
|
||||
|
||||
auto AICommandEvaluator::PerformLookahead(
|
||||
const PlayerId pid,
|
||||
@@ -293,8 +295,9 @@ auto AICommandEvaluator::EvaluateWithRandomness(
|
||||
|
||||
const auto guessedCommands = guessedEngine.GetAvailableCommandsForAIPlayer(pid);
|
||||
const ScoreValue leafMoveFollowUpBonus =
|
||||
remainingLookahead <= 0 ? LeafMoveFollowUpScoreBonus(guessedEngine, pid, commandIndex)
|
||||
: 0.0;
|
||||
scoreMoveFollowUps_ && remainingLookahead <= 0
|
||||
? LeafMoveFollowUpScoreBonus(guessedEngine, pid, commandIndex)
|
||||
: 0.0;
|
||||
auto innerEngine = std::make_shared<ShardokEngine>(guessedEngine, false);
|
||||
try {
|
||||
innerEngine->PostCommand(pid, commandIndex, randomGenerator);
|
||||
|
||||
@@ -35,7 +35,8 @@ public:
|
||||
AICommandEvaluator(
|
||||
const AIScoreCalculator& scorer,
|
||||
const APDCache& apdCache,
|
||||
BattalionTypeGetter battalionTypeGetter); // Pass by value
|
||||
BattalionTypeGetter battalionTypeGetter,
|
||||
bool scoreMoveFollowUps = true); // Pass by value
|
||||
|
||||
/// Evaluates the score for a particular command index with lookahead.
|
||||
struct EvaluationResult {
|
||||
@@ -79,6 +80,7 @@ private:
|
||||
const AIScoreCalculator& scorer_;
|
||||
const APDCache& apdCache_;
|
||||
BattalionTypeGetter battalionTypeGetter_;
|
||||
bool scoreMoveFollowUps_;
|
||||
|
||||
struct ImmediateAndLookaheadScore {
|
||||
ScoreValue immediateScore{};
|
||||
|
||||
@@ -44,14 +44,16 @@ IterativeDeepeningAI::IterativeDeepeningAI(
|
||||
const CoordsSet& castleCoords,
|
||||
const AIScoreCalculator& scorer,
|
||||
const APDCache& apdCache,
|
||||
BattalionTypeGetter battalionTypeGetter)
|
||||
BattalionTypeGetter battalionTypeGetter,
|
||||
const bool scoreMoveFollowUps)
|
||||
: playerId(playerId),
|
||||
isDefender(isDefender),
|
||||
strategy(std::move(strategy)),
|
||||
castleCoords(castleCoords),
|
||||
scorer(scorer),
|
||||
apdCache(apdCache),
|
||||
battalionTypeGetter(std::move(battalionTypeGetter)) {}
|
||||
battalionTypeGetter(std::move(battalionTypeGetter)),
|
||||
scoreMoveFollowUps(scoreMoveFollowUps) {}
|
||||
|
||||
auto IterativeDeepeningAI::IterativeSearch(
|
||||
const GameSettingsSPtr& settings,
|
||||
@@ -333,7 +335,7 @@ auto IterativeDeepeningAI::SearchCommandAtDepthWithEngine(
|
||||
const auto deadline = startTime + timeBudget.remainingBudget;
|
||||
|
||||
// Create command evaluator for lookahead search
|
||||
AICommandEvaluator evaluator(scorer, apdCache, battalionTypeGetter);
|
||||
AICommandEvaluator evaluator(scorer, apdCache, battalionTypeGetter, scoreMoveFollowUps);
|
||||
|
||||
// Get the future from EvaluateCommand - don't wait yet
|
||||
// Note: EvaluateCommand expects remainingLookahead, not desiredDepth
|
||||
|
||||
@@ -64,7 +64,8 @@ public:
|
||||
const CoordsSet& castleCoords,
|
||||
const AIScoreCalculator& scorer,
|
||||
const APDCache& apdCache,
|
||||
BattalionTypeGetter battalionTypeGetter); // Pass by value
|
||||
BattalionTypeGetter battalionTypeGetter,
|
||||
bool scoreMoveFollowUps); // Pass by value
|
||||
|
||||
[[nodiscard]] SearchResult IterativeSearch(
|
||||
const GameSettingsSPtr& settings,
|
||||
@@ -80,6 +81,7 @@ private:
|
||||
const AIScoreCalculator& scorer;
|
||||
const APDCache& apdCache;
|
||||
BattalionTypeGetter battalionTypeGetter;
|
||||
bool scoreMoveFollowUps;
|
||||
|
||||
// Reusable vectors to reduce memory allocations
|
||||
mutable std::vector<std::vector<ScoreValue>> scoresByDepth;
|
||||
|
||||
@@ -65,12 +65,14 @@ ShardokAIClient::ShardokAIClient(
|
||||
const SettingsGetter &settings,
|
||||
const AIAlgorithmType aiAlgorithmType,
|
||||
const ScoringCalculatorType scoringCalculatorType,
|
||||
const mcts::MCTSConfig &mctsConfig)
|
||||
const mcts::MCTSConfig &mctsConfig,
|
||||
const bool scoreMoveFollowUps)
|
||||
: playerId(playerId),
|
||||
isDefender(isDefender),
|
||||
isAllAiBattle(isAllAiBattle),
|
||||
aiAlgorithmType(aiAlgorithmType),
|
||||
scoringCalculatorType(scoringCalculatorType),
|
||||
scoreMoveFollowUps(scoreMoveFollowUps),
|
||||
alCache(std::make_unique<AttackLocationsCache>(hexMap, settings)),
|
||||
waterCrossingCommandChooser(playerId, apdCache),
|
||||
mctsConfig(mctsConfig) {
|
||||
@@ -365,7 +367,8 @@ auto ShardokAIClient::StandardChooseCommandIndex(
|
||||
castleCoords,
|
||||
*scorer,
|
||||
apdCache,
|
||||
battalionTypeGetter);
|
||||
battalionTypeGetter,
|
||||
scoreMoveFollowUps);
|
||||
search_result =
|
||||
ai.IterativeSearch(settings, guessedState, realAvailableCommands, timeBudget);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ private:
|
||||
const bool isAllAiBattle; // Whether this battle has only AI players (for faster time budgets)
|
||||
const AIAlgorithmType aiAlgorithmType;
|
||||
const ScoringCalculatorType scoringCalculatorType;
|
||||
const bool scoreMoveFollowUps;
|
||||
|
||||
APDCache apdCache = std::make_shared<ActionPointDistancesCache>();
|
||||
ALCache alCache;
|
||||
@@ -75,7 +76,8 @@ public:
|
||||
const SettingsGetter& settings,
|
||||
AIAlgorithmType aiAlgorithmType,
|
||||
ScoringCalculatorType scoringCalculatorType,
|
||||
const mcts::MCTSConfig& mctsConfig);
|
||||
const mcts::MCTSConfig& mctsConfig,
|
||||
bool scoreMoveFollowUps = true);
|
||||
~ShardokAIClient() = default;
|
||||
|
||||
[[nodiscard]] auto GetPlayerId() const -> PlayerId { return playerId; }
|
||||
|
||||
@@ -571,6 +571,8 @@ std::unique_ptr<ShardokAIClient> AiBattleSimulator::CreateAIClient(
|
||||
const ScoringCalculatorType scoringType =
|
||||
ConvertScoringCalculatorType(playerConfig.scoring_calculator());
|
||||
const auto mctsConfig = BuildMCTSConfig(playerConfig, config_.random_seed(), playerId);
|
||||
const bool scoreMoveFollowUps =
|
||||
!playerConfig.has_score_move_follow_ups() || playerConfig.score_move_follow_ups();
|
||||
|
||||
return ai_testing_common::AIClientFactory::Create(
|
||||
playerId,
|
||||
@@ -580,7 +582,8 @@ std::unique_ptr<ShardokAIClient> AiBattleSimulator::CreateAIClient(
|
||||
algorithmType,
|
||||
scoringType,
|
||||
true,
|
||||
mctsConfig);
|
||||
mctsConfig,
|
||||
scoreMoveFollowUps);
|
||||
}
|
||||
|
||||
BattleResult AiBattleSimulator::RunSetupPhase(
|
||||
|
||||
@@ -17,7 +17,8 @@ auto AIClientFactory::Create(
|
||||
AIAlgorithmType algorithmType,
|
||||
ScoringCalculatorType scoringType,
|
||||
bool isAllAiBattle,
|
||||
mcts::MCTSConfig mctsConfig) -> std::unique_ptr<ShardokAIClient> {
|
||||
mcts::MCTSConfig mctsConfig,
|
||||
const bool scoreMoveFollowUps) -> std::unique_ptr<ShardokAIClient> {
|
||||
return std::make_unique<ShardokAIClient>(
|
||||
playerId,
|
||||
isDefender,
|
||||
@@ -26,7 +27,8 @@ auto AIClientFactory::Create(
|
||||
settings,
|
||||
algorithmType,
|
||||
scoringType,
|
||||
mctsConfig);
|
||||
mctsConfig,
|
||||
scoreMoveFollowUps);
|
||||
}
|
||||
|
||||
} // namespace shardok::ai_testing_common
|
||||
|
||||
@@ -62,7 +62,8 @@ public:
|
||||
AIAlgorithmType algorithmType = AIAlgorithmType::ITERATIVE_DEEPENING,
|
||||
ScoringCalculatorType scoringType = ScoringCalculatorType::STANDARD,
|
||||
bool isAllAiBattle = false,
|
||||
mcts::MCTSConfig mctsConfig = mcts::MCTSConfig{}) -> std::unique_ptr<ShardokAIClient>;
|
||||
mcts::MCTSConfig mctsConfig = mcts::MCTSConfig{},
|
||||
bool scoreMoveFollowUps = true) -> std::unique_ptr<ShardokAIClient>;
|
||||
};
|
||||
|
||||
} // namespace ai_testing_common
|
||||
|
||||
@@ -126,6 +126,10 @@ message PlayerConfig {
|
||||
|
||||
// MCTS settings, used only when ai_algorithm is MCTS.
|
||||
MctsConfig mcts_config = 4;
|
||||
|
||||
// Whether iterative deepening should add leaf-score bonuses for move follow-up actions.
|
||||
// Defaults to true, matching production behavior.
|
||||
optional bool score_move_follow_ups = 5;
|
||||
}
|
||||
|
||||
// Complete battle configuration
|
||||
|
||||
Reference in New Issue
Block a user