Add a somewhat hidden option in the UI to turn on simulation via a context menu on the AI radio button on desktop.

This allows choosing the AI mode without recompiling and also allows things like making a non-simulation AI play a simulation AI.
This commit is contained in:
Myrd
2015-02-07 18:32:02 +00:00
parent 4e1706ad22
commit 859a853499
7 changed files with 65 additions and 25 deletions

View File

@@ -100,20 +100,23 @@ import forge.util.MyRandom;
* @version $Id$ * @version $Id$
*/ */
public class AiController { public class AiController {
private static boolean USE_SIMULATION = false;
private final Player player; private final Player player;
private final Game game; private final Game game;
private final AiCardMemory memory; private final AiCardMemory memory;
public boolean bCheatShuffle; private boolean cheatShuffle;
private boolean useSimulation;
private SpellAbilityPicker simPicker; private SpellAbilityPicker simPicker;
public boolean canCheatShuffle() { public boolean canCheatShuffle() {
return bCheatShuffle; return cheatShuffle;
} }
public void allowCheatShuffle(boolean canCheatShuffle) { public void allowCheatShuffle(boolean canCheatShuffle) {
this.bCheatShuffle = canCheatShuffle; this.cheatShuffle = canCheatShuffle;
}
public void setUseSimulation(boolean value) {
this.useSimulation = value;
} }
public Game getGame() { public Game getGame() {
@@ -1213,7 +1216,7 @@ public class AiController {
if (all == null || all.isEmpty()) if (all == null || all.isEmpty())
return null; return null;
if (USE_SIMULATION) { if (useSimulation) {
return simPicker.chooseSpellAbilityToPlay(getOriginalAndAltCostAbilities(all), skipCounter); return simPicker.chooseSpellAbilityToPlay(getOriginalAndAltCostAbilities(all), skipCounter);
} }

View File

@@ -1,5 +1,7 @@
package forge.ai; package forge.ai;
import java.util.Map;
import forge.LobbyPlayer; import forge.LobbyPlayer;
import forge.game.Game; import forge.game.Game;
import forge.game.player.IGameEntitiesFactory; import forge.game.player.IGameEntitiesFactory;
@@ -7,19 +9,23 @@ import forge.game.player.Player;
import forge.game.player.PlayerController; import forge.game.player.PlayerController;
public class LobbyPlayerAi extends LobbyPlayer implements IGameEntitiesFactory { public class LobbyPlayerAi extends LobbyPlayer implements IGameEntitiesFactory {
public LobbyPlayerAi(String name) {
super(name);
}
private String aiProfile = ""; private String aiProfile = "";
private boolean rotateProfileEachGame; private boolean rotateProfileEachGame;
private boolean allowCheatShuffle; private boolean allowCheatShuffle;
private boolean useSimulation;
public LobbyPlayerAi(String name, Map<String, String> options) {
super(name);
if (options != null && "True".equals(options.get("UseSimulation"))) {
this.useSimulation = true;
}
}
public boolean isAllowCheatShuffle() { public boolean isAllowCheatShuffle() {
return allowCheatShuffle; return allowCheatShuffle;
} }
public void setAllowCheatShuffle(boolean allowCheatShuffle) { public void setAllowCheatShuffle(boolean allowCheatShuffle) {
this.allowCheatShuffle = allowCheatShuffle; this.allowCheatShuffle = allowCheatShuffle;
} }
@@ -38,6 +44,7 @@ public class LobbyPlayerAi extends LobbyPlayer implements IGameEntitiesFactory {
private PlayerControllerAi createControllerFor(Player ai) { private PlayerControllerAi createControllerFor(Player ai) {
PlayerControllerAi result = new PlayerControllerAi(ai.getGame(), ai, this); PlayerControllerAi result = new PlayerControllerAi(ai.getGame(), ai, this);
result.setUseSimulation(useSimulation);
result.allowCheatShuffle(allowCheatShuffle); result.allowCheatShuffle(allowCheatShuffle);
return result; return result;
} }

View File

@@ -74,6 +74,9 @@ public class PlayerControllerAi extends PlayerController {
brains.allowCheatShuffle(value); brains.allowCheatShuffle(value);
} }
public void setUseSimulation(boolean value) {
brains.setUseSimulation(value);
}
public SpellAbility getAbilityToPlay(List<SpellAbility> abilities, ITriggerEvent triggerEvent) { public SpellAbility getAbilityToPlay(List<SpellAbility> abilities, ITriggerEvent triggerEvent) {
if (abilities.size() == 0) { if (abilities.size() == 0) {

View File

@@ -228,7 +228,7 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
for (final int i : view.getParticipants()) { for (final int i : view.getParticipants()) {
String name = view.getPlayerName(i); String name = view.getPlayerName(i);
LobbyPlayer lobbyPlayer = view.isPlayerAI(i) LobbyPlayer lobbyPlayer = view.isPlayerAI(i)
? GamePlayerUtil.createAiPlayer(name, view.getPlayerAvatar(i)) ? GamePlayerUtil.createAiPlayer(name, view.getPlayerAvatar(i), view.getAiOptions(i))
: GamePlayerUtil.getGuiPlayer(name, i); : GamePlayerUtil.getGuiPlayer(name, i);
RegisteredPlayer rp = view.getDeckChooser(i).getPlayer(); RegisteredPlayer rp = view.getDeckChooser(i).getPlayer();

View File

@@ -12,14 +12,18 @@ import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.Vector; import java.util.Vector;
import javax.swing.ButtonGroup; import javax.swing.ButtonGroup;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.ScrollPaneConstants; import javax.swing.ScrollPaneConstants;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
@@ -469,6 +473,15 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
return playerPanels.get(playernum).isAi(); return playerPanels.get(playernum).isAi();
} }
public Map<String, String> getAiOptions(int playernum) {
if (playerPanels.get(playernum).isSimulatedAi()) {
Map<String, String> options = new HashMap<String, String>();
options.put("UseSimulation", "True");
return options;
}
return null;
}
public int getNumPlayers() { public int getNumPlayers() {
return activePlayersNum; return activePlayersNum;
} }
@@ -506,6 +519,7 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
private final FTextField txtPlayerName = new FTextField.Builder().text("Player name").build(); private final FTextField txtPlayerName = new FTextField.Builder().text("Player name").build();
private FRadioButton radioHuman; private FRadioButton radioHuman;
private FRadioButton radioAi; private FRadioButton radioAi;
private JCheckBoxMenuItem radioAiUseSimulation;
private FComboBoxWrapper<Object> teamComboBox = new FComboBoxWrapper<Object>(); private FComboBoxWrapper<Object> teamComboBox = new FComboBoxWrapper<Object>();
private FComboBoxWrapper<Object> aeTeamComboBox = new FComboBoxWrapper<Object>(); private FComboBoxWrapper<Object> aeTeamComboBox = new FComboBoxWrapper<Object>();
@@ -559,7 +573,7 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
this.add(radioAi, "wrap"); this.add(radioAi, "wrap");
this.add(newLabel("Team:"), "w 40px, h 30px"); this.add(newLabel("Team:"), "w 40px, h 30px");
populateTeamsComboBoxes(); populateTeamsComboBoxes();
teamComboBox.addActionListener(teamListener); teamComboBox.addActionListener(teamListener);
aeTeamComboBox.addActionListener(teamListener); aeTeamComboBox.addActionListener(teamListener);
teamComboBox.addTo(this, variantBtnConstraints + ", pushx, growx, gaptop 5px"); teamComboBox.addTo(this, variantBtnConstraints + ", pushx, growx, gaptop 5px");
@@ -742,10 +756,14 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
} }
} }
public Boolean isAi() { public boolean isAi() {
return radioAi.isSelected(); return radioAi.isSelected();
} }
public boolean isSimulatedAi() {
return radioAi.isSelected() && radioAiUseSimulation.isSelected();
}
public void setVanguardButtonText(String text) { public void setVanguardButtonText(String text) {
vgdSelectorBtn.setText(text); vgdSelectorBtn.setText(text);
} }
@@ -906,6 +924,10 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
private void createPlayerTypeOptions() { private void createPlayerTypeOptions() {
radioHuman = new FRadioButton("Human", index == 0); radioHuman = new FRadioButton("Human", index == 0);
radioAi = new FRadioButton("AI", index != 0); radioAi = new FRadioButton("AI", index != 0);
JPopupMenu menu = new JPopupMenu();
radioAiUseSimulation = new JCheckBoxMenuItem("Use Simulation");
menu.add(radioAiUseSimulation);
radioAi.setComponentPopupMenu(menu);
radioHuman.addMouseListener(radioMouseAdapter); radioHuman.addMouseListener(radioMouseAdapter);
radioAi.addMouseListener(radioMouseAdapter); radioAi.addMouseListener(radioMouseAdapter);
@@ -1382,15 +1404,15 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
/** update vanguard list. */ /** update vanguard list. */
public void updateVanguardList(int playerIndex) { public void updateVanguardList(int playerIndex) {
FList<Object> vgdList = getVanguardLists().get(playerIndex); FList<Object> vgdList = getVanguardLists().get(playerIndex);
Object lastSelection = vgdList.getSelectedValue(); Object lastSelection = vgdList.getSelectedValue();
vgdList.setListData(isPlayerAI(playerIndex) ? aiListData : humanListData); vgdList.setListData(isPlayerAI(playerIndex) ? aiListData : humanListData);
if (null != lastSelection) { if (null != lastSelection) {
vgdList.setSelectedValue(lastSelection, true); vgdList.setSelectedValue(lastSelection, true);
} }
if (-1 == vgdList.getSelectedIndex()) { if (-1 == vgdList.getSelectedIndex()) {
vgdList.setSelectedIndex(0); vgdList.setSelectedIndex(0);
} }
} }
} }

View File

@@ -29,8 +29,8 @@ public class GameSimulatorTest extends TestCase {
private Game initAndCreateGame() { private Game initAndCreateGame() {
List<RegisteredPlayer> players = Lists.newArrayList(); List<RegisteredPlayer> players = Lists.newArrayList();
Deck d1 = new Deck(); Deck d1 = new Deck();
players.add(new RegisteredPlayer(d1).setPlayer(new LobbyPlayerAi("p2"))); players.add(new RegisteredPlayer(d1).setPlayer(new LobbyPlayerAi("p2", null)));
players.add(new RegisteredPlayer(d1).setPlayer(new LobbyPlayerAi("p1"))); players.add(new RegisteredPlayer(d1).setPlayer(new LobbyPlayerAi("p1", null)));
GameRules rules = new GameRules(GameType.Constructed); GameRules rules = new GameRules(GameType.Constructed);
Match match = new Match(rules, players); Match match = new Match(rules, players);
Game game = new Game(players, rules, match); Game game = new Game(players, rules, match);

View File

@@ -1,5 +1,7 @@
package forge.player; package forge.player;
import java.util.Map;
import forge.GuiBase; import forge.GuiBase;
import forge.LobbyPlayer; import forge.LobbyPlayer;
import forge.ai.AiProfileUtil; import forge.ai.AiProfileUtil;
@@ -46,7 +48,10 @@ public final class GamePlayerUtil {
return createAiPlayer(name, avatarCount == 0 ? 0 : MyRandom.getRandom().nextInt(avatarCount)); return createAiPlayer(name, avatarCount == 0 ? 0 : MyRandom.getRandom().nextInt(avatarCount));
} }
public final static LobbyPlayer createAiPlayer(String name, int avatarIndex) { public final static LobbyPlayer createAiPlayer(String name, int avatarIndex) {
LobbyPlayerAi player = new LobbyPlayerAi(name); return createAiPlayer(name, avatarIndex, null);
}
public final static LobbyPlayer createAiPlayer(String name, int avatarIndex, Map<String, String> options) {
LobbyPlayerAi player = new LobbyPlayerAi(name, options);
// TODO: implement specific AI profiles for quest mode. // TODO: implement specific AI profiles for quest mode.
String lastProfileChosen = FModel.getPreferences().getPref(FPref.UI_CURRENT_AI_PROFILE); String lastProfileChosen = FModel.getPreferences().getPref(FPref.UI_CURRENT_AI_PROFILE);