Escape-sprowe / src / escape / EscapeGameManagerImpl.java
EscapeGameManagerImpl.java
Raw
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);
        }
    }
}