add user setting for AI Timeout

This commit is contained in:
Anthony Calosa
2024-11-14 22:06:23 +08:00
parent e2c37d11e7
commit 8dbb648638
19 changed files with 59 additions and 10 deletions

View File

@@ -967,7 +967,7 @@ public class AiAttackController {
})); }));
} }
CompletableFuture<?>[] futuresArray = futures.toArray(new CompletableFuture<?>[0]); CompletableFuture<?>[] futuresArray = futures.toArray(new CompletableFuture<?>[0]);
CompletableFuture.allOf(futuresArray).completeOnTimeout(null, 5, TimeUnit.SECONDS).join(); CompletableFuture.allOf(futuresArray).completeOnTimeout(null, ai.getTimeout(), TimeUnit.SECONDS).join();
futures.clear(); futures.clear();
if (attackersLeft.isEmpty()) { if (attackersLeft.isEmpty()) {
return aiAggression; return aiAggression;

View File

@@ -1667,7 +1667,7 @@ public class AiController {
} }
//timeout 5 seconds? even the AI don't acquire all, there should be SA to cast if valid //timeout 5 seconds? even the AI don't acquire all, there should be SA to cast if valid
CompletableFuture<?>[] futuresArray = futures.toArray(new CompletableFuture<?>[0]); CompletableFuture<?>[] futuresArray = futures.toArray(new CompletableFuture<?>[0]);
CompletableFuture.allOf(futuresArray).completeOnTimeout(null, 5, TimeUnit.SECONDS).join(); CompletableFuture.allOf(futuresArray).completeOnTimeout(null, player.getTimeout(), TimeUnit.SECONDS).join();
futures.clear(); futures.clear();
if (!spells.isEmpty()) { if (!spells.isEmpty()) {

View File

@@ -215,6 +215,7 @@ public class GameCopier {
private void copyGameState(Game newGame, Player aiPlayer) { private void copyGameState(Game newGame, Player aiPlayer) {
newGame.EXPERIMENTAL_RESTORE_SNAPSHOT = origGame.EXPERIMENTAL_RESTORE_SNAPSHOT; newGame.EXPERIMENTAL_RESTORE_SNAPSHOT = origGame.EXPERIMENTAL_RESTORE_SNAPSHOT;
newGame.AI_TIMEOUT = origGame.AI_TIMEOUT;
newGame.setAge(origGame.getAge()); newGame.setAge(origGame.getAge());
// TODO countersAddedThisTurn // TODO countersAddedThisTurn

View File

@@ -90,6 +90,7 @@ public class Game {
private final GameLog gameLog = new GameLog(); private final GameLog gameLog = new GameLog();
private final Zone stackZone = new Zone(ZoneType.Stack, this); private final Zone stackZone = new Zone(ZoneType.Stack, this);
public int AI_TIMEOUT = 5;
public boolean EXPERIMENTAL_RESTORE_SNAPSHOT = false; public boolean EXPERIMENTAL_RESTORE_SNAPSHOT = false;
// While this is false here, its really set by the Match/Preferences // While this is false here, its really set by the Match/Preferences

View File

@@ -131,6 +131,8 @@ public class Player extends GameEntity implements Comparable<Player> {
private boolean revolt = false; private boolean revolt = false;
private int descended = 0; private int descended = 0;
// AI Timeout
private int aiTimeout = 5;
private List<Card> sacrificedThisTurn = new ArrayList<>(); private List<Card> sacrificedThisTurn = new ArrayList<>();
private List<Card> discardedThisTurn = new ArrayList<>(); private List<Card> discardedThisTurn = new ArrayList<>();
@@ -209,6 +211,7 @@ public class Player extends GameEntity implements Comparable<Player> {
super(id0); super(id0);
game = game0; game = game0;
aiTimeout = game.AI_TIMEOUT;
for (final ZoneType z : Player.ALL_ZONES) { for (final ZoneType z : Player.ALL_ZONES) {
final PlayerZone toPut = z == ZoneType.Battlefield ? new PlayerZoneBattlefield(z, this) : new PlayerZone(z, this); final PlayerZone toPut = z == ZoneType.Battlefield ? new PlayerZoneBattlefield(z, this) : new PlayerZone(z, this);
zones.put(z, toPut); zones.put(z, toPut);
@@ -267,6 +270,10 @@ public class Player extends GameEntity implements Comparable<Player> {
teamNumber = iTeam; teamNumber = iTeam;
} }
public final int getTimeout() {
return aiTimeout;
}
public boolean isArchenemy() { public boolean isArchenemy() {
return getZone(ZoneType.SchemeDeck).size() > 0; //Only the archenemy has schemes. return getZone(ZoneType.SchemeDeck).size() > 0; //Only the archenemy has schemes.
} }

View File

@@ -209,6 +209,7 @@ public enum CSubmenuPreferences implements ICDoc {
initializeMulliganRuleComboBox(); initializeMulliganRuleComboBox();
initializeAiProfilesComboBox(); initializeAiProfilesComboBox();
initializeAiSideboardingModeComboBox(); initializeAiSideboardingModeComboBox();
initializeAiTimeoutComboBox();
initializeSoundSetsComboBox(); initializeSoundSetsComboBox();
initializeMusicSetsComboBox(); initializeMusicSetsComboBox();
initializeStackAdditionsComboBox(); initializeStackAdditionsComboBox();
@@ -415,6 +416,14 @@ public enum CSubmenuPreferences implements ICDoc {
comboBox.addActionListener(actionEvent -> AiProfileUtil.setAiSideboardingMode(AiProfileUtil.AISideboardingMode.normalizedValueOf(comboBox.getSelectedItem()))); comboBox.addActionListener(actionEvent -> AiProfileUtil.setAiSideboardingMode(AiProfileUtil.AISideboardingMode.normalizedValueOf(comboBox.getSelectedItem())));
} }
private void initializeAiTimeoutComboBox() {
final FPref userSetting = FPref.MATCH_AI_TIMEOUT;
final FComboBoxPanel<String> panel = this.view.getAiTimeoutComboBox();
final FComboBox<String> comboBox = createComboBox(new String[] {"5", "10", "60", "120", "240", "300", "600"}, userSetting);
final String selectedItem = this.prefs.getPref(userSetting);
panel.setComboBox(comboBox, selectedItem);
}
private void initializeSoundSetsComboBox() { private void initializeSoundSetsComboBox() {
final FPref userSetting = FPref.UI_CURRENT_SOUND_SET; final FPref userSetting = FPref.UI_CURRENT_SOUND_SET;
final FComboBoxPanel<String> panel = this.view.getSoundSetsComboBoxPanel(); final FComboBoxPanel<String> panel = this.view.getSoundSetsComboBoxPanel();

View File

@@ -135,6 +135,7 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
private final FComboBoxPanel<String> cbpMusicSets = new FComboBoxPanel<>(localizer.getMessage("cbpMusicSets")+":"); private final FComboBoxPanel<String> cbpMusicSets = new FComboBoxPanel<>(localizer.getMessage("cbpMusicSets")+":");
private final FComboBoxPanel<String> cbpAiProfiles = new FComboBoxPanel<>(localizer.getMessage("cbpAiProfiles")+":"); private final FComboBoxPanel<String> cbpAiProfiles = new FComboBoxPanel<>(localizer.getMessage("cbpAiProfiles")+":");
private final FComboBoxPanel<String> cbpAiSideboardingMode = new FComboBoxPanel<>(localizer.getMessage("cbpAiSideboardingMode")+":"); private final FComboBoxPanel<String> cbpAiSideboardingMode = new FComboBoxPanel<>(localizer.getMessage("cbpAiSideboardingMode")+":");
private final FComboBoxPanel<String> cbpAiTimeout = new FComboBoxPanel<>(localizer.getMessage("cbAITimeout")+":");
private final FComboBoxPanel<String> cbpStackAdditions = new FComboBoxPanel<>(localizer.getMessage("cbpStackAdditions")+":"); private final FComboBoxPanel<String> cbpStackAdditions = new FComboBoxPanel<>(localizer.getMessage("cbpStackAdditions")+":");
private final FComboBoxPanel<String> cbpLandPlayed = new FComboBoxPanel<>(localizer.getMessage("cbpLandPlayed")+":"); private final FComboBoxPanel<String> cbpLandPlayed = new FComboBoxPanel<>(localizer.getMessage("cbpLandPlayed")+":");
private final FComboBoxPanel<String> cbpDisplayCurrentCardColors = new FComboBoxPanel<>(localizer.getMessage("cbpDisplayCurrentCardColors")+":"); private final FComboBoxPanel<String> cbpDisplayCurrentCardColors = new FComboBoxPanel<>(localizer.getMessage("cbpDisplayCurrentCardColors")+":");
@@ -245,6 +246,9 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
pnlPrefs.add(cbExperimentalRestore, titleConstraints); pnlPrefs.add(cbExperimentalRestore, titleConstraints);
pnlPrefs.add(new NoteLabel(localizer.getMessage("nlExperimentalRestore")), descriptionConstraints); pnlPrefs.add(new NoteLabel(localizer.getMessage("nlExperimentalRestore")), descriptionConstraints);
pnlPrefs.add(cbpAiTimeout, titleConstraints);
pnlPrefs.add(new NoteLabel(localizer.getMessage("nlAITimeout")), descriptionConstraints);
pnlPrefs.add(cbFilteredHands, titleConstraints); pnlPrefs.add(cbFilteredHands, titleConstraints);
pnlPrefs.add(new NoteLabel(localizer.getMessage("nlFilteredHands")), descriptionConstraints); pnlPrefs.add(new NoteLabel(localizer.getMessage("nlFilteredHands")), descriptionConstraints);
@@ -790,6 +794,10 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
return cbpAiSideboardingMode; return cbpAiSideboardingMode;
} }
public FComboBoxPanel<String> getAiTimeoutComboBox() {
return cbpAiTimeout;
}
public FComboBoxPanel<String> getCbpStackAdditionsComboBoxPanel() { public FComboBoxPanel<String> getCbpStackAdditionsComboBoxPanel() {
return cbpStackAdditions; return cbpStackAdditions;
} }

View File

@@ -47,6 +47,7 @@ public class SimulationTest {
Game game = new Game(players, rules, match); Game game = new Game(players, rules, match);
game.setAge(GameStage.Play); game.setAge(GameStage.Play);
game.EXPERIMENTAL_RESTORE_SNAPSHOT = false; game.EXPERIMENTAL_RESTORE_SNAPSHOT = false;
game.AI_TIMEOUT = FModel.getPreferences().getPrefInt(FPref.MATCH_AI_TIMEOUT);
return game; return game;
} }

View File

@@ -244,6 +244,10 @@ public class SettingsPage extends TabPage<SettingsScreen> {
Forge.getLocalizer().getMessage("cbExperimentalRestore"), Forge.getLocalizer().getMessage("cbExperimentalRestore"),
Forge.getLocalizer().getMessage("nlExperimentalRestore")), Forge.getLocalizer().getMessage("nlExperimentalRestore")),
1); 1);
lstSettings.addItem(new CustomSelectSetting(FPref.MATCH_AI_TIMEOUT, Forge.getLocalizer().getMessage("cbAITimeout"),
Forge.getLocalizer().getMessage("nlAITimeout"),
Lists.newArrayList("5", "10", "60", "120", "240", "300", "600")),
1);
lstSettings.addItem(new BooleanSetting(FPref.FILTERED_HANDS, lstSettings.addItem(new BooleanSetting(FPref.FILTERED_HANDS,
Forge.getLocalizer().getMessage("cbFilteredHands"), Forge.getLocalizer().getMessage("cbFilteredHands"),
Forge.getLocalizer().getMessage("nlFilteredHands")), Forge.getLocalizer().getMessage("nlFilteredHands")),

View File

@@ -3476,3 +3476,5 @@ lblSellable=Verkaufbar
lblAutoSellable=Autoverkauf lblAutoSellable=Autoverkauf
lblNonSellable=Kein Verkauf lblNonSellable=Kein Verkauf
lblPromptAutoSell=Aufforderung zum Autoverkauf lblPromptAutoSell=Aufforderung zum Autoverkauf
cbAITimeout=AI Time-out
nlAITimeout=Zeitüberschreitung in Sekunden für AI, wenn die zu spielenden Zauber berechnet und Angreifer deklariert werden

View File

@@ -3195,3 +3195,5 @@ lblSellable=Sellable
lblAutoSellable=Auto-Sell lblAutoSellable=Auto-Sell
lblNonSellable=No-Sell lblNonSellable=No-Sell
lblPromptAutoSell=Prompt for auto sell lblPromptAutoSell=Prompt for auto sell
cbAITimeout=AI Timeout
nlAITimeout=Time-out in seconds for AI when computing for spells to play and declaring attackers

View File

@@ -3483,3 +3483,5 @@ lblSellable=Vendible
lblAutoSellable=Venta automática lblAutoSellable=Venta automática
lblNonSellable=Sin venta lblNonSellable=Sin venta
lblPromptAutoSell=Solicitar venta automática lblPromptAutoSell=Solicitar venta automática
cbAITimeout=AI Se acabó el tiempo
nlAITimeout=Tiempo de espera en segundos para AI al calcular los hechizos a jugar y declarar atacantes

View File

@@ -3484,3 +3484,5 @@ lblSellable=Vendable
lblAutoSellable=Vente automatique lblAutoSellable=Vente automatique
lblNonSellable=Pas de vente lblNonSellable=Pas de vente
lblPromptAutoSell=Invite pour la vente automatique lblPromptAutoSell=Invite pour la vente automatique
cbAITimeout=AI Temps mort
nlAITimeout=Délai d'attente en secondes pour AI lors du calcul des sorts à jouer et de la déclaration des attaquants

View File

@@ -3482,3 +3482,5 @@ lblSellable=Vendibile
lblAutoSellable=Vendita automatica lblAutoSellable=Vendita automatica
lblNonSellable=Nessuna vendita lblNonSellable=Nessuna vendita
lblPromptAutoSell=Richiesta di vendita auto lblPromptAutoSell=Richiesta di vendita auto
cbAITimeout=AI Tempo scaduto
nlAITimeout=Timeout in secondi per AI durante il calcolo degli incantesimi da giocare e la dichiarazione degli attaccanti

View File

@@ -3478,3 +3478,5 @@ lblSellable=販売可能
lblAutoSellable=自動販売 lblAutoSellable=自動販売
lblNonSellable=売りません lblNonSellable=売りません
lblPromptAutoSell=自動車販売のプロンプト lblPromptAutoSell=自動車販売のプロンプト
cbAITimeout=AI タイムアウト
nlAITimeout=プレイする呪文を計算し、攻撃者を宣言するときの AI のタイムアウト (秒単位)

View File

@@ -3568,3 +3568,5 @@ lblSellable=Vendável
lblAutoSellable=Venda automática lblAutoSellable=Venda automática
lblNonSellable=Não vender lblNonSellable=Não vender
lblPromptAutoSell=Solicitação de venda automática lblPromptAutoSell=Solicitação de venda automática
cbAITimeout=AI Tempo esgotado
nlAITimeout=Tempo limite em segundos para AI ao calcular feitiços para jogar e declarar atacantes

View File

@@ -3469,3 +3469,5 @@ lblSellable=可出售
lblAutoSellable=自动销售 lblAutoSellable=自动销售
lblNonSellable=不卖 lblNonSellable=不卖
lblPromptAutoSell=提示汽车出售 lblPromptAutoSell=提示汽车出售
cbAITimeout=AI 暂停
nlAITimeout=计算要播放的咒语并宣布攻击者时AI 超时(以秒为单位)

View File

@@ -155,6 +155,7 @@ public class HostedMatch {
game = match.createGame(); game = match.createGame();
game.EXPERIMENTAL_RESTORE_SNAPSHOT = FModel.getPreferences().getPrefBoolean(FPref.MATCH_EXPERIMENTAL_RESTORE); game.EXPERIMENTAL_RESTORE_SNAPSHOT = FModel.getPreferences().getPrefBoolean(FPref.MATCH_EXPERIMENTAL_RESTORE);
game.AI_TIMEOUT = FModel.getPreferences().getPrefInt(FPref.MATCH_AI_TIMEOUT);
StaticData.instance().setSourceImageForClone(FModel.getPreferences().getPrefBoolean(FPref.UI_CLONE_MODE_SOURCE)); StaticData.instance().setSourceImageForClone(FModel.getPreferences().getPrefBoolean(FPref.UI_CLONE_MODE_SOURCE));

View File

@@ -205,6 +205,7 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
MATCH_AI_SIDEBOARDING_MODE("Human For AI"), MATCH_AI_SIDEBOARDING_MODE("Human For AI"),
MATCH_EXPERIMENTAL_RESTORE("false"), MATCH_EXPERIMENTAL_RESTORE("false"),
MATCH_AI_TIMEOUT("5"),
ENFORCE_DECK_LEGALITY ("true"), ENFORCE_DECK_LEGALITY ("true"),
PERFORMANCE_MODE ("false"), PERFORMANCE_MODE ("false"),
FILTERED_HANDS ("false"), FILTERED_HANDS ("false"),