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