2
\$\begingroup\$

Right now, the purpose of this java program is to correctly move chess pieces with a driver class.

ChessBoard.java

import java.util.ArrayList;

public class ChessBoard implements ChessBoardInterface {

    protected Square[][] board;
    protected ArrayList<Piece> whitePieces;
    protected ArrayList<Piece> blackPieces;
    private boolean turn;
    private int BOARD_SIZE = 8;

    public ChessBoard() {
        turn = true;
        whitePieces = new ArrayList<Piece>();
        blackPieces = new ArrayList<Piece>();
        board = new Square[BOARD_SIZE][BOARD_SIZE];
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[i].length; j++) {
                // Row range 1-8 iterator has to be > 0, Col range 0-7 iterator has to be > -1
                // or <= BOARD_SIZE
                String squareNote = String.valueOf((char) ('a' + j) + "" + ((BOARD_SIZE) - i));
                Square newSquare = new Square(squareNote);
                board[i][j] = newSquare;
                if ((BOARD_SIZE - i) == 2) {
                    Pawn newPawn = new Pawn("P", true, newSquare);
                    whitePieces.add(newPawn);
                    newSquare.setPiece(newPawn);
                } else if ((BOARD_SIZE - i) == 7) {
                    Pawn newPawn = new Pawn("P", false, newSquare);
                    blackPieces.add(newPawn);
                    newSquare.setPiece(newPawn);
                } else if ((BOARD_SIZE - i) == 1 && (('a' + j) == 'a' || ('a' + j) == 'h')) {
                    Rook newRook = new Rook("R", true, newSquare);
                    whitePieces.add(newRook);
                    newSquare.setPiece(newRook);
                } else if ((BOARD_SIZE - i) == 8 && (('a' + j) == 'a' || ('a' + j) == 'h')) {
                    Rook newRook = new Rook("R", false, newSquare);
                    blackPieces.add(newRook);
                    newSquare.setPiece(newRook);
                } else if ((BOARD_SIZE - i) == 1 && (('a' + j) == 'b' || ('a' + j) == 'g')) {
                    Knight newKnight = new Knight("N", true, newSquare);
                    whitePieces.add(newKnight);
                    newSquare.setPiece(newKnight);
                } else if ((BOARD_SIZE - i) == 8 && (('a' + j) == 'b' || ('a' + j) == 'g')) {
                    Knight newKnight = new Knight("N", false, newSquare);
                    blackPieces.add(newKnight);
                    newSquare.setPiece(newKnight);
                } else if ((BOARD_SIZE - i) == 1 && (('a' + j) == 'c' || ('a' + j) == 'f')) {
                    Bishop newBishop = new Bishop("B", true, newSquare);
                    whitePieces.add(newBishop);
                    newSquare.setPiece(newBishop);
                } else if ((BOARD_SIZE - i) == 8 && (('a' + j) == 'c' || ('a' + j) == 'f')) {
                    Bishop newBishop = new Bishop("B", false, newSquare);
                    blackPieces.add(newBishop);
                    newSquare.setPiece(newBishop);
                } else if ((BOARD_SIZE - i) == 1 && (('a' + j) == 'e')) {
                    King newKing = new King("K", true, newSquare);
                    whitePieces.add(newKing);
                    newSquare.setPiece(newKing);
                } else if ((BOARD_SIZE - i) == 8 && (('a' + j) == 'e')) {
                    King newKing = new King("K", false, newSquare);
                    blackPieces.add(newKing);
                    newSquare.setPiece(newKing);
                } else if ((BOARD_SIZE - i) == 1 && (('a' + j) == 'd')) {
                    Queen newQueen = new Queen("Q", true, newSquare);
                    whitePieces.add(newQueen);
                    newSquare.setPiece(newQueen);
                } else if ((BOARD_SIZE - i) == 8 && (('a' + j) == 'd')) {
                    Queen newQueen = new Queen("Q", false, newSquare);
                    blackPieces.add(newQueen);
                    newSquare.setPiece(newQueen);
                }
            }
        }

        // for (int i = 0; i < whitePieces.size(); i++) {
        // if (whitePieces.get(i).getSquare().getSquareNotation().equals("e2")) {
        // whitePieces.remove(i);
        // }
        //
        // }
        // getSquare("e2").getSquarePiece().setSquare(null);
        // getSquare("e2").setPiece(null);

        for (int i = 0; i < whitePieces.size(); i++) {
            whitePieces.get(i).generatePossibleMoves(this);

        }
        for (int i = 0; i < blackPieces.size(); i++) {
            blackPieces.get(i).generatePossibleMoves(this);

        }
    }

    @Override
    public Square getSquare(String notation) {
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[i].length; j++) {
                if (board[i][j].getSquareNotation().equals(notation)) {
                    return board[i][j];
                }
            }
        }
        return null;
    }

    @Override
    public ArrayList<Piece> getWhitePieces() {
        ArrayList<Piece> retWhitePieces = whitePieces;
        return retWhitePieces;
    }

    @Override
    public ArrayList<Piece> getBlackPieces() {
        ArrayList<Piece> retBlackPieces = blackPieces;
        return retBlackPieces;
    }

    public boolean getTurn() {
        boolean retTurn = turn;
        return retTurn;
    }

    @Override
    public void move(String pieceType, String toNotation) {

        if (getTurn() == true) {
            for (int i = 0; i < whitePieces.size(); i++) {
                if (whitePieces.get(i).getType().equals(pieceType)
                        && whitePieces.get(i).getPossibleMoves().contains(toNotation)) {
                    movePiece(whitePieces.get(i), whitePieces.get(i).getSquare(), toNotation);
                    whitePieces.get(i).setFirstMove(false);
                    if (kingLeftInCheck()) {
                        throw new IllegalStateException();
                    }
                }
            }
        } else {
            for (int i = 0; i < blackPieces.size(); i++) {
                if (blackPieces.get(i).getType().equals(pieceType)
                        && blackPieces.get(i).getPossibleMoves().contains(toNotation)) {
                    movePiece(blackPieces.get(i), blackPieces.get(i).getSquare(), toNotation);
                    blackPieces.get(i).setFirstMove(false);
                    if (kingLeftInCheck()) {
                        throw new IllegalStateException();
                    }
                }
            }
        }
    }

    public void movePiece(Piece piece, Square fromSquare, String toNotation) {
        ArrayList<Piece> currentMove = null;
        int turnInt; // 1 for white, 0 for black
        if (getTurn() == false) {
            turnInt = 1;
        } else {
            turnInt = 0;
        }
        switch (turnInt) {
        case 0:
            currentMove = blackPieces;
            break;
        case 1:
            currentMove = whitePieces;
            break;
        }

        if (toNotation.equals("0-0")) {
            int squareNotationCol = Integer.parseInt(fromSquare.getSquareNotation().substring(1, 2));
            String squareNoteOverOne = String
                    .valueOf((char) (fromSquare.getSquareNotation().charAt(0) + 1) + "" + (squareNotationCol));
            String squareNoteOverTwo = String
                    .valueOf((char) (fromSquare.getSquareNotation().charAt(0) + 2) + "" + (squareNotationCol));
            String squareNoteOverThree = String
                    .valueOf((char) (fromSquare.getSquareNotation().charAt(0) + 3) + "" + (squareNotationCol));

            Square rookFromSquare = getSquare(squareNoteOverThree);
            Square kingFromSquare = fromSquare;
            Square rookToSquare = getSquare(squareNoteOverOne);
            Square kingToSquare = getSquare(squareNoteOverTwo);

            kingToSquare.setPiece(kingFromSquare.getSquarePiece());
            kingFromSquare.getSquarePiece().setSquare(kingToSquare);
            rookToSquare.setPiece(rookFromSquare.getSquarePiece());
            rookFromSquare.getSquarePiece().setSquare(rookToSquare);
            rookFromSquare.setPiece(null);
            kingFromSquare.setPiece(null);

        } else if (toNotation.equals("0-0-0")) {
            int squareNotationCol = Integer.parseInt(fromSquare.getSquareNotation().substring(1, 2));
            String squareNoteOverOne = String
                    .valueOf((char) (fromSquare.getSquareNotation().charAt(0) + 1) + "" + (squareNotationCol));
            String squareNoteOverTwo = String
                    .valueOf((char) (fromSquare.getSquareNotation().charAt(0) + 2) + "" + (squareNotationCol));
            String squareNoteOverFour = String
                    .valueOf((char) (fromSquare.getSquareNotation().charAt(0) + 4) + "" + (squareNotationCol));

            Square rookFromSquare = getSquare(squareNoteOverFour);
            Square kingFromSquare = fromSquare;
            Square rookToSquare = getSquare(squareNoteOverOne);
            Square kingToSquare = getSquare(squareNoteOverTwo);

            kingToSquare.setPiece(kingFromSquare.getSquarePiece());
            kingFromSquare.getSquarePiece().setSquare(kingToSquare);
            rookToSquare.setPiece(rookFromSquare.getSquarePiece());
            rookFromSquare.getSquarePiece().setSquare(rookToSquare);
            rookFromSquare.setPiece(null);
            kingFromSquare.setPiece(null);

        } else if (piece.getType().equals("P")
                && (toNotation.substring(1, 2).equals("8") || toNotation.substring(1, 2).equals("1"))) {
            char promoteTo = toNotation.charAt(toNotation.length() - 1);
            int representsPieceType = promoteTo - 'A';
            Piece newPiece = null;
            Square toSquare = getSquare(toNotation.substring(0, toNotation.length() - 1));

            switch (representsPieceType) {
            case 16:
                newPiece = new Queen("Q", piece.getColor(), toSquare);
                break;
            case 1:
                newPiece = new Bishop("B", piece.getColor(), toSquare);
                break;
            case 17:
                newPiece = new Rook("R", piece.getColor(), toSquare);
                break;
            case 13:
                newPiece = new Knight("N", piece.getColor(), toSquare);
                break;
            }

            fromSquare.setPiece(null);
            piece.setSquare(null);

            if (turn == true) {
                for (int i = 0; i < whitePieces.size(); i++) {
                    if (whitePieces.get(i).equals(piece)) {
                        whitePieces.remove(i);
                        whitePieces.add(newPiece);
                    }
                }
            } else {
                for (int i = 0; i < blackPieces.size(); i++) {
                    if (blackPieces.get(i).equals(piece)) {
                        blackPieces.remove(i);
                        blackPieces.add(newPiece);
                    }
                }
            }

            if (toSquare.getSquarePiece() != null && toSquare.getSquarePiece().getColor() != piece.getColor()) {
                for (int i = 0; i < currentMove.size(); i++) {
                    if (currentMove.get(i).equals(toSquare.getSquarePiece())) {
                        currentMove.remove(i);
                    }
                }
            }
            toSquare.setPiece(newPiece);

        } else {
            Square toSquare = getSquare(toNotation);
            fromSquare.setPiece(null);

            // for enpassant
            char offSetCol = toSquare.getSquareNotation().charAt(0);
            int offSetRow = Integer.parseInt(toSquare.getSquareNotation().substring(1, 2));
            if (toSquare.getSquarePiece() != null && toSquare.getSquarePiece().getColor() != piece.getColor()) {
                for (int i = 0; i < currentMove.size(); i++) {
                    if (currentMove.get(i).equals(toSquare.getSquarePiece())) {
                        currentMove.remove(i);
                    }
                }
            } else if (piece.getType().equals("P") && toSquare.getSquarePiece() == null
                    && offSetCol != piece.getSquare().getSquareNotation().charAt(0)) {
                Square enPassantPieceTaken = getSquare(offSetCol + "" + (offSetRow
                        - (offSetRow - Integer.parseInt(piece.getSquare().getSquareNotation().substring(1, 2)))));
                for (int i = 0; i < currentMove.size(); i++) {
                    if (currentMove.get(i).getSquare().equals(enPassantPieceTaken)) {
                        enPassantPieceTaken.getSquarePiece().setSquare(null);
                        enPassantPieceTaken.setPiece(null);
                        currentMove.remove(i);
                    }
                }
            }

            piece.setSquare(toSquare);
            toSquare.setPiece(piece);
        }
        turn = !turn;

        for (int i = 0; i < whitePieces.size(); i++) {
            whitePieces.get(i).generatePossibleMoves(this);

        }
        for (int i = 0; i < blackPieces.size(); i++) {
            blackPieces.get(i).generatePossibleMoves(this);

        }

        if (piece.getType().equals("P") && piece.getFirstMove() == true
                && (toNotation.substring(1, 2).equals("4") || toNotation.substring(1, 2).equals("5"))) {
            piece.setEnPassant(true);
        }
        addEnPassantMoves();
        addCastlingMoves();

    }

    public void addCastlingMoves() {

        if (turn == true) {
            String castleShortOneOver = "";
            String castleLongOneOver = "";
            for (int k = 0; k < whitePieces.size(); k++) {
                if (whitePieces.get(k).getType().equals("K")) {
                    Piece tempPiece = whitePieces.get(k);
                    int squareNotationCol = Integer
                            .parseInt(whitePieces.get(k).getSquare().getSquareNotation().substring(1, 2));
                    castleShortOneOver = String
                            .valueOf((char) (whitePieces.get(k).getSquare().getSquareNotation().charAt(0) + 1) + ""
                                    + (squareNotationCol));
                    castleLongOneOver = String
                            .valueOf((char) (whitePieces.get(k).getSquare().getSquareNotation().charAt(0) - 1) + ""
                                    + (squareNotationCol));

                    if (!checkIfCheck(whitePieces.get(k).getSquare().getSquareNotation())
                            && !checkIfCheck(castleShortOneOver)
                            && castleRightsShort(tempPiece, tempPiece.getSquare())) {
                        whitePieces.get(k).addPossibleMove("0-0");
                    } else if (!checkIfCheck(whitePieces.get(k).getSquare().getSquareNotation())
                            && !checkIfCheck(castleLongOneOver) && castleRightsLong(tempPiece, tempPiece.getSquare())) {
                        whitePieces.get(k).addPossibleMove("0-0-0");
                    }
                }
            }
        } else {
            String castleShortOneOver = "";
            String castleLongOneOver = "";
            for (int k = 0; k < blackPieces.size(); k++) {
                if (blackPieces.get(k).getType().equals("K")) {
                    Piece tempPiece = blackPieces.get(k);
                    int squareNotationCol = Integer
                            .parseInt(blackPieces.get(k).getSquare().getSquareNotation().substring(1, 2));
                    castleShortOneOver = String
                            .valueOf((char) (blackPieces.get(k).getSquare().getSquareNotation().charAt(0) + 1) + ""
                                    + (squareNotationCol));
                    castleLongOneOver = String
                            .valueOf((char) (blackPieces.get(k).getSquare().getSquareNotation().charAt(0) - 1) + ""
                                    + (squareNotationCol));

                    if (!checkIfCheck(blackPieces.get(k).getSquare().getSquareNotation())
                            && !checkIfCheck(castleShortOneOver)
                            && castleRightsShort(tempPiece, tempPiece.getSquare())) {
                        blackPieces.get(k).addPossibleMove("0-0");
                    } else if (!checkIfCheck(blackPieces.get(k).getSquare().getSquareNotation())
                            && !checkIfCheck(castleLongOneOver) && castleRightsLong(tempPiece, tempPiece.getSquare())) {
                        blackPieces.get(k).addPossibleMove("0-0-0");
                    }
                }
            }
        }
    }

    public boolean castleRightsLong(Piece movePiece, Square curSquare) {
        int squareNotationCol = Integer.parseInt(curSquare.getSquareNotation().substring(1, 2));
        String squareNoteOverOne = String
                .valueOf((char) (curSquare.getSquareNotation().charAt(0) + 1) + "" + (squareNotationCol));
        String squareNoteOverTwo = String
                .valueOf((char) (curSquare.getSquareNotation().charAt(0) + 2) + "" + (squareNotationCol));
        String squareNoteOverThree = String
                .valueOf((char) (curSquare.getSquareNotation().charAt(0) + 3) + "" + (squareNotationCol));
        String squareNoteOverFour = String
                .valueOf((char) (curSquare.getSquareNotation().charAt(0) + 4) + "" + (squareNotationCol));

        if (movePiece.getFirstMove() == true && getSquare(squareNoteOverOne).getSquarePiece() == null
                && getSquare(squareNoteOverTwo).getSquarePiece() == null
                && getSquare(squareNoteOverThree).getSquarePiece() == null
                && getSquare(squareNoteOverFour).getSquarePiece().getType().equals("R")
                && getSquare(squareNoteOverFour).getSquarePiece().getFirstMove() == true) {
            return true;
        } else {
            return false;
        }
    }

    public boolean castleRightsShort(Piece movePiece, Square curSquare) {
        int squareNotationCol = Integer.parseInt(curSquare.getSquareNotation().substring(1, 2));
        String squareNoteOverOne = String
                .valueOf((char) (curSquare.getSquareNotation().charAt(0) + 1) + "" + (squareNotationCol));
        String squareNoteOverTwo = String
                .valueOf((char) (curSquare.getSquareNotation().charAt(0) + 2) + "" + (squareNotationCol));
        String squareNoteOverThree = String
                .valueOf((char) (curSquare.getSquareNotation().charAt(0) + 3) + "" + (squareNotationCol));

        if (movePiece.getFirstMove() == true && getSquare(squareNoteOverOne).getSquarePiece() == null
                && getSquare(squareNoteOverTwo).getSquarePiece() == null
                && getSquare(squareNoteOverThree).getSquarePiece().getType().equals("R")
                && getSquare(squareNoteOverThree).getSquarePiece().getFirstMove() == true) {
            return true;
        } else {
            return false;
        }
    }

    public boolean checkIfCheck(String squareNotation) {
        if (turn == true) {
            for (int i = 0; i < blackPieces.size(); i++) {
                ArrayList<String> tempBlackMoves = blackPieces.get(i).getPossibleMoves();
                for (int j = 0; j < tempBlackMoves.size(); j++) {
                    if (tempBlackMoves.get(j).contains(squareNotation)) {
                        return true;
                    }
                }
            }
        } else {
            for (int i = 0; i < whitePieces.size(); i++) {
                ArrayList<String> tempWhiteMoves = whitePieces.get(i).getPossibleMoves();
                for (int j = 0; j < tempWhiteMoves.size(); j++) {
                    if (tempWhiteMoves.get(j).contains(squareNotation)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public void addEnPassantMoves() {
        if (turn == true) {
            for (int i = 0; i < whitePieces.size(); i++) {
                if (whitePieces.get(i).getType().equals("P")
                        && whitePieces.get(i).getSquare().getSquareNotation().substring(1, 2).equals("5")) {
                    for (int j = 0; j < blackPieces.size(); j++) {
                        if (blackPieces.get(j).getType().equals("P") && blackPieces.get(j).getEnPassant() == true) {
                            char offSetCol = blackPieces.get(j).getSquare().getSquareNotation().charAt(0);
                            int offSetRow = Integer
                                    .parseInt(blackPieces.get(j).getSquare().getSquareNotation().substring(1, 2));
                            whitePieces.get(i).addPossibleMove(offSetCol + "" + (offSetRow + 1));
                        }
                    }
                }
            }
        } else {
            for (int i = 0; i < blackPieces.size(); i++) {
                if (blackPieces.get(i).getType().equals("P")
                        && blackPieces.get(i).getSquare().getSquareNotation().substring(1, 2).equals("5")) {
                    for (int j = 0; j < blackPieces.size(); j++) {
                        if (whitePieces.get(j).getType().equals("P") && whitePieces.get(j).getEnPassant() == true) {
                            char offSetCol = whitePieces.get(j).getSquare().getSquareNotation().charAt(0);
                            int offSetRow = Integer
                                    .parseInt(whitePieces.get(j).getSquare().getSquareNotation().substring(1, 2));
                            blackPieces.get(i).addPossibleMove(offSetCol + "" + (offSetRow - 1));
                        }
                    }
                }
            }
        }

    }

    public boolean kingLeftInCheck() {
        int turnInt; // 1 for white, 0 for black
        ArrayList<Piece> lastMoved = null;
        boolean leftInCheck = false;
        boolean lastMovedColor = !getTurn();
        if (getTurn() == false) {
            turnInt = 1;
        } else {
            turnInt = 0;
        }
        switch (turnInt) {
        case 0:
            lastMoved = blackPieces;
            break;
        case 1:
            lastMoved = whitePieces;
            break;
        }

        String kingSquareNotation = "";
        for (int i = 0; i < lastMoved.size(); i++) {
            if (lastMoved.get(i).getType().equals("K")) {
                kingSquareNotation = lastMoved.get(i).getSquare().getSquareNotation();
            }
        }
        int offSetCol = kingSquareNotation.charAt(0) - 97;
        int offSetRow = Integer.parseInt(kingSquareNotation.substring(1, 2));

        // all possible moves in the up
        for (int i = offSetRow + 1; i <= board.length; i++) {
            String squareNote = String.valueOf((char) ('a' + offSetCol) + "" + (i));
            Square square = getSquare(squareNote);
            if (square.getSquarePiece() == null) {
                ;
            } else if ((square.getSquarePiece().getColor() == lastMovedColor
                    || !square.getSquarePiece().getType().equals("Q"))
                    && !square.getSquarePiece().getType().equals("R")) {
                break;
            } else if (square.getSquarePiece().getColor() != lastMovedColor
                    && square.getSquarePiece().getType().equals("Q") || square.getSquarePiece().getType().equals("R")) {
                leftInCheck = true;
                break;
            }
        }

        // all possible moves in the down
        for (int i = offSetRow - 1; i > 0; i--) {
            String squareNote = String.valueOf((char) ('a' + offSetCol) + "" + (i));
            Square square = getSquare(squareNote);
            if (square.getSquarePiece() == null) {
                ;
            } else if (square.getSquarePiece().getColor() == lastMovedColor
                    || !square.getSquarePiece().getType().equals("Q")
                            && !square.getSquarePiece().getType().equals("R")) {
                break;
            } else if (square.getSquarePiece().getColor() != lastMovedColor
                    && square.getSquarePiece().getType().equals("Q") || square.getSquarePiece().getType().equals("R")) {
                leftInCheck = true;
                break;
            }
        }

        // all possible moves to the right
        for (int i = offSetCol + 1; i < board.length; i++) {
            String squareNote = String.valueOf((char) ('a' + i) + "" + (offSetRow));
            Square square = getSquare(squareNote);
            if (square.getSquarePiece() == null) {
                ;
            } else if (square.getSquarePiece().getColor() == lastMovedColor
                    || !square.getSquarePiece().getType().equals("Q")
                            && !square.getSquarePiece().getType().equals("R")) {
                break;
            } else if (square.getSquarePiece().getColor() != lastMovedColor
                    && square.getSquarePiece().getType().equals("Q") || square.getSquarePiece().getType().equals("R")) {
                leftInCheck = true;
                break;
            }
        }

        // all possible moves to the left
        for (int i = offSetCol - 1; i > -1; i--) {
            String squareNote = String.valueOf((char) ('a' + i) + "" + (offSetRow));
            Square square = getSquare(squareNote);
            if (square.getSquarePiece() == null) {
                ;
            } else if (square.getSquarePiece().getColor() == lastMovedColor
                    || !square.getSquarePiece().getType().equals("Q")
                            && !square.getSquarePiece().getType().equals("R")) {
                break;
            } else if (square.getSquarePiece().getColor() != lastMovedColor
                    && square.getSquarePiece().getType().equals("Q") || square.getSquarePiece().getType().equals("R")) {
                leftInCheck = true;
                break;
            }
        }

        char offSetCharCol = kingSquareNotation.charAt(0);

        //////
        // Pawn attack
        //////
        final int PAWN_MOVE_ROWNUM = 3;
        final int PAWN_MOVE_COLNUM = 2;
        int[][] offsets;
        if (lastMovedColor == true) {
            offsets = new int[PAWN_MOVE_ROWNUM][PAWN_MOVE_COLNUM];
            // capture moves
            offsets[1][0] = 1;
            offsets[1][1] = 1;
            offsets[2][0] = 1;
            offsets[2][1] = -1;
        } else {
            offsets = new int[PAWN_MOVE_ROWNUM][PAWN_MOVE_COLNUM];

            // capture moves
            offsets[1][0] = -1;
            offsets[1][1] = 1;
            offsets[2][0] = -1;
            offsets[2][1] = -1;
        }

        for (int[] o : offsets) {
            if (offSetCharCol + o[1] >= 'a' && offSetCharCol + o[1] <= 'h' && offSetRow + o[0] > 0
                    && offSetRow + o[0] < 9) {
                String squareNote = String.valueOf((char) (offSetCharCol + o[1]) + "" + (offSetRow + o[0]));
                Square square = getSquare(squareNote);
                if (square.getSquarePiece() != null && square.getSquarePiece().getColor() != lastMovedColor
                        && square.getSquarePiece().getType().equals("P")) {
                    leftInCheck = true;
                }
            }
        }

        //////
        // Bishop attack
        //////

        // all possible moves in the down positive diagonal
        for (int j = offSetCol + 1, i = offSetRow + 1; j < board.length && i <= board.length; j++, i++) {
            String squareNote = String.valueOf((char) ('a' + j) + "" + (i));
            Square square = getSquare(squareNote);
            if (square.getSquarePiece() == null) {
                ;
            } else if (square.getSquarePiece().getColor() == lastMovedColor
                    || !square.getSquarePiece().getType().equals("B")
                            && !square.getSquarePiece().getType().equals("Q")) {
                break;
            } else if (square.getSquarePiece().getColor() != lastMovedColor
                    && (square.getSquarePiece().getType().equals("Q")
                            || square.getSquarePiece().getType().equals("B"))) {
                leftInCheck = true;
                break;
            }
        }

        // all possible moves in the up positive diagonal
        for (int j = offSetCol - 1, i = offSetRow + 1; j > -1 && i <= board.length; j--, i++) {
            String squareNote = String.valueOf((char) ('a' + j) + "" + (i));
            Square square = getSquare(squareNote);
            if (square.getSquarePiece() == null) {
                ;
            } else if (square.getSquarePiece().getColor() == lastMovedColor
                    || !square.getSquarePiece().getType().equals("B")
                            && !square.getSquarePiece().getType().equals("Q")) {
                break;
            } else if (square.getSquarePiece().getColor() != lastMovedColor
                    && (square.getSquarePiece().getType().equals("Q")
                            || square.getSquarePiece().getType().equals("B"))) {
                leftInCheck = true;
                break;
            }
        }

        // all possible moves in the up negative diagonal
        for (int j = offSetCol - 1, i = offSetRow - 1; j > -1 && i > 0; j--, i--) {
            String squareNote = String.valueOf((char) ('a' + j) + "" + (i));
            Square square = getSquare(squareNote);
            if (square.getSquarePiece() == null) {
                ;
            } else if (square.getSquarePiece().getColor() == lastMovedColor
                    || !square.getSquarePiece().getType().equals("B")
                            && !square.getSquarePiece().getType().equals("Q")) {
                break;
            } else if (square.getSquarePiece().getColor() != lastMovedColor
                    && (square.getSquarePiece().getType().equals("Q")
                            || square.getSquarePiece().getType().equals("B"))) {
                leftInCheck = true;
                break;
            }
        }

        // all possible moves in the down negative diagonal
        for (int j = offSetCol + 1, i = offSetRow - 1; j < board.length && i > 0; j++, i--) {
            String squareNote = String.valueOf((char) ('a' + j) + "" + (i));
            Square square = getSquare(squareNote);
            if (square.getSquarePiece() == null) {
                ;
            } else if (square.getSquarePiece().getColor() == lastMovedColor
                    || !square.getSquarePiece().getType().equals("B")
                            && !square.getSquarePiece().getType().equals("Q")) {
                break;
            } else if (square.getSquarePiece().getColor() != lastMovedColor
                    && (square.getSquarePiece().getType().equals("Q")
                            || square.getSquarePiece().getType().equals("B"))) {
                leftInCheck = true;
                break;
            }
        }

        //////
        // Knight attack
        //////

        int[][] offsetsKnight = { { -2, 1 }, { -1, 2 }, { 1, 2 }, { 2, 1 }, { 2, -1 }, { 1, -2 }, { -1, -2 },
                { -2, -1 } };

        for (int[] o : offsetsKnight) {
            if (offSetCharCol + o[0] >= 'a' && offSetCharCol + o[0] <= 'h' && offSetRow + o[1] > 0
                    && offSetRow + o[1] < 9) {
                String squareNote = String.valueOf((char) (offSetCharCol + o[0]) + "" + (offSetRow + o[1]));
                Square square = getSquare(squareNote);
                if (square.getSquarePiece() != null && square.getSquarePiece().getColor() != lastMovedColor
                        && square.getSquarePiece().getType().equals("N")) {
                    leftInCheck = true;
                }
            }
        }

        return leftInCheck;
    }

    @Override
    public String toString() {

        String retString = "";
        for (int i = 0; i < BOARD_SIZE; i++) {
            if (i != BOARD_SIZE) {
                retString += "[ ";
            }
            for (int j = 0; j < BOARD_SIZE; j++) {
                retString += board[i][j];
                if (j != BOARD_SIZE - 1) {
                    retString += " , ";
                }
                if (j == BOARD_SIZE - 1) {
                    retString += "]\n";
                }
            }
        }
        if (turn == true) {
            retString += "\n";

            for (int i = 0; i < whitePieces.size(); i++) {

                retString += " " + whitePieces.get(i);
            }
        } else {
            retString += "\n";

            for (int i = 0; i < blackPieces.size(); i++) {

                retString += " " + blackPieces.get(i);
            }

        }
        retString += "\n";
        return retString;
    }
}

Piece Interface

public interface PieceInterface {

    /**
     * Returns the possible moves for a piece. The moves are returned in a array list
     * of type string with the possible move represented as chess notation.
     * 
     * @return the array list containing the possible moves
     */
    public ArrayList<String> getPossibleMoves();

    /**
     * Generates the possible moves for a piece on a specific chess board.
     * 
     * @param curBoard the current board to generate possible moves from
     */
    public void generatePossibleMoves(ChessBoard curBoard);

    /**
     * Removes an illegal move from the array list of possible moves for a piece.
     * 
     * @param illegalMove the String containing the illegal move
     */
    public void removePossibleMove(String illegalMove);

    /**
     * Adds a move to the array list of possible moves for a piece.
     * 
     * @param addMove the String containing the move you want to add
     */
    public void addPossibleMove(String addMove);

    /**
     * Returns a the first letter of the name of this piece. I.e, a piece of type
     * Rook will return an "R" String.
     * 
     * @return the type of piece
     */
    public String getType();

    /**
     * Returns the color of the piece as a boolean.  True represents white and false
     * represents black.
     * 
     * @return the color of the piece
     */
    public boolean getColor();

    /**
     * Sets the square that this piece is currently occupying.
     * 
     * @param square the square that this piece currently occupies
     */
    public void setSquare(Square square);

    /**
     * Gets the status of whether or not the piece has moved.
     * 
     * @return true if piece has not moved and false if piece has moved
     */
    public boolean getFirstMove();

    /**
     * Sets the status of whether or not the piece has moved.
     * 
     * @param didMove the status of the piece moving.
     */
    public void setFirstMove(boolean didMove);

    /**
     * Returns the square that this piece is currently occupying.
     * 
     * @return the square this piece occupies
     */
    public Square getSquare();

    /**
     * Returns a boolean that describes whether this piece enables en passant for the opposing
     * side. The boolean will be true if the piece is of type Pawn and the pawn just made its
     * first move and moved two ranks. Otherwise, returns false.
     * 
     * @return the status of whether this piece enables en passant
     */
    public boolean getEnPassant();

    /**
     * Returns a boolean that describes whether this piece enables en passant for the opposing
     * side. The boolean will be true if the piece is of type Pawn and the pawn just made its
     * first move and moved two ranks. Otherwise, returns false.
     * 
     * @param enPassant the status of the piece enabling enPassant
     */
    public void setEnPassant(boolean enPassant);
}

Piece

import java.util.ArrayList;

public abstract class Piece implements PieceInterface {


    @Override
    public abstract ArrayList<String> getPossibleMoves();

    @Override
    public abstract String getType();

    @Override
    public abstract void setSquare(Square square);

    @Override
    public abstract Square getSquare();

    @Override
    public abstract void generatePossibleMoves(ChessBoard curBoard);

    @Override
    public abstract void removePossibleMove(String illegalMove);

    @Override
    public abstract void addPossibleMove(String addMove);

    @Override
    public abstract boolean getFirstMove();

    @Override
    public abstract void setFirstMove(boolean didMove);

    @Override
    public abstract boolean getEnPassant();

    @Override
    public abstract void setEnPassant(boolean enPassant);

}

Bishop

import java.util.ArrayList;

public class Bishop extends Piece {

    private final boolean COLOR;
    private Square curSquare;
    private final String TYPE;
    private ArrayList<String> possibleMoves;
    private boolean firstMove;

    public Bishop(String type, boolean color, Square curSquare) {
        this.TYPE = type;
        this.COLOR = color;
        this.curSquare = curSquare;
        firstMove = true;
    }

    @Override
    public ArrayList<String> getPossibleMoves() {
        ArrayList<String> retPossibleMoves = possibleMoves;
        return retPossibleMoves;
    }

    @Override
    public boolean getColor() {
        boolean retColor = COLOR;
        return retColor;
    }

    @Override
    public void generatePossibleMoves(ChessBoard curBoard) {
        possibleMoves = new ArrayList<String>();
        int offSetCol = curSquare.getSquareNotation().charAt(0) - 97;
        int offSetRow = Integer.parseInt(curSquare.getSquareNotation().substring(1, 2));

        // all possible moves in the down positive diagonal
        for (int j = offSetCol + 1, i = offSetRow + 1; j < curBoard.board.length
                && i <= curBoard.board.length; j++, i++) {
            String squareNote = String.valueOf((char) ('a' + j) + "" + (i));
            Square square = curBoard.getSquare(squareNote);
            if (square.getSquarePiece() == null) {
                possibleMoves.add(square.getSquareNotation());
            } else if (square.getSquarePiece().getColor() != COLOR) {
                possibleMoves.add(square.getSquareNotation());
                break;
            } else {
                break;
            }
        }

        // all possible moves in the up positive diagonal
        for (int j = offSetCol - 1, i = offSetRow + 1; j > -1 && i <= curBoard.board.length; j--, i++) {
            String squareNote = String.valueOf((char) ('a' + j) + "" + (i));
            Square square = curBoard.getSquare(squareNote);
            if (square.getSquarePiece() == null) {
                possibleMoves.add(square.getSquareNotation());
            } else if (square.getSquarePiece().getColor() != COLOR) {
                possibleMoves.add(square.getSquareNotation());
                break;
            } else {
                break;
            }
        }

        // all possible moves in the up negative diagonal
        for (int j = offSetCol - 1, i = offSetRow - 1; j > -1 && i > 0; j--, i--) {
            String squareNote = String.valueOf((char) ('a' + j) + "" + (i));
            Square square = curBoard.getSquare(squareNote);
            if (square.getSquarePiece() == null) {
                possibleMoves.add(square.getSquareNotation());
            } else if (square.getSquarePiece().getColor() != COLOR) {
                possibleMoves.add(square.getSquareNotation());
                break;
            } else {
                break;
            }
        }

        // all possible moves in the down negative diagonal
        for (int j = offSetCol + 1, i = offSetRow - 1; j < curBoard.board.length && i > 0; j++, i--) {
            String squareNote = String.valueOf((char) ('a' + j) + "" + (i));
            Square square = curBoard.getSquare(squareNote);
            if (square.getSquarePiece() == null) {
                possibleMoves.add(square.getSquareNotation());
            } else if (square.getSquarePiece().getColor() != COLOR) {
                possibleMoves.add(square.getSquareNotation());
                break;
            } else {
                break;
            }
        }
    }

    @Override
    public void removePossibleMove(String illegalMove) {
        String testIfMove = "";

        for(int i = 0; i < possibleMoves.size(); i++) {
            testIfMove = possibleMoves.get(i);
            if(testIfMove.equals(illegalMove)) {
                possibleMoves.remove(i);
                break;
            }
        }
    }

    @Override
    public String getType() {
        String retType = TYPE;
        return retType;
    }

    @Override
    public void setSquare(Square square) {
        curSquare = square;
    }

    @Override
    public Square getSquare() {
        return curSquare;
    }

    @Override
    public boolean getFirstMove() {
        boolean retFirstMove = firstMove;
        return retFirstMove;
    }

    @Override
    public void setFirstMove(boolean didMove) {
        firstMove = didMove;
    }

    @Override
    public void addPossibleMove(String addMove) {
        possibleMoves.add(addMove);
    }

    @Override
    public String toString() {
        String tempMove = "";
        for(int i = 0; i < possibleMoves.size(); i++) {
            tempMove += TYPE + possibleMoves.get(i) + " ";
        }

        if(possibleMoves.isEmpty()) {
            tempMove = "No possible moves.";
        }

        return tempMove;
    }

    @Override
    public boolean getEnPassant() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void setEnPassant(boolean enPassant) {
        // TODO Auto-generated method stub

    }

}

Pawn

import java.util.ArrayList;

public class Pawn extends Piece {

    private final boolean COLOR;
    private Square curSquare;
    private String type;
    private ArrayList<String> possibleMoves;
    private boolean enPassant;
    private boolean firstMove;
    private final int PAWN_MOVE_ROWNUM = 3;
    private final int PAWN_MOVE_COLNUM = 2;
    private final int PAWN_MOVE_ROWNUM_IF_FIRSTMOVE = 4;

    public Pawn(String type, boolean color, Square curSquare) {
        enPassant = false;
        firstMove = true;
        this.type = type;
        this.COLOR = color;
        this.curSquare = curSquare;
    }

    @Override
    public boolean getColor() {
        boolean retColor = COLOR;
        return retColor;
    }

    @Override
    public ArrayList<String> getPossibleMoves() {
        ArrayList<String> retPossibleMoves = possibleMoves;
        return retPossibleMoves;
    }

    @Override
    public void generatePossibleMoves(ChessBoard curBoard) {
        possibleMoves = new ArrayList<String>();
        enPassant = false;
        char offSetCol = curSquare.getSquareNotation().charAt(0);
        int offSetRow = Integer.parseInt(curSquare.getSquareNotation().substring(1, 2));

        int[][] offsets;
        if (COLOR == true) {
            if(firstMove == true) {
                 offsets = new int[PAWN_MOVE_ROWNUM_IF_FIRSTMOVE][PAWN_MOVE_COLNUM];
                // first move, move double
                 offsets[3][0] = 2;
                 offsets[3][1] = 0;
            } else {
                offsets = new int[PAWN_MOVE_ROWNUM][PAWN_MOVE_COLNUM];
            }
            // standard non capture move
            offsets[0][0] = 1;
            offsets[0][1] = 0;

            // capture moves
            offsets[1][0] = 1;
            offsets[1][1] = 1;
            offsets[2][0] = 1;
            offsets[2][1] = -1;
        } else {
            if(firstMove == true) {
                 offsets = new int[PAWN_MOVE_ROWNUM_IF_FIRSTMOVE][PAWN_MOVE_COLNUM];
                 // first move, move double
                 offsets[3][0] = -2;
                 offsets[3][1] = 0;
            } else {
                offsets = new int[PAWN_MOVE_ROWNUM][PAWN_MOVE_COLNUM];
            }
            // standard non capture move
            offsets[0][0] = -1;
            offsets[0][1] = 0;

            // capture moves
            offsets[1][0] = -1;
            offsets[1][1] = 1;
            offsets[2][0] = -1;
            offsets[2][1] = -1;
        }

        for (int[] o : offsets) {
            if (offSetCol + o[1] >= 'a' && offSetCol + o[1] <= 'h' && offSetRow + o[0] > 1 && offSetRow + o[0] < 8) {
                String squareNote = String.valueOf((char) (offSetCol + o[1]) + "" + (offSetRow + o[0]));
                Square square = curBoard.getSquare(squareNote);
                if ((square.getSquarePiece() == null && o[1] == 0)) {
                    possibleMoves.add(square.getSquareNotation());
                } else if (square.getSquarePiece() != null && square.getSquarePiece().getColor() != COLOR
                        && Math.abs(o[1]) == 1) {
                    possibleMoves.add(square.getSquareNotation());
                }
            } else if(offSetCol + o[1] >= 'a' && offSetCol + o[1] <= 'h' && offSetRow + o[0] == 1 || offSetRow + o[0] == 8) {
                String squareNote = String.valueOf((char) (offSetCol + o[1]) + "" + (offSetRow + o[0]));
                Square square = curBoard.getSquare(squareNote);
                String[] promotionPiece = {"Q", "B", "N", "R"};
                for(int i = 0; i < promotionPiece.length; i++) {
                    String currentPromotion = promotionPiece[i];
                    if ((square.getSquarePiece() == null && o[1] == 0)) {
                        possibleMoves.add(square.getSquareNotation() + currentPromotion);
                    } else if (square.getSquarePiece() != null && square.getSquarePiece().getColor() != COLOR
                            && Math.abs(o[1]) == 1) {
                        possibleMoves.add(square.getSquareNotation() + currentPromotion);
                    }
                }
            }
        }
    }

    @Override
    public void removePossibleMove(String illegalMove) {
        String testIfMove = "";

        for(int i = 0; i < possibleMoves.size(); i++) {
            testIfMove = possibleMoves.get(i);
            if(testIfMove.equals(illegalMove)) {
                possibleMoves.remove(i);
                break;
            }
        }
    }

    @Override
    public String getType() {
        String retType = type;
        return retType;
    }

    @Override
    public void setSquare(Square square) {
        curSquare = square;
        firstMove = true;
    }

    @Override
    public Square getSquare() {
        return curSquare;
    }

    public boolean getEnPassant() {
        boolean retEnPassant = enPassant;
        return retEnPassant;
    }

    public void setEnPassant(boolean enPassant) {
        this.enPassant = enPassant;
    }

    @Override
    public void addPossibleMove(String addMove) {
        possibleMoves.add(addMove);
    }

    @Override
    public boolean getFirstMove() {
        boolean retFirstMove = firstMove;
        return retFirstMove;
    }

    @Override
    public void setFirstMove(boolean didMove) {
        firstMove = didMove;
    }

    @Override
    public String toString() {
        String tempMove = "";
        for(int i = 0; i < possibleMoves.size(); i++) {
            tempMove += type + possibleMoves.get(i) + " ";
        }

        if(possibleMoves.isEmpty()) {
            tempMove = "No possible moves.";
        }

        return tempMove;
    }
}

I won't bother including the other piece child classes. However one thing I know for sure that has to be a better way of doing is the enPassant methods. All of the piece child classes have the two enpassant methods. I had to put it as a method in the piece interface even though the only class that uses it is pawn. Is there a way around this?

\$\endgroup\$
  • \$\begingroup\$ In response to your question about the enPassant methods, you could encapsulate that as its own interface. interface IEnPassant { .... } class Pawn extends Piece implement IEnPassant { ... } Java 8 has default methods, so there is no need for your Piece abstract class. Just make Piece an interface. \$\endgroup\$ – Jacques René Mesrine Nov 20 '17 at 21:31
  • \$\begingroup\$ @JacquesRenéMesrine " so there is no need for your Piece abstract class. Just make Piece an interface" do you mean make Piece an interface that implements the piece interface. And then still have pieces extend piece? \$\endgroup\$ – Dporth Nov 20 '17 at 21:40
  • 1
    \$\begingroup\$ I mean rename PieceInterface as Piece. Whether or not you need an intermediary abstract class is up to you. My rule of thumb is to avoid all the ghastlly indirection. When I design my code; these are some of the questions I ask myself: (1) How can I minimize the number of classes/interfaces. (2) Is my code testable? (3) Are the names describing the problem domain. \$\endgroup\$ – Jacques René Mesrine Nov 20 '17 at 21:53
  • 3
    \$\begingroup\$ @JacquesRenéMesrine Why do you review in the comments instead of just writing an answer? Gets you better formatting and even some imaginary internet points.... \$\endgroup\$ – Vogel612 Nov 21 '17 at 13:04
  • 4
    \$\begingroup\$ @Maybe_Factor same to you... Why review in the comments instead of in an answer??? \$\endgroup\$ – Vogel612 Nov 21 '17 at 13:04
0
\$\begingroup\$

First of all, thanks for sharing your code.

Now let's start breaking it down. (Note, you did plenty of things right too, so don't feel bad about this review. I'm just not going to mention most of those).

interface or abstract class

You should make a choice. Either the interface, or the abstract class. As some of the comments already mentioned you're now using the abstract class exactly as if it was an interface. And you don't use the interface at all.

In this case I'd say the choice is easy. Remove the interface. And since we got an abstract class you should also use it as such. The most obvious example being the COLOR field.

Just put that in the abstract Piece class and actually implement the getter into that class as well. That way you can completely remove them in the subclasses.

getters for boolean

The convention for normal getters is indeed to prepend the method with "get". The only exception to this rule is for boolean values. Combined with this is the fact that COLOR is not the best name for a boolean value.

I suggest renaming it like this:

private boolean isWhite;

public boolean isWhite(){
    return isWhite;
}

This reads especially nice in a check if some piece is white or black:

if(piece.isWhite()){
    //handle white piece
} else {
    //handle black piece
}

Similar for the first move. public boolean isFirstMove()

unnecessary intermediate variables

The worst case is this:

ArrayList<Piece> currentMove = null;
int turnInt; // 1 for white, 0 for black
if (getTurn() == false) {
    turnInt = 1;
} else {
    turnInt = 0;
}
switch (turnInt) {
case 0:
    currentMove = blackPieces;
    break;
case 1:
    currentMove = whitePieces;
    break;
}

Why not just:

ArrayList<Piece> currentMove = null;
if(isWhiteTurn()){
    currentMove = blackPieces;
} else {
    currentMove = whitePieces;
}

There's also plenty of places where you create a new variable to return instead of directly returning the requested result.

@Override
public boolean getFirstMove() {
    boolean retFirstMove = firstMove;
    return retFirstMove;
}

This should just be

@Override
public boolean getFirstMove() {
    return FirstMove;
}

encapsulation

It's rarely a good idea to make variables protected. Just make them private and use getters where needed. (Also only provide setters if you really need to change the value of the field).

constants should be constant

private int BOARD_SIZE = 8; folows the right naming convention to be a constant (good job). But it should really be final and probably static as well (as it's independant from any specific instance of the class).

private static final int BOARD_SIZE = 8;

(side note: I would argue that 8 in the context of chess boards isn't really a magic constant and could be used without a field i.e. board = new Square[8][8];).

huuuuuge for loop to initialise the board

You're trying to do too much at once to initialise the board. I would split this up more. Start by creating an 8 x 8 grid of empty squares. Then after that (double) for loop start putting in the pieces.

for(int row = 0; row < 8; row ++){
    for(int col = 0; col < 8; col ++) {
        String squarenote = ...;
        board[row][col] = new Square(...);
    }
}

for(int col = 0; col < 8; col++){
    final Piece pawn = new Pawn("P", false, board[1][col];
    board[1][col].add(pawn);
    blackPieces.add(pawn);
}

final Piece blackKing = new King("K", true, board[0][4]);
board[0][4].add(blackKing);
blackPieces.add(blackKing);

...

Optionaly you can also put some parts in helper functions. Like: initBlackPieces();. Which obviously places all the black pieces on the board.

foreach loop

It's possible to replace this

for (int i = 0; i < whitePieces.size(); i++) {

with

for(Piece piece : whitePieces){

This kind of for loop is more readable and is preferred if you don't explicitly need the index. The normal for loop is used correctly to initialise the board since you do want to know the index there.

This makes a huge difference in the readability of your move method:

public void move(String pieceType, String toNotation) {

    if (isWhiteTurn()) {
        for (Piece piece : whitePieces) {
            if (piece.getType().equals(pieceType)
                    && piece.getPossibleMoves().contains(toNotation)) {
                movePiece(piece, toNotation);
                piece.setFirstMove(false);
                if (kingLeftInCheck()) {
                    throw new IllegalStateException();
                }
            }
        }
    } else {
        ... same thing
    }
}

(Quick note here, I also removed the parameter Square fromSquare from the movePiece method, since you already pass the Piece itself. Just use the getter on the piece when needed.)

who is responsible for the moves

This one is bigger. You have parts of the move logic taken care of in the ChessBoard class. And some other parts in the individual Piece classes. Since some of the moves are rather complicaded for chess, I would say that it's actually better to just handle all moves inside the ChessBoard class. That way a piece does not have to know what a board is. It's litteraly just a piece that you can put on the board. (And if you would upgrade to a graphical interface, should probably contain the image of that piece for example).

Alternatively you could argue that moves that are piece specific could be placed in each of those classes (matches closesly what you do now) but then I would actually let them handle the moving completely.

Do not store the "possible moves" into the pieces. Instead, provide a method on the Piece classes that can check if it can move to a specific spot on the board (while passing in the current board as a parameter). That way, your move method in the ChessBoard class could look like this:

public void move(String pieceType, String toNotation) {
    if(isWhiteTurn()){
        for(Piece piece : whiePieces){
            if(piece.move(toNotation, board)){
                if(kingLeftInCheck()){
                    throw new IllegalStateException();
                }
                return;
            }
        }
    } else {
         ....
    }

To solve your problem of en passant you could also pass in the latest moved piece.

It could be useful to provide a protected boolean isAttackingMove(boolean isWhiteTurn, Square[][] board, Piece last moved, String moveTo) method in the Piece class. This method checks if the moveTo square contains a piece of the other color. Or if it's an en passent square.

Then you can use it in the subclasses to check if that square is a valid move (like a pawn attacking diagonally).


There might be some other points to improve but I guess this answer is already long enough as is. Feel free to post a follow up review question after making the changes you agree with.

\$\endgroup\$
  • \$\begingroup\$ Wouldn't returning the actual variable like in the method getFirstMove() as you mentioned be violating encapsulation? \$\endgroup\$ – Dporth Nov 22 '17 at 1:58
  • \$\begingroup\$ No. Think about what needs to change if you want to turn the internal representation to an integer instead of a boolean for example. Those changes are all internal to that class, no other class needs to be touched despite using the method. (edit: I mean, in the method use return moves == 0 to still return a boolean response to that method, despite saving it as an int internally) \$\endgroup\$ – Imus Nov 22 '17 at 13:28
  • \$\begingroup\$ It would be different if you would return something mutable like a list for example. In that case you most likely want to first create a new list, add all elements from the internal list and return that new list. That way the class that requested the list can't modify the internal list . That's different from what you did here. \$\endgroup\$ – Imus Nov 22 '17 at 13:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.