AI: improved performance on too many possible targets (fix game freezes and server crashes - see #9539, #9438, #9518, related to #11285, #5023);

This commit is contained in:
Oleg Agafonov 2025-08-10 02:16:18 +04:00
parent 384ce67cc3
commit 2833460e59
10 changed files with 397 additions and 234 deletions

View file

@ -219,6 +219,7 @@ public class ComputerPlayer6 extends ComputerPlayer {
}
// Condition to stop deeper simulation
if (SimulationNode2.nodeCount > MAX_SIMULATED_NODES_PER_ERROR) {
// how-to fix: make sure you are disabled debug mode by COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS = false
throw new IllegalStateException("AI ERROR: too much nodes (possible actions)");
}
if (depth <= 0
@ -501,7 +502,7 @@ public class ComputerPlayer6 extends ComputerPlayer {
}
logger.warn("Possible freeze chain:");
if (root != null && chain.isEmpty()) {
logger.warn(" - unknown use case"); // maybe can't finish any calc, maybe related to target options, I don't know
logger.warn(" - unknown use case (too many possible targets?)"); // maybe can't finish any calc, maybe related to target options, I don't know
}
chain.forEach(s -> {
logger.warn(" - " + s);
@ -642,7 +643,7 @@ public class ComputerPlayer6 extends ComputerPlayer {
return "unknown";
})
.collect(Collectors.joining(", "));
logger.info(String.format("Sim Prio [%d] -> with choices (TODO): [%d]<diff %s> (%s)",
logger.info(String.format("Sim Prio [%d] -> with possible choices: [%d]<diff %s> (%s)",
depth,
currentNode.getDepth(),
printDiffScore(currentScore - prevScore),
@ -651,14 +652,18 @@ public class ComputerPlayer6 extends ComputerPlayer {
} else if (!currentNode.getChoices().isEmpty()) {
// ON CHOICES
String choicesInfo = String.join(", ", currentNode.getChoices());
logger.info(String.format("Sim Prio [%d] -> with choices (TODO): [%d]<diff %s> (%s)",
logger.info(String.format("Sim Prio [%d] -> with possible choices (must not see that code): [%d]<diff %s> (%s)",
depth,
currentNode.getDepth(),
printDiffScore(currentScore - prevScore),
choicesInfo)
);
} else {
throw new IllegalStateException("AI CALC ERROR: unknown calculation result (no abilities, no targets, no choices)");
logger.info(String.format("Sim Prio [%d] -> with do nothing: [%d]<diff %s>",
depth,
currentNode.getDepth(),
printDiffScore(currentScore - prevScore))
);
}
}
}

View file

@ -318,6 +318,7 @@ public final class SimulatedPlayer2 extends ComputerPlayer {
Ability ability = source.copy();
List<Ability> options = getPlayableOptions(ability, game);
if (options.isEmpty()) {
// no options - activate as is
logger.debug("simulating -- triggered ability:" + ability);
game.getStack().push(game, new StackAbility(ability, playerId));
if (ability.activate(game, false) && ability.isUsesStack()) {
@ -326,6 +327,8 @@ public final class SimulatedPlayer2 extends ComputerPlayer {
game.applyEffects();
game.getPlayers().resetPassed();
} else {
// many options - activate and add to sims tree
// TODO: AI run all sims, but do not use best option for triggers yet
SimulationNode2 parent = (SimulationNode2) game.getCustomData();
int depth = parent.getDepth() - 1;
if (depth == 0) {
@ -350,7 +353,7 @@ public final class SimulatedPlayer2 extends ComputerPlayer {
logger.debug("simulating -- node #:" + SimulationNode2.getCount() + " triggered ability option");
for (Target target : ability.getTargets()) {
for (UUID targetId : target.getTargets()) {
newNode.getTargets().add(targetId); // save for info only (real targets in newNode.ability already)
newNode.getTargets().add(targetId); // save for info only (real targets in newNode.game.stack already)
}
}
parent.children.add(newNode);