PlayerController class divided in 2 subclasses - one for human, other for AI

This commit is contained in:
Maxmtg
2013-01-27 08:00:20 +00:00
parent 469e40bdca
commit f61d63ccbe
7 changed files with 322 additions and 77 deletions

2
.gitattributes vendored
View File

@@ -13917,6 +13917,8 @@ src/main/java/forge/game/player/HumanPlayer.java svneol=native#text/plain
src/main/java/forge/game/player/LobbyPlayer.java -text src/main/java/forge/game/player/LobbyPlayer.java -text
src/main/java/forge/game/player/Player.java svneol=native#text/plain src/main/java/forge/game/player/Player.java svneol=native#text/plain
src/main/java/forge/game/player/PlayerController.java -text src/main/java/forge/game/player/PlayerController.java -text
src/main/java/forge/game/player/PlayerControllerAi.java -text
src/main/java/forge/game/player/PlayerControllerHuman.java -text
src/main/java/forge/game/player/PlayerOutcome.java -text src/main/java/forge/game/player/PlayerOutcome.java -text
src/main/java/forge/game/player/PlayerStatistics.java -text src/main/java/forge/game/player/PlayerStatistics.java -text
src/main/java/forge/game/player/PlayerType.java svneol=native#text/plain src/main/java/forge/game/player/PlayerType.java svneol=native#text/plain

View File

@@ -29,8 +29,6 @@ import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.game.GameState; import forge.game.GameState;
import forge.game.ai.AiController; import forge.game.ai.AiController;
import forge.game.ai.AiInputBlock;
import forge.game.ai.AiInputCommon;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.util.Aggregates; import forge.util.Aggregates;
@@ -46,7 +44,7 @@ import forge.util.MyRandom;
*/ */
public class AIPlayer extends Player { public class AIPlayer extends Player {
private final AiController brains; private final PlayerControllerAi controller;
/** /**
* <p> * <p>
* Constructor for AIPlayer. * Constructor for AIPlayer.
@@ -57,12 +55,12 @@ public class AIPlayer extends Player {
* a {@link java.lang.String} object. * a {@link java.lang.String} object.
*/ */
public AIPlayer(final LobbyPlayer player, final GameState game) { public AIPlayer(final LobbyPlayer player, final GameState game) {
super(player, game, new PlayerController(game)); super(player, game);
brains = new AiController(this, game); controller = new PlayerControllerAi(game, this);
PlayerController pc = getController(); }
pc.setDefaultInput(new AiInputCommon(brains));
pc.setBlockInput(new AiInputBlock(game, this)); public AiController getAi() {
pc.setCleanupInput(pc.getDefaultInput()); return controller.getAi();
} }
@@ -244,4 +242,13 @@ public class AIPlayer extends Player {
public PlayerType getType() { public PlayerType getType() {
return PlayerType.COMPUTER; return PlayerType.COMPUTER;
} }
/* (non-Javadoc)
* @see forge.game.player.Player#getController()
*/
@Override
public PlayerController getController() {
return controller;
}
} // end AIPlayer class } // end AIPlayer class

View File

@@ -24,9 +24,6 @@ import forge.Card;
import forge.Singletons; import forge.Singletons;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.control.input.Input; import forge.control.input.Input;
import forge.control.input.InputBlock;
import forge.control.input.InputCleanup;
import forge.control.input.InputPassPriority;
import forge.game.GameType; import forge.game.GameType;
import forge.game.GameState; import forge.game.GameState;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
@@ -44,6 +41,7 @@ import forge.quest.bazaar.QuestItemType;
* @version $Id$ * @version $Id$
*/ */
public class HumanPlayer extends Player { public class HumanPlayer extends Player {
private PlayerControllerHuman controller;
/** /**
* <p> * <p>
@@ -54,10 +52,9 @@ public class HumanPlayer extends Player {
* a {@link java.lang.String} object. * a {@link java.lang.String} object.
*/ */
public HumanPlayer(final LobbyPlayer player, GameState game) { public HumanPlayer(final LobbyPlayer player, GameState game) {
super(player, game, new PlayerController(game)); super(player, game);
getController().setDefaultInput(new InputPassPriority());
getController().setBlockInput(new InputBlock(this)); controller = new PlayerControllerHuman(game, this);
getController().setCleanupInput(new InputCleanup(game));
} }
// ////////////// // //////////////
@@ -78,6 +75,8 @@ public class HumanPlayer extends Player {
return true; return true;
} }
/** /**
* <p> * <p>
* isComputer. * isComputer.
@@ -223,4 +222,12 @@ public class HumanPlayer extends Player {
} }
return newHand; return newHand;
} }
/* (non-Javadoc)
* @see forge.game.player.Player#getController()
*/
@Override
public PlayerController getController() {
return controller;
}
} // end HumanPlayer class } // end HumanPlayer class

View File

@@ -157,8 +157,6 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
ZoneType.Sideboard)); ZoneType.Sideboard));
private final PlayerController controller;
protected final LobbyPlayer lobbyPlayer; protected final LobbyPlayer lobbyPlayer;
protected final GameState game; protected final GameState game;
@@ -178,7 +176,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* @param myPoisonCounters * @param myPoisonCounters
* a int. * a int.
*/ */
public Player(LobbyPlayer lobbyPlayer0, GameState game0, PlayerController pc) { public Player(LobbyPlayer lobbyPlayer0, GameState game0) {
lobbyPlayer = lobbyPlayer0; lobbyPlayer = lobbyPlayer0;
game = game0; game = game0;
for (final ZoneType z : Player.ALL_ZONES) { for (final ZoneType z : Player.ALL_ZONES) {
@@ -188,9 +186,6 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
this.zones.put(z, toPut); this.zones.put(z, toPut);
} }
this.setName(lobbyPlayer.getName()); this.setName(lobbyPlayer.getName());
pc.setPlayer(this);
controller = pc;
} }
public final PlayerStatistics getStats() { public final PlayerStatistics getStats() {
@@ -3079,9 +3074,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
* TODO: Write javadoc for this method. * TODO: Write javadoc for this method.
* @return * @return
*/ */
public PlayerController getController() { public abstract PlayerController getController();
return controller;
}
/** /**
* <p> * <p>

View File

@@ -2,13 +2,13 @@ package forge.game.player;
import java.util.List; import java.util.List;
import forge.Card;
import forge.Singletons; import forge.Singletons;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.control.input.Input; import forge.control.input.Input;
import forge.game.GameState; import forge.game.GameState;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.gui.GuiChoose;
import forge.gui.match.CMatchUI; import forge.gui.match.CMatchUI;
@@ -17,31 +17,22 @@ import forge.gui.match.CMatchUI;
* *
* Handles phase skips for now. * Handles phase skips for now.
*/ */
public class PlayerController { public abstract class PlayerController {
// Should keep some 'Model' of player here. protected final Player player;
// Yet I have little idea of what is model now. protected final GameState game;
private Player player;
private PhaseType autoPassUntil = null; private PhaseType autoPassUntil = null;
private Input defaultInput;
private Input blockInput;
private Input cleanupInput;
private final GameState game; public PlayerController(GameState game0, Player p) {
public final Input getDefaultInput() {
return defaultInput;
}
public PlayerController(GameState game0) {
game = game0; game = game0;
}
void setPlayer(Player p) {
player = p; player = p;
} }
public abstract Input getDefaultInput();
public abstract Input getBlockInput();
public abstract Input getCleanupInput();
/** /**
* TODO: Write javadoc for this method. * TODO: Write javadoc for this method.
@@ -66,37 +57,10 @@ public class PlayerController {
return isLocalPlayer && !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase); return isLocalPlayer && !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase);
} }
void setDefaultInput(Input input) {
defaultInput = input;
}
void setCleanupInput(Input input) {
// TODO Auto-generated method stub
cleanupInput = input;
}
/** /**
* Uses GUI to learn which spell the player (human in our case) would like to play * Uses GUI to learn which spell the player (human in our case) would like to play
*/ */
public SpellAbility getAbilityToPlay(List<SpellAbility> abilities) { public abstract SpellAbility getAbilityToPlay(List<SpellAbility> abilities);
if (abilities.size() == 0) {
return null;
} else if (abilities.size() == 1) {
return abilities.get(0);
} else {
return GuiChoose.oneOrNone("Choose", abilities); // some day network interaction will be here
}
}
/** Input to use when player has to declare blockers */
public Input getBlockInput() {
return blockInput;
}
void setBlockInput(Input blockInput0) {
this.blockInput = blockInput0;
}
/** /**
* TODO: Write javadoc for this method. * TODO: Write javadoc for this method.
@@ -109,11 +73,12 @@ public class PlayerController {
} }
/** /**
* @return the cleanupInput * TODO: Write javadoc for this method.
* @param c
*/ */
public Input getCleanupInput() { public abstract void playFromSuspend(Card c);
return cleanupInput; public abstract boolean playCascade(Card cascadedCard, Card sourceCard);
} public abstract void mayPlaySpellAbilityForFree(SpellAbility copySA);

View File

@@ -0,0 +1,149 @@
package forge.game.player;
import java.util.List;
import forge.Card;
import forge.card.spellability.Spell;
import forge.card.spellability.SpellAbility;
import forge.control.input.Input;
import forge.game.GameState;
import forge.game.ai.AiController;
import forge.game.ai.AiInputBlock;
import forge.game.ai.AiInputCommon;
import forge.game.ai.ComputerUtil;
import forge.gui.GuiChoose;
/**
* A prototype for player controller class
*
* Handles phase skips for now.
*/
public class PlayerControllerAi extends PlayerController {
private Input defaultInput;
private Input blockInput;
private Input cleanupInput;
private final AiController brains;
public final Input getDefaultInput() {
return defaultInput;
}
public PlayerControllerAi(GameState game, AIPlayer p) {
super(game, p);
brains = new AiController(player, game);
defaultInput = new AiInputCommon(brains);
blockInput = new AiInputBlock(game, player);
cleanupInput = getDefaultInput();
}
/**
* Uses GUI to learn which spell the player (human in our case) would like to play
*/
public SpellAbility getAbilityToPlay(List<SpellAbility> abilities) {
if (abilities.size() == 0) {
return null;
} else if (abilities.size() == 1) {
return abilities.get(0);
} else {
return GuiChoose.oneOrNone("Choose", abilities); // some day network interaction will be here
}
}
/** Input to use when player has to declare blockers */
public Input getBlockInput() {
return blockInput;
}
/**
* @return the cleanupInput
*/
public Input getCleanupInput() {
return cleanupInput;
}
/**
* TODO: Write javadoc for this method.
* @param c
*/
public void playFromSuspend(Card c) {
final List<SpellAbility> choices = c.getBasicSpells();
c.setSuspendCast(true);
for (final SpellAbility sa : choices) {
//Spells
if (sa instanceof Spell) {
Spell spell = (Spell) sa;
if (!spell.canPlayFromEffectAI(true, true)) {
continue;
}
} else {
if (sa.canPlayAI()) {
continue;
}
}
ComputerUtil.playSpellAbilityWithoutPayingManaCost(player, sa, game);
break;
}
}
/* (non-Javadoc)
* @see forge.game.player.PlayerController#playCascade(java.util.List, forge.Card)
*/
@Override
public boolean playCascade(Card cascadedCard, Card source) {
final List<SpellAbility> choices = cascadedCard.getBasicSpells();
for (final SpellAbility sa : choices) {
sa.setActivatingPlayer(player);
//Spells
if (sa instanceof Spell) {
Spell spell = (Spell) sa;
if (!spell.canPlayFromEffectAI(false, true)) {
continue;
}
} else {
if (!sa.canPlayAI()) {
continue;
}
}
ComputerUtil.playSpellAbilityWithoutPayingManaCost(player, sa, game);
return true;
}
return false;
}
/**
* TODO: Write javadoc for this method.
* @return
*/
public AiController getAi() {
return brains;
}
/* (non-Javadoc)
* @see forge.game.player.PlayerController#mayPlaySpellAbilityForFree(forge.card.spellability.SpellAbility)
*/
@Override
public void mayPlaySpellAbilityForFree(SpellAbility copySA) {
if (copySA instanceof Spell) {
Spell spell = (Spell) copySA;
if (spell.canPlayFromEffectAI(false, true)) {
ComputerUtil.playStackFree(player, copySA);
}
} else if (copySA.canPlayAI()) {
ComputerUtil.playStackFree(player, copySA);
}
}
}

View File

@@ -0,0 +1,122 @@
package forge.game.player;
import java.util.List;
import javax.swing.JOptionPane;
import forge.Card;
import forge.Singletons;
import forge.card.spellability.SpellAbility;
import forge.control.input.Input;
import forge.control.input.InputBlock;
import forge.control.input.InputCleanup;
import forge.control.input.InputPassPriority;
import forge.game.GameState;
import forge.game.phase.PhaseType;
import forge.gui.GuiChoose;
import forge.gui.match.CMatchUI;
/**
* A prototype for player controller class
*
* Handles phase skips for now.
*/
public class PlayerControllerHuman extends PlayerController {
private PhaseType autoPassUntil = null;
private final Input defaultInput;
private final Input blockInput;
private final Input cleanupInput;
public final Input getDefaultInput() {
return defaultInput;
}
public PlayerControllerHuman(GameState game0, HumanPlayer p) {
super(game0, p);
defaultInput = new InputPassPriority();
blockInput = new InputBlock(player);
cleanupInput = new InputCleanup(game);
}
public boolean mayAutoPass(PhaseType phase) {
return phase.isBefore(autoPassUntil);
}
public boolean isUiSetToSkipPhase(final Player turn, final PhaseType phase) {
boolean isLocalPlayer = player.equals(Singletons.getControl().getPlayer());
return isLocalPlayer && !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase);
}
/**
* Uses GUI to learn which spell the player (human in our case) would like to play
*/
public SpellAbility getAbilityToPlay(List<SpellAbility> abilities) {
if (abilities.size() == 0) {
return null;
} else if (abilities.size() == 1) {
return abilities.get(0);
} else {
return GuiChoose.oneOrNone("Choose", abilities); // some day network interaction will be here
}
}
/** Input to use when player has to declare blockers */
public Input getBlockInput() {
return blockInput;
}
/**
* @return the cleanupInput
*/
public Input getCleanupInput() {
return cleanupInput;
}
/**
* TODO: Write javadoc for this method.
* @param c
*/
public void playFromSuspend(Card c) {
c.setSuspend(true);
game.getAction().playCardWithoutManaCost(c, c.getOwner());
}
/* (non-Javadoc)
* @see forge.game.player.PlayerController#playCascade(java.util.List, forge.Card)
*/
@Override
public boolean playCascade(Card cascadedCard, Card sourceCard) {
final StringBuilder title = new StringBuilder();
title.append(sourceCard.getName()).append(" - Cascade Ability");
final StringBuilder question = new StringBuilder();
question.append("Cast ").append(cascadedCard.getName());
question.append(" without paying its mana cost?");
final int answer = JOptionPane.showConfirmDialog(null, question.toString(),
title.toString(), JOptionPane.YES_NO_OPTION);
boolean result = answer == JOptionPane.YES_OPTION;
game.getAction().playCardWithoutManaCost(cascadedCard, player);
return result;
}
/* (non-Javadoc)
* @see forge.game.player.PlayerController#mayPlaySpellAbilityForFree(forge.card.spellability.SpellAbility)
*/
@Override
public void mayPlaySpellAbilityForFree(SpellAbility copySA) {
game.getAction().playSpellAbilityForFree(copySA);
}
}