Escape-sprowe / src / escape / validation / MoveValidator.java
MoveValidator.java
Raw
package escape.validation;

import escape.Board;
import escape.enumerations.LocationType;
import escape.enumerations.Player;
import escape.exception.EscapeException;
import escape.util.GamePiece;
import escape.util.Location;

import static escape.interfaces.EscapePiece.PieceAttributeID.*;

public class MoveValidator {

    public boolean isValid(Board board, Location from, Location to, Player player, boolean remove) throws EscapeException{
        return pieceExists(board, from, to) && isOwned(board, from, player)
                && withinBounds(board, from, to) && validDest(board,from, to, remove) && inRange(board, from, to);
    }

    /**
     * Checks that there is a piece at a point and that we are not moving in place
     *
     * @param board
     * @param from
     * @param to
     * @return true if piece exists and we are moving.
     * @throws EscapeException
     */
    private boolean pieceExists(Board board, Location from, Location to) throws EscapeException{

        if ((from.getX() != to.getX() || from.getY() != to.getY()) && board.pieceAt(from) != null) {
            return true;
        }

        if(!(from.getX() != to.getX() || from.getY() != to.getY())){
            throw new EscapeException("Cannot move in place");
        }
        if(board.pieceAt(from) == null){
            throw new EscapeException("There is no piece on this space");
        }

        return false;
    }

    /**
     * Checks for ownership of a piece at the given location
     * @param board
     * @param from
     * @param player
     * @return true if owned
     * @throws EscapeException
     */
    private boolean isOwned(Board board, Location from, Player player) throws EscapeException{
        Player owner = board.pieceAt(from).getPlayer();
        if(owner == null || owner != player){
            throw new EscapeException("This piece is not owned by the current player");
        }
        return true;
    }

    /**
     * Checks that our move stays within the board bounds
     * I wrote this before I remembered that we don't have to check for it
     * @param board
     * @param from
     * @param to
     * @return true if in bounds, false otherwise
     * @throws EscapeException
     */
    private boolean withinBounds(Board board, Location from, Location to) throws EscapeException{
        boolean fromIn = false;
        boolean toIn = false;

        switch (board.getBoardType()) {
            case SQUARE:
                fromIn = (from.getX() <= board.getMaxX() && from.getX() > 0) &&
                        (from.getY() <= board.getMaxY() && from.getY() > 0);
                toIn = (to.getX() <= board.getMaxX() && to.getX() > 0) &&
                        (to.getY() <= board.getMaxY() && to.getY() > 0);
                break;
            case HEX:
                fromIn = (from.getX() <= board.getMaxX() && from.getX() >= (-1 * board.getMaxX())) &&
                        (from.getY() <= board.getMaxY() && from.getY() >= (-1 * board.getMaxY()));
                toIn = (from.getX() <= board.getMaxX() && from.getX() >= (-1 * board.getMaxX())) &&
                        (from.getY() <= board.getMaxY() && from.getY() >= (-1 * board.getMaxY()));
                break;
        }

        if(!(fromIn && toIn)){
            throw new EscapeException("Out of bounds");
        }
        return true;
    }

    /**
     * Asks PathFinder if a path exists that is in the Piece's range.
     * @param board
     * @param from
     * @param to
     * @return true if 'to' is in range, false otherwise
     * @throws EscapeException
     */
    private boolean inRange(Board board, Location from, Location to) throws EscapeException{
        PathFinder pathFinder = new PathFinder();
        if(!pathFinder.getPath(board, from, to)){
            throw new EscapeException("No path available");
        }
        return true;
    }

    /**
     * Checks if the destination is valid (not occupied by a piece or block)
     * If destination has a piece, only valid if remove is active
     * @param board
     * @param to
     * @return true if destination is valid, false otherwise
     * @throws EscapeException
     */
    private boolean validDest(Board board, Location from, Location to, boolean removeActive) throws EscapeException{
        GamePiece piece = board.pieceAt(to);
        Player owner = board.pieceAt(from).getPlayer();
        LocationType type = board.getLocationType(to);

        if(type == LocationType.BLOCK){
            throw new EscapeException("Cannot land on Block locations");
        }
        else if((piece != null && owner!= null) && piece.getPlayer() != owner && removeActive){
            return true;
        }
        if(piece != null){
            throw new EscapeException("Cannot land on a piece");
        }
        else return true;
    }

}