mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
Fixed (probably) the player1 concedes but other player2 wins. Fixed that if player runs out of timer time or player lose of beeing idle, the match will end correctly.
This commit is contained in:
parent
6d039e4262
commit
473c9e207b
32 changed files with 286 additions and 132 deletions
|
@ -71,10 +71,12 @@ public class NewTournamentDialog extends MageDialog {
|
|||
private TableView table;
|
||||
private UUID playerId;
|
||||
private UUID roomId;
|
||||
private Session session;
|
||||
private final Session session;
|
||||
private String lastSessionId;
|
||||
private final List<TournamentPlayerPanel> players = new ArrayList<>();
|
||||
private final List<JComboBox> packs = new ArrayList<>();
|
||||
private final int CONSTRUCTION_TIME_MIN = 6;
|
||||
private final int CONSTRUCTION_TIME_MAX = 30;
|
||||
|
||||
/** Creates new form NewTournamentDialog */
|
||||
public NewTournamentDialog() {
|
||||
|
@ -84,7 +86,7 @@ public class NewTournamentDialog extends MageDialog {
|
|||
txtName.setText("Tournament");
|
||||
this.spnNumWins.setModel(new SpinnerNumberModel(2, 1, 5, 1));
|
||||
this.spnFreeMulligans.setModel(new SpinnerNumberModel(0, 0, 5, 1));
|
||||
this.spnConstructTime.setModel(new SpinnerNumberModel(10, 10, 30, 5));
|
||||
this.spnConstructTime.setModel(new SpinnerNumberModel(10, CONSTRUCTION_TIME_MIN, CONSTRUCTION_TIME_MAX, 2));
|
||||
this.spnNumRounds.setModel(new SpinnerNumberModel(2, 2, 10, 1));
|
||||
}
|
||||
|
||||
|
@ -428,8 +430,7 @@ public class NewTournamentDialog extends MageDialog {
|
|||
if (tOptions.getLimitedOptions() == null) {
|
||||
tOptions.setLimitedOptions(new LimitedOptions());
|
||||
}
|
||||
tOptions.getLimitedOptions().setConstructionTime(60);
|
||||
// tOptions.getLimitedOptions().setConstructionTime((Integer)this.spnConstructTime.getValue() * 60);
|
||||
tOptions.getLimitedOptions().setConstructionTime((Integer)this.spnConstructTime.getValue() * 60);
|
||||
if (tournamentType.isCubeBooster()) {
|
||||
tOptions.getLimitedOptions().setDraftCubeName(this.cbDraftCube.getSelectedItem().toString());
|
||||
} else {
|
||||
|
@ -646,7 +647,11 @@ public class NewTournamentDialog extends MageDialog {
|
|||
break;
|
||||
}
|
||||
}
|
||||
this.spnConstructTime.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_CONSTR_TIME, "600"))/60);
|
||||
int constructionTime = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_CONSTR_TIME, "600")) / 60;
|
||||
if (constructionTime < CONSTRUCTION_TIME_MIN || constructionTime > CONSTRUCTION_TIME_MAX) {
|
||||
constructionTime = CONSTRUCTION_TIME_MIN;
|
||||
}
|
||||
this.spnConstructTime.setValue(constructionTime);
|
||||
String tournamentTypeName = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_TYPE, "Sealed Elimination");
|
||||
for (TournamentTypeView tournamentTypeView : session.getTournamentTypes()) {
|
||||
if (tournamentTypeView.getName().equals(tournamentTypeName)) {
|
||||
|
|
|
@ -12,6 +12,7 @@ public interface Action {
|
|||
|
||||
/**
|
||||
* Executes action.
|
||||
* @throws mage.MageException
|
||||
*/
|
||||
void execute() throws MageException;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package mage.utils.timer;
|
||||
|
||||
import mage.MageException;
|
||||
import mage.interfaces.Action;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import mage.MageException;
|
||||
import mage.interfaces.Action;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
* @author noxx
|
||||
|
@ -14,14 +13,11 @@ public class PriorityTimer extends TimerTask {
|
|||
|
||||
private static final Logger logger = Logger.getLogger(PriorityTimer.class);
|
||||
|
||||
private final long delay;
|
||||
private final Action taskOnTimeout;
|
||||
|
||||
private int count;
|
||||
|
||||
private long delay;
|
||||
|
||||
private Action taskOnTimeout;
|
||||
|
||||
private Action taskOnTick;
|
||||
|
||||
private States state = States.NONE;
|
||||
|
||||
enum States {
|
||||
|
|
|
@ -72,14 +72,18 @@ public class MatchView implements Serializable {
|
|||
}
|
||||
StringBuilder sb1 = new StringBuilder();
|
||||
StringBuilder sb2 = new StringBuilder();
|
||||
for (MatchPlayer player: match.getPlayers()) {
|
||||
sb1.append(player.getName());
|
||||
if(player.hasQuit()) {
|
||||
for (MatchPlayer matchPlayer: match.getPlayers()) {
|
||||
sb1.append(matchPlayer.getName());
|
||||
if(matchPlayer.hasQuit()) {
|
||||
if (matchPlayer.hasTimerTimeout()) {
|
||||
sb1.append(" [timer] ");
|
||||
} else {
|
||||
sb1.append(" [quit] ");
|
||||
}
|
||||
}
|
||||
sb1.append(", ");
|
||||
sb2.append(player.getName()).append(" ");
|
||||
sb2.append(player.getWins()).append("-").append(player.getLoses()).append(", ");
|
||||
sb2.append(matchPlayer.getName()).append(" ");
|
||||
sb2.append(matchPlayer.getWins()).append("-").append(matchPlayer.getLoses()).append(", ");
|
||||
}
|
||||
players = sb1.substring(0, sb1.length() - 2);
|
||||
result = sb2.substring(0, sb2.length() - 2);
|
||||
|
|
|
@ -39,7 +39,6 @@ import mage.game.Seat;
|
|||
import mage.game.Table;
|
||||
import mage.game.match.MatchPlayer;
|
||||
import mage.game.tournament.TournamentPlayer;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -54,7 +54,7 @@ public class TournamentGameView implements Serializable {
|
|||
this.matchId = pair.getMatch().getId();
|
||||
this.gameId = game.getId();
|
||||
this.players = pair.getPlayer1().getPlayer().getName() + " - " + pair.getPlayer2().getPlayer().getName();
|
||||
if (game.isGameOver()) {
|
||||
if (game.hasEnded()) {
|
||||
this.state = "Finished";
|
||||
this.result = game.getWinner();
|
||||
}
|
||||
|
|
|
@ -467,7 +467,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
logger.trace("interrupted - " + val);
|
||||
return val;
|
||||
}
|
||||
if (depth <= 0 || SimulationNode2.nodeCount > maxNodes || game.isGameOver()) {
|
||||
if (depth <= 0 || SimulationNode2.nodeCount > maxNodes || game.gameOver(null)) {
|
||||
logger.trace("Add actions -- reached end state, node count=" + SimulationNode2.nodeCount + ", depth=" + depth);
|
||||
val = GameStateEvaluator2.evaluate(playerId, game);
|
||||
UUID currentPlayerId = node.getGame().getPlayerList().get();
|
||||
|
@ -488,7 +488,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
}
|
||||
}
|
||||
|
||||
if (game.isGameOver()) {
|
||||
if (game.gameOver(null)) {
|
||||
val = GameStateEvaluator2.evaluate(playerId, game);
|
||||
} else if (node.getChildren().size() > 0) {
|
||||
//declared attackers or blockers or triggered abilities
|
||||
|
@ -534,7 +534,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
logger.debug("Sim Prio [" + depth + "] -- repeated action: " + action.toString());
|
||||
continue;
|
||||
}
|
||||
if (!sim.isGameOver() && action.isUsesStack()) {
|
||||
if (!sim.gameOver(null) && action.isUsesStack()) {
|
||||
// only pass if the last action uses the stack
|
||||
sim.getPlayer(currentPlayer.getId()).pass(game);
|
||||
sim.getPlayerList().getNext();
|
||||
|
@ -797,7 +797,7 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
break;
|
||||
case CLEANUP:
|
||||
game.getPhase().getStep().beginStep(game, activePlayerId);
|
||||
if (!game.checkStateAndTriggered() && !game.isGameOver()) {
|
||||
if (!game.checkStateAndTriggered() && !game.gameOver(null)) {
|
||||
game.getState().setActivePlayerId(game.getState().getPlayerList(game.getActivePlayerId()).getNext());
|
||||
game.getTurn().setPhase(new BeginningPhase());
|
||||
game.getPhase().setStep(new UntapStep());
|
||||
|
|
|
@ -229,7 +229,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
|
|||
return GameStateEvaluator2.evaluate(playerId, game);
|
||||
}
|
||||
// Condition to stop deeper simulation
|
||||
if (depth <= 0 || SimulationNode2.nodeCount > maxNodes || game.isGameOver()) {
|
||||
if (depth <= 0 || SimulationNode2.nodeCount > maxNodes || game.gameOver(null)) {
|
||||
val = GameStateEvaluator2.evaluate(playerId, game);
|
||||
if (logger.isTraceEnabled()) {
|
||||
StringBuilder sb = new StringBuilder("Add Actions -- reached end state <").append(val).append(">");
|
||||
|
@ -265,7 +265,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
|
|||
}
|
||||
}
|
||||
|
||||
if (game.isGameOver()) {
|
||||
if (game.gameOver(null)) {
|
||||
val = GameStateEvaluator2.evaluate(playerId, game);
|
||||
}
|
||||
else if (stepFinished) {
|
||||
|
@ -494,7 +494,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
|
|||
sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_POST, sim.getActivePlayerId(), sim.getActivePlayerId()));
|
||||
Combat simCombat = sim.getCombat().copy();
|
||||
finishCombat(sim);
|
||||
if (sim.isGameOver()) {
|
||||
if (sim.gameOver(null)) {
|
||||
val = GameStateEvaluator2.evaluate(playerId, sim);
|
||||
}
|
||||
else if (!counter) {
|
||||
|
@ -568,7 +568,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
|
|||
logger.debug("interrupted");
|
||||
return;
|
||||
}
|
||||
if (!game.isGameOver()) {
|
||||
if (!game.gameOver(null)) {
|
||||
game.getPhase().setStep(step);
|
||||
if (!step.skipStep(game, game.getActivePlayerId())) {
|
||||
step.beginStep(game, game.getActivePlayerId());
|
||||
|
@ -617,7 +617,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
|
|||
logger.debug("interrupted");
|
||||
return;
|
||||
}
|
||||
if (!game.isGameOver()) {
|
||||
if (!game.gameOver(null)) {
|
||||
game.getTurn().getPhase().endPhase(game, game.getActivePlayerId());
|
||||
game.getTurn().setPhase(new EndPhase());
|
||||
if (game.getTurn().getPhase().beginPhase(game, game.getActivePlayerId())) {
|
||||
|
|
|
@ -33,7 +33,7 @@ public class GameStateEvaluator2 {
|
|||
public static int evaluate(UUID playerId, Game game) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
Player opponent = game.getPlayer(game.getOpponents(playerId).iterator().next());
|
||||
if (game.isGameOver()) {
|
||||
if (game.gameOver(null)) {
|
||||
if (player.hasLost() || opponent.hasWon()) {
|
||||
return LOSE_GAME_SCORE;
|
||||
}
|
||||
|
|
|
@ -60,12 +60,14 @@ public class ActionSimulator {
|
|||
|
||||
public int evaluateState() {
|
||||
Player opponent = game.getPlayer(game.getOpponents(player.getId()).iterator().next());
|
||||
if (game.isGameOver()) {
|
||||
if (player.hasLost() || opponent.hasWon())
|
||||
if (game.gameOver(null)) {
|
||||
if (player.hasLost() || opponent.hasWon()) {
|
||||
return Integer.MIN_VALUE;
|
||||
if (opponent.hasLost() || player.hasWon())
|
||||
}
|
||||
if (opponent.hasLost() || player.hasWon()) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
int value = player.getLife();
|
||||
value -= opponent.getLife();
|
||||
PermanentEvaluator evaluator = new PermanentEvaluator();
|
||||
|
|
|
@ -58,11 +58,11 @@ public class MCTSNode {
|
|||
private int visits = 0;
|
||||
private int wins = 0;
|
||||
private MCTSNode parent;
|
||||
private List<MCTSNode> children = new ArrayList<MCTSNode>();
|
||||
private final List<MCTSNode> children = new ArrayList<MCTSNode>();
|
||||
private Ability action;
|
||||
private Game game;
|
||||
private Combat combat;
|
||||
private String stateValue;
|
||||
private final String stateValue;
|
||||
private UUID playerId;
|
||||
private boolean terminal = false;
|
||||
|
||||
|
@ -71,7 +71,7 @@ public class MCTSNode {
|
|||
public MCTSNode(Game game) {
|
||||
this.game = game;
|
||||
this.stateValue = game.getState().getValue(false, game);
|
||||
this.terminal = game.isGameOver();
|
||||
this.terminal = game.gameOver(null);
|
||||
setPlayer();
|
||||
nodeCount = 1;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ public class MCTSNode {
|
|||
protected MCTSNode(MCTSNode parent, Game game, Ability action) {
|
||||
this.game = game;
|
||||
this.stateValue = game.getState().getValue(false, game);
|
||||
this.terminal = game.isGameOver();
|
||||
this.terminal = game.gameOver(null);
|
||||
this.parent = parent;
|
||||
this.action = action;
|
||||
setPlayer();
|
||||
|
@ -90,22 +90,23 @@ public class MCTSNode {
|
|||
this.game = game;
|
||||
this.combat = combat;
|
||||
this.stateValue = game.getState().getValue(false, game);
|
||||
this.terminal = game.isGameOver();
|
||||
this.terminal = game.gameOver(null);
|
||||
this.parent = parent;
|
||||
setPlayer();
|
||||
nodeCount++;
|
||||
}
|
||||
|
||||
private void setPlayer() {
|
||||
if (game.getStep().getStepPart() == StepPart.PRIORITY)
|
||||
if (game.getStep().getStepPart() == StepPart.PRIORITY) {
|
||||
playerId = game.getPriorityPlayerId();
|
||||
else {
|
||||
if (game.getStep().getType() == PhaseStep.DECLARE_BLOCKERS)
|
||||
} else {
|
||||
if (game.getStep().getType() == PhaseStep.DECLARE_BLOCKERS) {
|
||||
playerId = game.getCombat().getDefenders().iterator().next();
|
||||
else
|
||||
} else {
|
||||
playerId = game.getActivePlayerId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MCTSNode select(UUID targetPlayerId) {
|
||||
double bestValue = Double.NEGATIVE_INFINITY;
|
||||
|
|
|
@ -330,7 +330,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
|
|||
return GameStateEvaluator.evaluate(playerId, game);
|
||||
}
|
||||
int val;
|
||||
if (node.depth > maxDepth || game.isGameOver()) {
|
||||
if (node.depth > maxDepth || game.gameOver(null)) {
|
||||
logger.debug(indent(node.depth) + "simulating -- reached end state");
|
||||
val = GameStateEvaluator.evaluate(playerId, game);
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
|
|||
}
|
||||
}
|
||||
|
||||
if (game.isGameOver()) {
|
||||
if (game.gameOver(null)) {
|
||||
val = GameStateEvaluator.evaluate(playerId, game);
|
||||
}
|
||||
else if (node.getChildren().size() > 0) {
|
||||
|
@ -403,7 +403,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
|
|||
logger.debug(indent(node.depth) + "found useless action: " + action);
|
||||
continue;
|
||||
}
|
||||
if (!sim.isGameOver() && action.isUsesStack()) {
|
||||
if (!sim.gameOver(null) && action.isUsesStack()) {
|
||||
// only pass if the last action uses the stack
|
||||
sim.getPlayer(currentPlayer.getId()).pass(game);
|
||||
sim.getPlayerList().getNext();
|
||||
|
@ -587,7 +587,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
|
|||
break;
|
||||
case CLEANUP:
|
||||
game.getPhase().getStep().beginStep(game, activePlayerId);
|
||||
if (!game.checkStateAndTriggered() && !game.isGameOver()) {
|
||||
if (!game.checkStateAndTriggered() && !game.gameOver(null)) {
|
||||
game.getState().setActivePlayerId(game.getState().getPlayerList(game.getActivePlayerId()).getNext());
|
||||
game.getTurn().setPhase(new BeginningPhase());
|
||||
game.getPhase().setStep(new UntapStep());
|
||||
|
|
|
@ -185,7 +185,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
logger.debug(indent(node.depth) + "interrupted");
|
||||
return GameStateEvaluator.evaluate(playerId, game);
|
||||
}
|
||||
if (node.depth > maxDepth || game.isGameOver()) {
|
||||
if (node.depth > maxDepth || game.gameOver(null)) {
|
||||
logger.debug(indent(node.depth) + "simulating -- reached end state");
|
||||
val = GameStateEvaluator.evaluate(playerId, game);
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
}
|
||||
}
|
||||
|
||||
if (game.isGameOver()) {
|
||||
if (game.gameOver(null)) {
|
||||
val = GameStateEvaluator.evaluate(playerId, game);
|
||||
}
|
||||
else if (stepFinished) {
|
||||
|
@ -406,7 +406,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_POST, sim.getActivePlayerId(), sim.getActivePlayerId()));
|
||||
Combat simCombat = sim.getCombat().copy();
|
||||
finishCombat(sim);
|
||||
if (sim.isGameOver()) {
|
||||
if (sim.gameOver(null)) {
|
||||
val = GameStateEvaluator.evaluate(playerId, sim);
|
||||
}
|
||||
else if (!counter) {
|
||||
|
@ -448,7 +448,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
return GameStateEvaluator.evaluate(playerId, game);
|
||||
}
|
||||
Integer val = null;
|
||||
if (!game.isGameOver()) {
|
||||
if (!game.gameOver(null)) {
|
||||
logger.debug(indent(node.depth) + "simulating -- ending turn");
|
||||
simulateToEnd(game);
|
||||
game.getState().setActivePlayerId(game.getState().getPlayerList(game.getActivePlayerId()).getNext());
|
||||
|
@ -476,7 +476,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
logger.debug("interrupted");
|
||||
return;
|
||||
}
|
||||
if (!game.isGameOver()) {
|
||||
if (!game.gameOver(null)) {
|
||||
game.getPhase().setStep(step);
|
||||
if (!step.skipStep(game, game.getActivePlayerId())) {
|
||||
step.beginStep(game, game.getActivePlayerId());
|
||||
|
@ -524,7 +524,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
|
|||
logger.debug("interrupted");
|
||||
return;
|
||||
}
|
||||
if (!game.isGameOver()) {
|
||||
if (!game.gameOver(null)) {
|
||||
game.getTurn().getPhase().endPhase(game, game.getActivePlayerId());
|
||||
game.getTurn().setPhase(new EndPhase());
|
||||
if (game.getTurn().getPhase().beginPhase(game, game.getActivePlayerId())) {
|
||||
|
|
|
@ -70,7 +70,7 @@ public class GameStateEvaluator {
|
|||
public static int evaluate(UUID playerId, Game game, boolean ignoreTapped) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
Player opponent = game.getPlayer(game.getOpponents(playerId).iterator().next());
|
||||
if (game.isGameOver()) {
|
||||
if (game.gameOver(null)) {
|
||||
if (player.hasLost() || opponent.hasWon())
|
||||
return LOSE_SCORE;
|
||||
if (opponent.hasLost() || player.hasWon())
|
||||
|
|
|
@ -593,7 +593,6 @@ public class TableController {
|
|||
* @return true if table can be closed
|
||||
*/
|
||||
public boolean endGameAndStartNextGame() {
|
||||
boolean matchIsOver = false;
|
||||
// get player that chooses who goes first
|
||||
UUID choosingPlayerId = match.getChooser();
|
||||
match.endGame();
|
||||
|
@ -604,27 +603,24 @@ public class TableController {
|
|||
}
|
||||
GameManager.getInstance().removeGame(match.getGame().getId());
|
||||
try {
|
||||
if (!match.isMatchOver()) {
|
||||
if (!match.hasEnded()) {
|
||||
table.sideboard();
|
||||
setupTimeout(Match.SIDEBOARD_TIME);
|
||||
match.sideboard();
|
||||
cancelTimeout();
|
||||
if (!match.isMatchOver()) {
|
||||
if (!match.hasEnded()) {
|
||||
startGame(choosingPlayerId);
|
||||
} else {
|
||||
matchIsOver = true;
|
||||
closeTable();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if match has only one game
|
||||
matchIsOver = true;
|
||||
closeTable();
|
||||
}
|
||||
} catch (GameException ex) {
|
||||
logger.fatal(null, ex);
|
||||
}
|
||||
return matchIsOver;
|
||||
return match.hasEnded();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -240,8 +240,8 @@ public class GameController implements GameCallback {
|
|||
PriorityTimer timer = new PriorityTimer(count, delay, new Action() {
|
||||
@Override
|
||||
public void execute() throws MageException {
|
||||
game.concede(initPlayerId);
|
||||
logger.debug("Game timeout for player: " + initPlayerId + ". Conceding.");
|
||||
game.timerTimeout(initPlayerId);
|
||||
logger.debug(new StringBuilder("Game timeout for player: ").append(initPlayerId).append(". Conceding."));
|
||||
}
|
||||
});
|
||||
timers.put(playerId, timer);
|
||||
|
@ -399,7 +399,7 @@ public class GameController implements GameCallback {
|
|||
.append(ConfigSettings.getInstance().getMaxSecondsIdle())
|
||||
.append(" seconds ) - Auto concede.");
|
||||
ChatManager.getInstance().broadcast(chatId, "", sb.toString() , MessageColor.BLACK, true, MessageType.STATUS);
|
||||
concede(userId);
|
||||
game.idleTimeout(getPlayerId(userId));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ public enum TableState {
|
|||
CONSTRUCTING ("Constructing"),
|
||||
FINISHED ("Finished");
|
||||
|
||||
private String text;
|
||||
private final String text;
|
||||
|
||||
TableState(String text) {
|
||||
this.text = text;
|
||||
|
|
|
@ -122,7 +122,8 @@ public interface Game extends MageItem, Serializable {
|
|||
UUID getActivePlayerId();
|
||||
UUID getPriorityPlayerId();
|
||||
void leave(UUID playerId);
|
||||
boolean isGameOver();
|
||||
boolean gameOver(UUID playerId);
|
||||
boolean hasEnded();
|
||||
Battlefield getBattlefield();
|
||||
SpellStack getStack();
|
||||
Exile getExile();
|
||||
|
@ -218,6 +219,8 @@ public interface Game extends MageItem, Serializable {
|
|||
void mulligan(UUID playerId);
|
||||
void endMulligan(UUID playerId);
|
||||
void quit(UUID playerId);
|
||||
void timerTimeout(UUID playerId);
|
||||
void idleTimeout(UUID playerId);
|
||||
void concede(UUID playerId);
|
||||
void undo(UUID playerId);
|
||||
void emptyManaPools();
|
||||
|
|
|
@ -418,8 +418,26 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts check if game over or if playerId is given
|
||||
* let the player concede.
|
||||
*
|
||||
* @param playerId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean isGameOver() {
|
||||
public synchronized boolean gameOver(UUID playerId) {
|
||||
if (playerId == null) {
|
||||
boolean result = checkIfGameIsOver();
|
||||
return result;
|
||||
} else {
|
||||
leave(playerId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean checkIfGameIsOver() {
|
||||
if (state.isGameOver()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -447,6 +465,11 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEnded() {
|
||||
return endTime != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWinner() {
|
||||
if (winnerId == null) {
|
||||
|
@ -546,13 +569,13 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
Player player = getPlayer(players.get());
|
||||
boolean wasPaused = state.isPaused();
|
||||
state.resume();
|
||||
if (!isGameOver()) {
|
||||
if (!gameOver(null)) {
|
||||
fireInformEvent(new StringBuilder("Turn ").append(state.getTurnNum()).toString());
|
||||
if (checkStopOnTurnOption()) {
|
||||
return;
|
||||
}
|
||||
state.getTurn().resumePlay(this, wasPaused);
|
||||
if (!isPaused() && !isGameOver()) {
|
||||
if (!isPaused() && !gameOver(null)) {
|
||||
endOfTurn();
|
||||
player = players.getNext(this);
|
||||
state.setTurnNum(state.getTurnNum() + 1);
|
||||
|
@ -562,10 +585,10 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
}
|
||||
|
||||
protected void play(UUID nextPlayerId) {
|
||||
if (!isPaused() && !isGameOver()) {
|
||||
if (!isPaused() && !gameOver(null)) {
|
||||
PlayerList players = state.getPlayerList(nextPlayerId);
|
||||
Player player = getPlayer(players.get());
|
||||
while (!isPaused() && !isGameOver()) {
|
||||
while (!isPaused() && !gameOver(null)) {
|
||||
|
||||
if (!playTurn(player)) {
|
||||
break;
|
||||
|
@ -583,7 +606,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
player = players.getNext(this);
|
||||
}
|
||||
}
|
||||
if (isGameOver()) {
|
||||
if (gameOver(null)) {
|
||||
winnerId = findWinnersAndLosers();
|
||||
logger.info(new StringBuilder("Game with gameId ").append(this.getId()).append(" ended."));
|
||||
}
|
||||
|
@ -597,7 +620,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
state.setActivePlayerId(player.getId());
|
||||
player.becomesActivePlayer();
|
||||
state.getTurn().play(this, player.getId());
|
||||
if (isPaused() || isGameOver()) {
|
||||
if (isPaused() || gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
endOfTurn();
|
||||
|
@ -866,8 +889,29 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
public synchronized void quit(UUID playerId) {
|
||||
Player player = state.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
fireInformEvent(player.getName() + " quits the match.");
|
||||
player.quit(this);
|
||||
}else {
|
||||
logger.error(new StringBuilder("player not found - playerId: ").append(playerId));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void timerTimeout(UUID playerId) {
|
||||
Player player = state.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
player.timerTimeout(this);
|
||||
} else {
|
||||
logger.error(new StringBuilder("player not found - playerId: ").append(playerId));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void idleTimeout(UUID playerId) {
|
||||
Player player = state.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
player.idleTimeout(this);
|
||||
} else {
|
||||
logger.error(new StringBuilder("player not found - playerId: ").append(playerId));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -923,7 +967,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
int bookmark = 0;
|
||||
clearAllBookmarks();
|
||||
try {
|
||||
while (!isPaused() && !isGameOver()) {
|
||||
while (!isPaused() && !gameOver(null)) {
|
||||
if (!resuming) {
|
||||
state.getPlayers().resetPassed();
|
||||
state.getPlayerList().setCurrent(activePlayerId);
|
||||
|
@ -933,13 +977,13 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
}
|
||||
fireUpdatePlayersEvent();
|
||||
Player player;
|
||||
while (!isPaused() && !isGameOver()) {
|
||||
while (!isPaused() && !gameOver(null)) {
|
||||
try {
|
||||
//if (bookmark == 0)
|
||||
//bookmark = bookmarkState();
|
||||
player = getPlayer(state.getPlayerList().get());
|
||||
state.setPriorityPlayerId(player.getId());
|
||||
while (!player.isPassed() && player.isInGame() && !isPaused() && !isGameOver()) {
|
||||
while (!player.isPassed() && player.isInGame() && !isPaused() && !gameOver(null)) {
|
||||
if (!resuming) {
|
||||
if (checkStateAndTriggered()) {
|
||||
applyEffects();
|
||||
|
@ -947,7 +991,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
//resetLKI();
|
||||
applyEffects();
|
||||
saveState(false);
|
||||
if (isPaused() || isGameOver()) {
|
||||
if (isPaused() || gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
// resetPassed should be called if player performs any action
|
||||
|
@ -962,7 +1006,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
}
|
||||
resetShortLivingLKI();
|
||||
resuming = false;
|
||||
if (isPaused() || isGameOver()) {
|
||||
if (isPaused() || gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
if (allPassed()) {
|
||||
|
@ -1164,9 +1208,9 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
public boolean checkStateAndTriggered() {
|
||||
boolean somethingHappened = false;
|
||||
//20091005 - 115.5
|
||||
while (!isPaused() && !this.isGameOver()) {
|
||||
while (!isPaused() && !gameOver(null)) {
|
||||
if (!checkStateBasedActions() ) {
|
||||
if (isPaused() || this.isGameOver() || !checkTriggered()) {
|
||||
if (isPaused() || gameOver(null) || !checkTriggered()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1729,7 +1773,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
return;
|
||||
}
|
||||
player.leave();
|
||||
if (this.isGameOver()) {
|
||||
if (gameOver(null)) {
|
||||
// no need to remove objects if only one player is left so the game is over
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ public class Table implements Serializable {
|
|||
|
||||
public void initTournament() {
|
||||
setState(TableState.DUELING);
|
||||
|
||||
tournament.setStepStartTime(new Date());
|
||||
}
|
||||
|
||||
public void endTournament() {
|
||||
|
@ -122,10 +122,12 @@ public class Table implements Serializable {
|
|||
|
||||
public void initDraft() {
|
||||
setState(TableState.DRAFTING);
|
||||
tournament.setStepStartTime(new Date());
|
||||
}
|
||||
|
||||
public void construct() {
|
||||
setState(TableState.CONSTRUCTING);
|
||||
tournament.setStepStartTime(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -191,7 +191,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
//20101001 - 508.1d
|
||||
checkAttackRequirements(player, game);
|
||||
player.selectAttackers(game, attackerId);
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
checkAttackRestrictions(player, game);
|
||||
|
@ -316,7 +316,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
}
|
||||
while (choose) {
|
||||
blockController.selectBlockers(game, defenderId);
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
if (!this.checkBlockRestrictions(defender, game)) {
|
||||
|
|
|
@ -48,7 +48,8 @@ public interface Match {
|
|||
|
||||
UUID getId();
|
||||
String getName();
|
||||
boolean isMatchOver();
|
||||
boolean hasEnded();
|
||||
boolean checkIfMatchEnds();
|
||||
List<MatchPlayer> getPlayers();
|
||||
MatchPlayer getPlayer(UUID playerId);
|
||||
|
||||
|
|
|
@ -126,18 +126,29 @@ public abstract class MatchImpl implements Match {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatchOver() {
|
||||
public boolean hasEnded() {
|
||||
return endTime != null;
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean checkIfMatchEnds() {
|
||||
int activePlayers = 0;
|
||||
for (MatchPlayer player: players) {
|
||||
if (!player.hasQuit()) {
|
||||
MatchPlayer matchWinner = null;
|
||||
for (MatchPlayer matchPlayer: players) {
|
||||
if (!matchPlayer.hasQuit()) {
|
||||
activePlayers++;
|
||||
matchWinner = matchPlayer;
|
||||
}
|
||||
if (player.getWins() >= options.getWinsNeeded()) {
|
||||
if (matchPlayer.getWins() >= options.getWinsNeeded()) {
|
||||
matchPlayer.setMatchWinner(true);
|
||||
endTime = new Date();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (activePlayers < 2) {
|
||||
if (matchWinner != null) {
|
||||
matchWinner.setMatchWinner(true);
|
||||
}
|
||||
endTime = new Date();
|
||||
return true;
|
||||
}
|
||||
|
@ -200,24 +211,28 @@ public abstract class MatchImpl implements Match {
|
|||
@Override
|
||||
public void endGame() {
|
||||
Game game = getGame();
|
||||
for (MatchPlayer player: this.players) {
|
||||
Player p = game.getPlayer(player.getPlayer().getId());
|
||||
if (p != null) {
|
||||
for (MatchPlayer matchPlayer: this.players) {
|
||||
Player player = game.getPlayer(matchPlayer.getPlayer().getId());
|
||||
if (player != null) {
|
||||
// get the left time from player priority timer
|
||||
if (game.getPriorityTime() > 0) {
|
||||
player.setPriorityTimeLeft(p.getPriorityTimeLeft());
|
||||
matchPlayer.setPriorityTimeLeft(player.getPriorityTimeLeft());
|
||||
}
|
||||
if (p.hasQuit()) {
|
||||
player.setQuit(true);
|
||||
if (player.hasQuit()) {
|
||||
matchPlayer.setQuit(true);
|
||||
}
|
||||
if (p.hasWon()) {
|
||||
player.addWin();
|
||||
if (player.hasTimerTimeout()) {
|
||||
matchPlayer.setTimerTimeout(true);
|
||||
}
|
||||
if (p.hasLost()) {
|
||||
player.addLose();
|
||||
if (player.hasWon()) {
|
||||
matchPlayer.addWin();
|
||||
}
|
||||
if (player.hasLost()) {
|
||||
matchPlayer.addLose();
|
||||
}
|
||||
}
|
||||
}
|
||||
checkIfMatchEnds();
|
||||
game.fireGameEndInfo();
|
||||
}
|
||||
|
||||
|
|
|
@ -39,12 +39,14 @@ import mage.players.Player;
|
|||
public class MatchPlayer {
|
||||
private int wins;
|
||||
private int loses;
|
||||
private boolean matchWinner;
|
||||
|
||||
private Deck deck;
|
||||
private Player player;
|
||||
private final String name;
|
||||
|
||||
private boolean quit;
|
||||
private boolean timerTimeout;
|
||||
private boolean doneSideboarding;
|
||||
private int priorityTimeLeft;
|
||||
|
||||
|
@ -55,7 +57,9 @@ public class MatchPlayer {
|
|||
this.loses = 0;
|
||||
this.doneSideboarding = true;
|
||||
this.quit = false;
|
||||
this.timerTimeout = false;
|
||||
this.name = player.getName();
|
||||
this.matchWinner = false;
|
||||
}
|
||||
|
||||
public int getPriorityTimeLeft() {
|
||||
|
@ -126,6 +130,22 @@ public class MatchPlayer {
|
|||
this.quit = quit;
|
||||
}
|
||||
|
||||
public boolean hasTimerTimeout() {
|
||||
return timerTimeout;
|
||||
}
|
||||
|
||||
public void setTimerTimeout(boolean timerTimeout) {
|
||||
this.timerTimeout = timerTimeout;
|
||||
}
|
||||
|
||||
public boolean isMatchWinner() {
|
||||
return matchWinner;
|
||||
}
|
||||
|
||||
public void setMatchWinner(boolean matchWinner) {
|
||||
this.matchWinner = matchWinner;
|
||||
}
|
||||
|
||||
public void cleanUpOnMatchEnd() {
|
||||
// Free resources that are not needed after match end
|
||||
this.deck = null;
|
||||
|
|
|
@ -72,7 +72,7 @@ public class Round {
|
|||
public boolean isRoundOver() {
|
||||
boolean roundIsOver = true;
|
||||
for (TournamentPairing pair: pairs) {
|
||||
if (pair.getMatch() != null && !pair.getMatch().isMatchOver()) {
|
||||
if (pair.getMatch() != null && !pair.getMatch().hasEnded()) {
|
||||
roundIsOver = false;
|
||||
} else {
|
||||
if (!pair.isAlreadyPublished()) {
|
||||
|
|
|
@ -78,6 +78,10 @@ public interface Tournament {
|
|||
// tournament times
|
||||
Date getStartTime();
|
||||
Date getEndTime();
|
||||
|
||||
Date getStepStartTime();
|
||||
void setStepStartTime(Date date);
|
||||
|
||||
// tournament type
|
||||
TournamentType getTournamentType();
|
||||
void setTournamentType(TournamentType tournamentType);
|
||||
|
|
|
@ -74,6 +74,7 @@ public abstract class TournamentImpl implements Tournament {
|
|||
|
||||
protected Date startTime;
|
||||
protected Date endTime;
|
||||
protected Date stepStartTime;
|
||||
protected boolean abort;
|
||||
protected String tournamentState;
|
||||
|
||||
|
@ -244,7 +245,7 @@ public abstract class TournamentImpl implements Tournament {
|
|||
for (Round round: rounds) {
|
||||
for (TournamentPairing pair: round.getPairs()) {
|
||||
Match match = pair.getMatch();
|
||||
if (match != null && match.isMatchOver()) {
|
||||
if (match != null && match.hasEnded()) {
|
||||
TournamentPlayer tp1 = pair.getPlayer1();
|
||||
TournamentPlayer tp2 = pair.getPlayer2();
|
||||
MatchPlayer mp1 = match.getPlayer(pair.getPlayer1().getPlayer().getId());
|
||||
|
@ -302,11 +303,11 @@ public abstract class TournamentImpl implements Tournament {
|
|||
matchResult.append(p2.getPlayer().getName());
|
||||
matchResult.append(" (").append(mp1.getWins());
|
||||
if (mp1.hasQuit()) {
|
||||
matchResult.append("Q");
|
||||
matchResult.append(mp1.hasTimerTimeout()?"T":"Q");
|
||||
}
|
||||
matchResult.append("-").append(mp2.getWins());
|
||||
if (mp2.hasQuit()) {
|
||||
matchResult.append("Q");
|
||||
matchResult.append(mp2.hasTimerTimeout()?"T":"Q");
|
||||
}
|
||||
matchResult.append(") ");
|
||||
return matchResult.toString();
|
||||
|
@ -479,4 +480,18 @@ public abstract class TournamentImpl implements Tournament {
|
|||
this.tournamentState = tournamentState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getStepStartTime() {
|
||||
if (stepStartTime != null) {
|
||||
return new Date(stepStartTime.getTime());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStepStartTime(Date stepStartTime) {
|
||||
this.stepStartTime = stepStartTime;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ public class TournamentPairing {
|
|||
}
|
||||
|
||||
public void eliminatePlayers() {
|
||||
if (match.isMatchOver()) {
|
||||
if (match.hasEnded()) {
|
||||
MatchPlayer mPlayer1 = match.getPlayer(player1.getPlayer().getId());
|
||||
MatchPlayer mPlayer2 = match.getPlayer(player2.getPlayer().getId());
|
||||
if (mPlayer1.hasQuit() || (!mPlayer2.hasQuit() && mPlayer1.getWins() < match.getWinsNeeded())) {
|
||||
|
|
|
@ -95,7 +95,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
}
|
||||
|
||||
public boolean play(Game game, UUID activePlayerId) {
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
if (beginPhase(game, activePlayerId)) {
|
||||
|
||||
for (Step step: steps) {
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
currentStep = step;
|
||||
|
@ -115,7 +115,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
playStep(game);
|
||||
}
|
||||
}
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
count++;
|
||||
|
@ -136,7 +136,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
}
|
||||
|
||||
public boolean resumePlay(Game game, PhaseStep stepType, boolean wasPaused) {
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
resumeStep(game, wasPaused);
|
||||
while (it.hasNext()) {
|
||||
step = it.next();
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
currentStep = step;
|
||||
|
@ -159,7 +159,7 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return false;
|
||||
}
|
||||
count++;
|
||||
|
@ -194,10 +194,10 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
protected void playStep(Game game) {
|
||||
if (!currentStep.skipStep(game, activePlayerId)) {
|
||||
prePriority(game, activePlayerId);
|
||||
if (!game.isPaused() && !game.isGameOver()) {
|
||||
if (!game.isPaused() && !game.gameOver(null)) {
|
||||
currentStep.priority(game, activePlayerId, false);
|
||||
}
|
||||
if (!game.isPaused() && !game.isGameOver()) {
|
||||
if (!game.isPaused() && !game.gameOver(null)) {
|
||||
postPriority(game, activePlayerId);
|
||||
}
|
||||
}
|
||||
|
@ -219,11 +219,11 @@ public abstract class Phase<T extends Phase<T>> implements Serializable {
|
|||
prePriority(game, activePlayerId);
|
||||
}
|
||||
case PRIORITY:
|
||||
if (!game.isPaused() && !game.isGameOver()) {
|
||||
if (!game.isPaused() && !game.gameOver(null)) {
|
||||
currentStep.priority(game, activePlayerId, resuming);
|
||||
}
|
||||
case POST:
|
||||
if (!game.isPaused() && !game.isGameOver()) {
|
||||
if (!game.isPaused() && !game.gameOver(null)) {
|
||||
postPriority(game, activePlayerId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ public class Turn implements Serializable {
|
|||
|
||||
private Phase currentPhase;
|
||||
private UUID activePlayerId;
|
||||
private List<Phase> phases = new ArrayList<Phase>();
|
||||
private final List<Phase> phases = new ArrayList<>();
|
||||
private boolean declareAttackersStepStarted = false;
|
||||
|
||||
public Turn() {
|
||||
|
@ -109,7 +109,7 @@ public class Turn implements Serializable {
|
|||
|
||||
public void play(Game game, UUID activePlayerId) {
|
||||
this.setDeclareAttackersStepStarted(false);
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ public class Turn implements Serializable {
|
|||
resetCounts();
|
||||
game.getPlayer(activePlayerId).beginTurn(game);
|
||||
for (Phase phase: phases) {
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
currentPhase = phase;
|
||||
|
@ -168,7 +168,7 @@ public class Turn implements Serializable {
|
|||
}
|
||||
while (it.hasNext()) {
|
||||
phase = it.next();
|
||||
if (game.isPaused() || game.isGameOver()) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
currentPhase = phase;
|
||||
|
|
|
@ -129,6 +129,10 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
boolean hasWon();
|
||||
boolean hasQuit();
|
||||
void quit(Game game);
|
||||
boolean hasTimerTimeout();
|
||||
void timerTimeout(Game game);
|
||||
boolean hasIdleTimeout();
|
||||
void idleTimeout(Game game);
|
||||
boolean hasLeft();
|
||||
/**
|
||||
* Player is still active in game (has not left, lost or won the game).
|
||||
|
|
|
@ -114,7 +114,10 @@ import mage.target.common.TargetDiscard;
|
|||
import mage.watchers.common.BloodthirstWatcher;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* * @param <T>
|
||||
*/
|
||||
public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Serializable {
|
||||
|
||||
private static final transient Logger log = Logger.getLogger(PlayerImpl.class);
|
||||
|
@ -160,6 +163,10 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
protected boolean left;
|
||||
// set if the player quits the complete match
|
||||
protected boolean quit;
|
||||
// set if the player lost match because of priority timeout
|
||||
protected boolean timerTimeout;
|
||||
// set if the player lost match because of idle timeout
|
||||
protected boolean idleTimeout;
|
||||
|
||||
protected RangeOfInfluence range;
|
||||
protected Set<UUID> inRange = new HashSet<>();
|
||||
|
@ -234,6 +241,8 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
|
||||
this.left = player.left;
|
||||
this.quit = player.quit;
|
||||
this.timerTimeout = player.timerTimeout;
|
||||
this.idleTimeout = player.idleTimeout;
|
||||
this.range = player.range;
|
||||
this.canGainLife = player.canGainLife;
|
||||
this.canLoseLife = player.canLoseLife;
|
||||
|
@ -288,6 +297,8 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
|
||||
this.left = player.hasLeft();
|
||||
this.quit = player.hasQuit();
|
||||
this.timerTimeout = player.hasTimerTimeout();
|
||||
this.idleTimeout = player.hasIdleTimeout();
|
||||
this.range = player.getRange();
|
||||
this.canGainLife = player.isCanGainLife();
|
||||
this.canLoseLife = player.isCanLoseLife();
|
||||
|
@ -343,7 +354,11 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
this.wins = false;
|
||||
this.loses = false;
|
||||
this.left = false;
|
||||
this.quit = false; // reset is neccessary because in tournament player will be used for each round
|
||||
// reset is neccessary because in tournament player will be used for each round
|
||||
this.quit = false;
|
||||
this.timerTimeout = false;
|
||||
this.idleTimeout = false;
|
||||
|
||||
this.passed = false;
|
||||
this.passedTurn = false;
|
||||
this.passedAllTurns = false;
|
||||
|
@ -732,7 +747,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
resetStoredBookmark(game);
|
||||
return true;
|
||||
}
|
||||
if (!game.isGameOver()) { // if player left or game is over no undo is possible - this could lead to wrong winner
|
||||
if (!game.hasEnded()) { // if player left or game is over no undo is possible - this could lead to wrong winner
|
||||
game.restoreState(bookmark);
|
||||
}
|
||||
}
|
||||
|
@ -1475,13 +1490,30 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
|
||||
@Override
|
||||
public void quit(Game game) {
|
||||
game.informPlayers(new StringBuilder(getName()).append(" quits the match.").toString());
|
||||
quit = true;
|
||||
this.concede(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void timerTimeout(Game game) {
|
||||
game.informPlayers(new StringBuilder(getName()).append(" has run out of time. Loosing the Match.").toString());
|
||||
quit = true;
|
||||
timerTimeout = true;
|
||||
this.concede(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void idleTimeout(Game game) {
|
||||
game.informPlayers(new StringBuilder(getName()).append(" has run out of time. Loosing the Match.").toString());
|
||||
quit = true;
|
||||
idleTimeout = true;
|
||||
this.concede(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void concede(Game game) {
|
||||
game.leave(playerId);
|
||||
game.gameOver(playerId);
|
||||
lost(game);
|
||||
this.left = true;
|
||||
}
|
||||
|
@ -2117,6 +2149,16 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
return quit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTimerTimeout() {
|
||||
return timerTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIdleTimeout() {
|
||||
return idleTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReachedNextTurnAfterLeaving(boolean reachedNextTurnAfterLeaving) {
|
||||
this.reachedNextTurnAfterLeaving = reachedNextTurnAfterLeaving;
|
||||
|
|
Loading…
Reference in a new issue