Here is the solution to generating possible moves and keeping the king safe. If someone is willing to look it over and come with some suggestion to perhaps improve it, I would appreciate it.
Full source code is at GitHub
King:
@Override
public Collection<Square> generatePossibleMoves() {
possibleMoves.clear();
List<Square> moves = new ArrayList<>();
int[][] offsets = {
{1, 0},
{0, 1},
{-1, 0},
{0, -1},
{1, 1},
{-1, 1},
{-1, -1},
{1, -1}
};
for (int[] o : offsets) {
Square square = super.getSquare().neighbour(o[0], o[1]);
if (square != null && (square.getPiece() == null || isOpponent(square.getPiece()))) {
moves.add(square);
}
}
possibleMoves.addAll(moves);
if (getSquare().isSelected()) {
Piece[] pieces = {
PieceType.PAWN.create(getPieceColor()),
PieceType.ROOK.create(getPieceColor()),
PieceType.BISHOP.create(getPieceColor()),
PieceType.KNIGHT.create(getPieceColor()),
PieceType.QUEEN.create(getPieceColor()),
PieceType.KING.create(getPieceColor())};
Piece oldKing = this;
getSquare().removePiece();
for (Square kingMove : moves) {
if (kingMove.isEmpty()) {
for (Piece piece : pieces) {
piece.putPieceOnSquareFirstTime(kingMove);
piece.generatePossibleMoves();
for (Square enemy : piece.getPossibleMoves()) {
if (!enemy.isEmpty() && enemy.getPiece().isOpponent(piece) && enemy.getPiece().getTypeNumber() == piece.getTypeNumber()) {
enemy.setBackground(Color.BLUE);
possibleMoves.remove(kingMove);
break;
}
}
}
kingMove.removePiece();
} else if (isOpponent(kingMove.getPiece())) {
Piece oldPiece = kingMove.getPiece();
for (Piece piece : pieces) {
kingMove.removePiece();
piece.putPieceOnSquareFirstTime(kingMove);
piece.generatePossibleMoves();
for (Square square1 : piece.getPossibleMoves()) {
if (!square1.isEmpty() && square1.getPiece().isOpponent(piece) && square1.getPiece().getTypeNumber() == piece.getTypeNumber()) {
possibleMoves.remove(kingMove);
break;
}
}
}
kingMove.removePiece();
oldPiece.putPieceOnSquareFirstTime(kingMove);
}
}
oldKing.putPieceOnSquareFirstTime(getSquare());
}
return possibleMoves;
}
Bishop
@Override
public Collection<Square> generatePossibleMoves() {
int row = super.getSquare().ROW;
int column = super.getSquare().COLUMN;
possibleMoves.clear();
//all possible moves in the down positive diagonal
for (int j = column + 1, i = row + 1; j < Board.SIZE && i < Board.SIZE; j++, i++) {
Square square = super.getSquare().getBoardSquare(i, j);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
//all possible moves in the up positive diagonal
for (int j = column - 1, i = row + 1; j > -1 && i < Board.SIZE; j--, i++) {
Square square = super.getSquare().getBoardSquare(i, j);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
//all possible moves in the up negative diagonal
for (int j = column - 1, i = row - 1; j > -1 && i > -1; j--, i--) {
Square square = super.getSquare().getBoardSquare(i, j);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
//all possible moves in the down negative diagonal
for (int j = column + 1, i = row - 1; j < Board.SIZE && i > -1; j++, i--) {
Square square = super.getSquare().getBoardSquare(i, j);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
return possibleMoves;
}
Knight
@Override
public Collection<Square> generatePossibleMoves() {
possibleMoves.clear();
int[][] offsets = {
{-2, 1},
{-1, 2},
{1, 2},
{2, 1},
{2, -1},
{1, -2},
{-1, -2},
{-2, -1}
};
for (int[] o : offsets) {
Square square = super.getSquare().neighbour(o[0], o[1]);
if (square != null && (square.getPiece() == null || isOpponent(square.getPiece()))) {
possibleMoves.add(square);
}
}
return possibleMoves;
}
Rook
@Override
public Collection<Square> generatePossibleMoves() {
int row = super.getSquare().ROW;
int column = super.getSquare().COLUMN;
possibleMoves.clear();
//all possible moves in the up
for (int i = row + 1; i < Board.SIZE; i++) {
Square square = super.getSquare().getBoardSquare(i, column);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
//all possible moves in the down
for (int i = row - 1; i > -1; i--) {
Square square = super.getSquare().getBoardSquare(i, column);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
//all possible moves to the right
for (int i = column + 1; i < Board.SIZE; i++) {
Square square = super.getSquare().getBoardSquare(row, i);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
//all possible moves to the left
for (int i = column - 1; i > -1; i--) {
Square square = super.getSquare().getBoardSquare(row, i);
if (square.getPiece() == null) {
possibleMoves.add(square);
} else if (isOpponent(square.getPiece())) {
possibleMoves.add(square);
break;
} else {
break;
}
}
return possibleMoves;
}
Queen
Moves exactly like the Rook and Bishop so why not reuse?
@Override
public Collection<Square> generatePossibleMoves() {
possibleMoves.clear();
Piece[] pieces = {
PieceType.ROOK.create(getPieceColor()),
PieceType.BISHOP.create(getPieceColor())
};
for (Piece piece : pieces) {
piece.setSquare(getSquare());
possibleMoves.addAll(piece.generatePossibleMoves());
}
return possibleMoves;
}
Pawn
@Override
public Collection<Square> generatePossibleMoves() {
possibleMoves.clear();
boolean color = super.isWhite();
int dx = color ? -1 : 1;
Square ahead = super.getSquare().neighbour(dx, 0);
if (ahead.getPiece() == null) {
possibleMoves.add(ahead);
if (super.getSquare().ROW == 6 && color) {
Square aheadsecond = super.getSquare().neighbour(dx - 1, 0);
if (aheadsecond.getPiece() == null) {
possibleMoves.add(aheadsecond);
}
} else if (super.getSquare().ROW == 1 && !color) {
Square aheadsecond = super.getSquare().neighbour(dx + 1, 0);
if (aheadsecond.getPiece() == null) {
possibleMoves.add(aheadsecond);
}
}
}
Square aheadLeft = super.getSquare().neighbour(dx, -1);
if (aheadLeft != null && aheadLeft.getPiece() != null && isOpponent(aheadLeft.getPiece())) {
possibleMoves.add(aheadLeft);
}
Square aheadRight = super.getSquare().neighbour(dx, 1);
if (aheadRight != null && aheadRight.getPiece() != null && isOpponent(aheadRight.getPiece())) {
possibleMoves.add(aheadRight);
}
return possibleMoves;
}