2015-02-17 11:14:50 -08:00
|
|
|
package magic.headless;
|
|
|
|
|
|
|
|
import magic.exception.UndoClickedException;
|
|
|
|
import magic.ai.MagicAI;
|
|
|
|
import magic.model.ILogBookListener;
|
|
|
|
import magic.model.MagicCardList;
|
|
|
|
import magic.model.MagicGame;
|
|
|
|
import magic.model.MagicLogBookEvent;
|
|
|
|
import magic.model.MagicPlayer;
|
|
|
|
import magic.model.MagicSource;
|
|
|
|
import magic.model.event.MagicEvent;
|
|
|
|
import magic.model.event.MagicPriorityEvent;
|
|
|
|
import magic.model.target.MagicTarget;
|
|
|
|
import magic.model.target.MagicTargetNone;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.concurrent.BlockingQueue;
|
|
|
|
import java.util.concurrent.SynchronousQueue;
|
|
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
import magic.model.IGameController;
|
|
|
|
import magic.model.MagicColor;
|
|
|
|
import magic.model.MagicManaCost;
|
|
|
|
import magic.model.MagicSubType;
|
|
|
|
import magic.model.choice.MagicPlayChoiceResult;
|
|
|
|
|
|
|
|
public class HeadlessGameController implements IGameController, ILogBookListener {
|
|
|
|
|
|
|
|
private long MAX_TEST_MODE_DURATION=10000;
|
|
|
|
private final MagicGame game;
|
|
|
|
|
|
|
|
/** Fully artificial test game. */
|
|
|
|
public HeadlessGameController(final MagicGame aGame) {
|
|
|
|
game = aGame;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setMaxTestGameDuration(final long duration) {
|
|
|
|
MAX_TEST_MODE_DURATION = duration;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void showMessage(final MagicSource source, final String message) {
|
|
|
|
System.out.println(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Object[] getArtificialNextEventChoiceResults(final MagicEvent event) {
|
|
|
|
//dynamically get the AI based on the player's index
|
|
|
|
final MagicPlayer player = event.getPlayer();
|
|
|
|
final MagicAI ai = game.getDuel().getAIs()[player.getIndex()];
|
|
|
|
return ai.findNextEventChoiceResults(game, player);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void executeNextEventWithChoices(final MagicEvent event) {
|
|
|
|
game.executeNextEvent(getArtificialNextEventChoiceResults(event));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Main game loop runs on separate thread.
|
|
|
|
*/
|
|
|
|
public void runGame() {
|
|
|
|
final long startTime=System.currentTimeMillis();
|
2015-02-17 18:30:40 -08:00
|
|
|
while (true) {
|
|
|
|
if (game.isFinished()) {
|
2015-02-17 18:47:29 -08:00
|
|
|
game.advanceDuel();
|
2015-02-17 18:30:40 -08:00
|
|
|
break;
|
2015-02-17 11:14:50 -08:00
|
|
|
} else {
|
|
|
|
executeNextEventOrPhase();
|
2015-02-17 18:30:40 -08:00
|
|
|
if (System.currentTimeMillis() - startTime > MAX_TEST_MODE_DURATION) {
|
|
|
|
System.err.println("WARNING. Max time for AI game exceeded");
|
|
|
|
break;
|
2015-02-17 11:14:50 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void executeNextEventOrPhase() {
|
|
|
|
if (game.hasNextEvent()) {
|
|
|
|
executeNextEvent();
|
|
|
|
} else {
|
|
|
|
game.executePhase();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void executeNextEvent() {
|
|
|
|
final MagicEvent event=game.getNextEvent();
|
|
|
|
if (event instanceof MagicPriorityEvent) {
|
|
|
|
game.logMessages();
|
|
|
|
}
|
|
|
|
if (event.hasChoice()) {
|
|
|
|
executeNextEventWithChoices(event);
|
|
|
|
} else {
|
|
|
|
game.executeNextEvent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2015-02-17 18:19:26 -08:00
|
|
|
public void messageLogged(final MagicLogBookEvent ev) {
|
|
|
|
//do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void enableForwardButton() {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void disableActionButton(final boolean thinking) {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void pause(final int t) {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void waitForInput() throws UndoClickedException {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isActionClicked() {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public <T> T getChoiceClicked() {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setSourceCardDefinition(final MagicSource source) {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void focusViewers(final int handGraveyard) {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void clearCards() {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void showCards(final MagicCardList cards) {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void clearValidChoices() {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setValidChoices(final Set<?> aValidChoices,final boolean aCombatChoice) {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void updateGameView() {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
2015-02-17 11:14:50 -08:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public MagicSubType getLandSubTypeChoice(final MagicSource source) throws UndoClickedException {
|
2015-02-17 18:15:58 -08:00
|
|
|
throw new UnsupportedOperationException();
|
2015-02-17 11:14:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean getPayBuyBackCostChoice(final MagicSource source, final String costText) throws UndoClickedException {
|
2015-02-17 18:15:58 -08:00
|
|
|
throw new UnsupportedOperationException();
|
2015-02-17 11:14:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public MagicColor getColorChoice(final MagicSource source) throws UndoClickedException {
|
2015-02-17 18:15:58 -08:00
|
|
|
throw new UnsupportedOperationException();
|
2015-02-17 11:14:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getMultiKickerCountChoice(
|
|
|
|
final MagicSource source,
|
|
|
|
final MagicManaCost cost,
|
|
|
|
final int maximumCount,
|
|
|
|
final String name) throws UndoClickedException {
|
2015-02-17 18:15:58 -08:00
|
|
|
throw new UnsupportedOperationException();
|
2015-02-17 11:14:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getSingleKickerCountChoice(
|
|
|
|
final MagicSource source,
|
|
|
|
final MagicManaCost cost,
|
|
|
|
final String name) throws UndoClickedException {
|
2015-02-17 18:15:58 -08:00
|
|
|
throw new UnsupportedOperationException();
|
2015-02-17 11:14:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean getMayChoice(final MagicSource source, final String description) throws UndoClickedException {
|
2015-02-17 18:15:58 -08:00
|
|
|
throw new UnsupportedOperationException();
|
2015-02-17 11:14:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean getTakeMulliganChoice(
|
|
|
|
final MagicSource source,
|
|
|
|
final MagicPlayer player) throws UndoClickedException {
|
2015-02-17 18:15:58 -08:00
|
|
|
throw new UnsupportedOperationException();
|
2015-02-17 11:14:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getModeChoice(final MagicSource source, final List<Integer> availableModes) throws UndoClickedException {
|
2015-02-17 18:15:58 -08:00
|
|
|
throw new UnsupportedOperationException();
|
2015-02-17 11:14:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getPayManaCostXChoice(final MagicSource source, final int maximumX) throws UndoClickedException {
|
2015-02-17 18:15:58 -08:00
|
|
|
throw new UnsupportedOperationException();
|
2015-02-17 11:14:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public MagicPlayChoiceResult getPlayChoice(final MagicSource source, final List<MagicPlayChoiceResult> results) throws UndoClickedException {
|
2015-02-17 18:15:58 -08:00
|
|
|
throw new UnsupportedOperationException();
|
2015-02-17 11:14:50 -08:00
|
|
|
}
|
|
|
|
}
|