package escape; import escape.exception.EscapeException; import escape.initializers.LocationInitializer; import escape.initializers.PieceTypeDescriptor; import escape.initializers.RuleDescriptor; import escape.interfaces.Coordinate; import escape.interfaces.EscapePiece; import escape.enumerations.Player; import escape.interfaces.GameObserver; import escape.util.*; import escape.validation.MoveValidator; import java.util.ArrayList; import java.util.List; public class EscapeGameManagerImpl implements EscapeGameManager<Location> { public Board board; private PieceTypeDescriptor[] pieceTypes; private MoveValidator moveValidator; private boolean playerOneTurn; private RuleDescriptor[] rules; private List<GameObserver> observers = new ArrayList<>(); private int playerOneScore; private int playerTwoScore; private int scoreLimit; private boolean removeActive; private int turnCount; private int turnLimit; private boolean gameOver; private Player winner = null; public EscapeGameManagerImpl(){ board = new Board(); moveValidator = new MoveValidator(); playerOneTurn = true; playerOneScore = 0; playerTwoScore = 0; turnCount = 0; turnLimit = Integer.MAX_VALUE; scoreLimit = Integer.MAX_VALUE; removeActive = false; gameOver = false; } @Override public boolean move(Location from, Location to) { if(gameOver){ if(winner != null){ updateObservers("Game is over and " + winner.toString() + " has won"); } else{ updateObservers("Game is over and it was a draw"); } return false; } boolean valid; if(playerOneTurn){ try{ valid = moveValidator.isValid(board, from, to, Player.PLAYER1, removeActive); } catch (EscapeException exception){ updateObservers("Move Error: ", exception); valid = false; } } else{ try{ valid = moveValidator.isValid(board, from, to, Player.PLAYER2, removeActive); } catch (EscapeException exception){ updateObservers("Move Error: ", exception); valid = false; } } if(valid){ int pointsGained = board.movePiece(from,to); if(playerOneTurn){ playerOneScore += pointsGained; } else{ playerTwoScore += pointsGained; } /* if(!playerOneTurn){ turnCount += 1; }*/ turnCount += 1; playerOneTurn = !playerOneTurn; //Check endgame conditions if(playerOneScore >= scoreLimit){ updateObservers("PLAYER 1 wins"); gameOver = true; winner = Player.PLAYER1; } if(playerTwoScore >= scoreLimit){ updateObservers("PLAYER 2 wins"); gameOver = true; winner = Player.PLAYER2; } if(turnCount >= turnLimit){ if(playerOneScore > playerTwoScore){ updateObservers("PLAYER 1 wins"); winner = Player.PLAYER1; } if(playerTwoScore > playerOneScore){ updateObservers("PLAYER 2 wins"); winner = Player.PLAYER2; } else{ updateObservers("Game over in a draw"); winner = null; } gameOver = true; } // Check if each player has any pieces left if(scoreLimit == Integer.MAX_VALUE){ if(playerOneTurn && board.playerHasPieces(Player.PLAYER1)){ updateObservers("PLAYER 1 wins"); winner = Player.PLAYER1; } else if(!playerOneTurn && board.playerHasPieces(Player.PLAYER2)){ updateObservers("PLAYER 2 wins"); winner = Player.PLAYER2; } } } return valid; } @Override public EscapePiece getPieceAt(Location coordinate) { if(gameOver){ return null; } else{ return board.pieceAt(coordinate); } } @Override public Location makeCoordinate(int x, int y) { return new Location(x,y); } public void setPieceTypes(PieceTypeDescriptor[] types){ pieceTypes = types; } public void setRules(RuleDescriptor[] rules) { this.rules = rules; for(RuleDescriptor rule: rules){ switch(rule.ruleId){ case SCORE: scoreLimit = rule.ruleValue; break; case TURN_LIMIT: turnLimit = rule.ruleValue; break; case REMOVE: removeActive = true; break; } } } public void setBoard(int maxX, int maxY, Coordinate.CoordinateType boardType, LocationInitializer[] locs){ board.setBoardType(boardType); board.setMaxX(maxX); board.setMaxY(maxY); board.setImportantLocs(locs, pieceTypes); } public GameObserver addObserver(GameObserver observer){ this.observers.add(observer); return observer; } public GameObserver removeObserver(GameObserver observer){ this.observers.remove(observer); return observer; } private void updateObservers(String message){ for(GameObserver obs: observers){ obs.notify(message); } } private void updateObservers(String message, Throwable cause){ for(GameObserver obs: observers){ obs.notify(message, cause); } } }