This repository has been archived on 2021-02-18. You can view files and clone it, but cannot push or open issues or pull requests.
chess/src/dev/kske/chess/Board.java

216 lines
6.1 KiB
Java
Raw Normal View History

package dev.kske.chess;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import dev.kske.chess.event.GameEvent;
import dev.kske.chess.event.GameEvent.GameEventType;
import dev.kske.chess.event.GameEventListener;
import dev.kske.chess.piece.Bishop;
import dev.kske.chess.piece.King;
import dev.kske.chess.piece.Knight;
import dev.kske.chess.piece.Pawn;
import dev.kske.chess.piece.Piece;
import dev.kske.chess.piece.Piece.Color;
import dev.kske.chess.piece.Piece.Type;
import dev.kske.chess.piece.Queen;
import dev.kske.chess.piece.Rook;
/**
* Project: <strong>Chess</strong><br>
* File: <strong>Board.java</strong><br>
* Created: <strong>01.07.2019</strong><br>
* Author: <strong>Kai S. K. Engelbart</strong>
*/
public class Board {
private Piece[][] boardArr;
private Map<Color, Position> kingPos;
private List<GameEventListener> gameEventListeners;
public Board() {
boardArr = new Piece[8][8];
kingPos = new HashMap<>();
gameEventListeners = new ArrayList<>();
initializeDefaultPositions();
}
/**
* Moves a piece across the board if the move is legal.
*
* @param move The move to execute
* @return {@code true}, if the attempted move was legal and thus executed
*/
public boolean attemptMove(Move move) {
Piece piece = getPos(move);
if (piece == null || !piece.isValidMove(move)) return false;
else {
/*
* Move piece
* Save destination piece for possible canceling of the move
*/
Piece capturePiece = move(move);
// Revert move if it caused a check for its team
if (checkCheck(piece.getColor())) {
revert(move, capturePiece);
return false;
}
// TODO: detecting checkmate
// Check for check on the opposite team
Color oppositeColor = piece.getColor() == Color.WHITE ? Color.BLACK : Color.WHITE;
if (checkCheck(oppositeColor)) notifyListeners(new GameEvent(this, GameEventType.CHECK, oppositeColor));
return true;
}
}
/**
* Moves a piece across the board without checking if the move is legal.
*
* @param move The move to execute
* @return The captures piece, or null if the move's destination was empty
*/
public Piece move(Move move) {
Piece piece = getPos(move);
Piece capturePiece = getDest(move);
setDest(move, piece);
setPos(move, null);
// Update the king's position if the moved piece is the king
if (piece.getType() == Type.KING) kingPos.put(piece.getColor(), move.dest);
return capturePiece;
}
/**
* Reverts a move.
*
* @param move The move to revert
* @param capturedPiece The piece that has been captured when the move has been
* applied
*/
public void revert(Move move, Piece capturedPiece) {
setPos(move, getDest(move));
setDest(move, capturedPiece);
// Update the king's position if the moved piece is the king
if (getPos(move).getType() == Type.KING) kingPos.put(getPos(move).getColor(), move.pos);
}
/**
* Generated every legal move for one color
*
* @param color The color to generate the moves for
* @return A list of all legal moves
*/
public List<Move> getMoves(Color color) {
List<Move> moves = new ArrayList<>();
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
if (boardArr[i][j] != null && boardArr[i][j].getColor() == color)
moves.addAll(boardArr[i][j].getMoves(new Position(i, j)));
return moves;
}
public List<Move> getMoves(Position pos) {
return get(pos).getMoves(pos);
}
public boolean checkCheck(Color color) {
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
if (boardArr[i][j] != null && boardArr[i][j].getColor() != color
&& boardArr[i][j].isValidMove(new Move(new Position(i, j), kingPos.get(color))))
return true;
return false;
}
public void registerGameEventListener(GameEventListener listener) {
gameEventListeners.add(listener);
}
private void notifyListeners(GameEvent evt) {
gameEventListeners.forEach(listener -> listener.onGameEvent(evt));
}
public Piece get(Position pos) {
return boardArr[pos.x][pos.y];
}
public void set(Position pos, Piece piece) {
boardArr[pos.x][pos.y] = piece;
}
public Piece getPos(Move move) {
return get(move.pos);
}
public Piece getDest(Move move) {
return get(move.dest);
}
public void setPos(Move move, Piece piece) {
set(move.pos, piece);
}
public void setDest(Move move, Piece piece) {
set(move.dest, piece);
}
/**
* Initialized the board array with the default chess pieces and positions.
*/
public void initializeDefaultPositions() {
// Initialize pawns
for (int i = 0; i < 8; i++) {
boardArr[i][1] = new Pawn(Color.BLACK, this);
boardArr[i][6] = new Pawn(Color.WHITE, this);
}
// Initialize kings
boardArr[4][0] = new King(Color.BLACK, this);
boardArr[4][7] = new King(Color.WHITE, this);
// Initialize king position objects
kingPos.put(Color.BLACK, new Position(4, 0));
kingPos.put(Color.WHITE, new Position(4, 7));
// Initialize queens
boardArr[3][0] = new Queen(Color.BLACK, this);
boardArr[3][7] = new Queen(Color.WHITE, this);
// Initialize rooks
boardArr[0][0] = new Rook(Color.BLACK, this);
boardArr[0][7] = new Rook(Color.WHITE, this);
boardArr[7][0] = new Rook(Color.BLACK, this);
boardArr[7][7] = new Rook(Color.WHITE, this);
// Initialize knights
boardArr[1][0] = new Knight(Color.BLACK, this);
boardArr[1][7] = new Knight(Color.WHITE, this);
boardArr[6][0] = new Knight(Color.BLACK, this);
boardArr[6][7] = new Knight(Color.WHITE, this);
// Initialize bishops
boardArr[2][0] = new Bishop(Color.BLACK, this);
boardArr[2][7] = new Bishop(Color.WHITE, this);
boardArr[5][0] = new Bishop(Color.BLACK, this);
boardArr[5][7] = new Bishop(Color.WHITE, this);
// Clear all other tiles
for (int i = 0; i < 8; i++)
for (int j = 2; j < 6; j++)
boardArr[i][j] = null;
}
/**
* @return The board array
*/
public Piece[][] getBoardArr() { return boardArr; }
}