forked from pabulaner/vivi
331 lines
13 KiB
Java
331 lines
13 KiB
Java
package de.vivi.chess.game;
|
|
|
|
import de.vivi.chess.board.Board;
|
|
import de.vivi.chess.board.Field;
|
|
import de.vivi.chess.pieces.Color;
|
|
import de.vivi.chess.pieces.King;
|
|
import de.vivi.chess.pieces.Piece;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Scanner;
|
|
|
|
import static de.vivi.chess.pieces.Color.BLACK;
|
|
import static de.vivi.chess.pieces.Color.WHITE;
|
|
|
|
public class Game {
|
|
|
|
private Board board;
|
|
private Color player;
|
|
private int count = 0;
|
|
private boolean whiteTurn = true;
|
|
|
|
/**
|
|
* TODO: implement
|
|
*/
|
|
public Game() {
|
|
this.board = new Board();
|
|
player = null;
|
|
}
|
|
|
|
/**
|
|
* TODO: implement
|
|
* <p>
|
|
* Starts the game and should process the game like it is
|
|
* specified inside example-output.txt.
|
|
*/
|
|
public void play() {
|
|
System.out.println("Welcome to Vivi's Chess Game!");
|
|
System.out.println(board);
|
|
player = ((count % 2) == 0) ? WHITE : BLACK;
|
|
System.out.println("It is white's turn: [from:to]");
|
|
|
|
Scanner scanner = new Scanner(System.in);
|
|
|
|
while (scanner.hasNext()) {
|
|
|
|
scanner.useDelimiter(":\\s*");
|
|
String fromString = scanner.nextLine();
|
|
|
|
char[] arrayInRange = fromString.toCharArray();
|
|
|
|
if ((arrayInRange[0] == 'A' ||
|
|
arrayInRange[0] == 'B' ||
|
|
arrayInRange[0] == 'C' ||
|
|
arrayInRange[0] == 'D' ||
|
|
arrayInRange[0] == 'E' ||
|
|
arrayInRange[0] == 'F' ||
|
|
arrayInRange[0] == 'G' ||
|
|
arrayInRange[0] == 'H' ) &&
|
|
(arrayInRange[1] == '0' ||
|
|
arrayInRange[1] == '1' ||
|
|
arrayInRange[1] == '2' ||
|
|
arrayInRange[1] == '3' ||
|
|
arrayInRange[1] == '4' ||
|
|
arrayInRange[1] == '5' ||
|
|
arrayInRange[1] == '6' ||
|
|
arrayInRange[1] == '7' ||
|
|
arrayInRange[1] == '8' )) {
|
|
|
|
StringBuilder sb=new StringBuilder(fromString);
|
|
int l=sb.length();
|
|
|
|
if (l == 2) {
|
|
String toString = scanner.nextLine();
|
|
Field from = Field.fromString(fromString);
|
|
Field to = Field.fromString(toString);
|
|
|
|
System.out.println("player == WHITE && board.getPiece(from).getColor() == WHITE " +
|
|
(player == WHITE && board.getPiece(from).getColor() == WHITE));
|
|
|
|
|
|
System.out.println("board.getPiece(from).isValidMove(board, from,to) " +
|
|
(board.getPiece(from).isValidMove(board, from,to)));
|
|
|
|
if (player == WHITE && board.getPiece(from).getColor() == WHITE) {
|
|
if (board.getPiece(from).isValidMove(board, from,to)) {
|
|
count++;
|
|
board.move(from, to);
|
|
System.out.println("Moving white " + board.getPiece(to).getType()
|
|
+ " from " + fromString + " to " + toString);
|
|
}
|
|
System.out.println(board);
|
|
} else if (player == BLACK && board.getPiece(from).getColor() == BLACK) {
|
|
if (board.getPiece(from).isValidMove(board, from,to)) {
|
|
count++;
|
|
board.move(from, to);
|
|
System.out.println("Moving black " + board.getPiece(to).getType()
|
|
+ " from " + fromString + " to " + toString);
|
|
}
|
|
System.out.println(board);
|
|
} else {
|
|
System.err.println("Illegal move, try again: ");
|
|
}
|
|
|
|
player = ((count % 2) == 0) ? WHITE : BLACK;
|
|
if (player == BLACK) {
|
|
System.out.println("It is black's turn: [from:to]");
|
|
} else {
|
|
System.out.println("It is white's turn: [from:to]");
|
|
}
|
|
} else {
|
|
System.err.println("Illegal move, try again: ");
|
|
}
|
|
} else
|
|
System.err.println("Illegal move, try again: ");
|
|
}
|
|
}
|
|
|
|
public Board getBoard() {
|
|
return this.board;
|
|
}
|
|
|
|
public void resetGame() {
|
|
this.board = new Board();
|
|
this.whiteTurn = true;
|
|
}
|
|
|
|
public Color getCurrentPlayerColor() {
|
|
return whiteTurn ? Color.WHITE : Color.BLACK;
|
|
}
|
|
|
|
private Field selectedField;
|
|
|
|
public boolean isPieceSelected() {
|
|
return selectedField != null;
|
|
}
|
|
|
|
public boolean handleSquareSelection(int row, int col) {
|
|
if (selectedField == null) {
|
|
Piece selectedPiece = board.getPiece(row, col);
|
|
if (selectedPiece != null
|
|
&& selectedPiece.getColor() == (whiteTurn ? Color.WHITE : Color.BLACK)) {
|
|
selectedField = new Field(row, col);
|
|
return false;
|
|
}
|
|
} else {
|
|
boolean moveMade = makeMove(selectedField, new Field(row, col));
|
|
selectedField = null;
|
|
return moveMade;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public boolean makeMove(Field from, Field to) {
|
|
Piece movingPiece = board.getPiece(Field.from(from.getRow(), from.getColumn()));
|
|
if (movingPiece == null || movingPiece.getColor() != (whiteTurn ? WHITE : BLACK)) {
|
|
return false;
|
|
}
|
|
|
|
if (movingPiece.isValidMove(board, movingPiece.getField(), to)) {
|
|
board.move(from, to);
|
|
whiteTurn = !whiteTurn;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public boolean isInCheck(Color kingColor) {
|
|
Field kingPosition = findKingPosition(kingColor);
|
|
for (int row = 0; row < 8; row++) {
|
|
for (int col = 0; col < 8; col++) {
|
|
Piece piece = board.getPiece(Field.from(row, col));
|
|
if (piece != null && piece.getColor() != kingColor) {
|
|
if (piece.isValidMove(board, piece.getField(), kingPosition)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
|
|
}
|
|
|
|
private Field findKingPosition(Color color) {
|
|
for (int row = 0; row < 8; row++) {
|
|
for (int col = 0; col < 8; col++) {
|
|
Piece piece = board.getPiece(Field.from(row, col));
|
|
if (piece instanceof King && piece.getColor() == color) {
|
|
return new Field(row, col);
|
|
}
|
|
}
|
|
}
|
|
throw new RuntimeException("King not found, which should never happen.");
|
|
}
|
|
|
|
public boolean isCheckmate(Color kingColor) {
|
|
if (!isInCheck(kingColor)) {
|
|
return false;
|
|
}
|
|
|
|
Field kingPosition = findKingPosition(kingColor);
|
|
King king = (King) board.getPiece(Field.from(kingPosition.getRow(), kingPosition.getColumn()));
|
|
|
|
for (int rowOffset = -1; rowOffset <= 1; rowOffset++) {
|
|
for (int colOffset = -1; colOffset <= 1; colOffset++) {
|
|
if (rowOffset == 0 && colOffset == 0) {
|
|
continue;
|
|
}
|
|
Field newPosition = new Field(kingPosition.getRow() + rowOffset,
|
|
kingPosition.getColumn() + colOffset);
|
|
if (
|
|
isPositionOnBoard(newPosition) &&
|
|
king.isValidMove(board, king.getField() , newPosition)
|
|
&& !wouldBeInCheckAfterMove(kingColor, kingPosition, newPosition)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
private boolean isPositionOnBoard(Field field) {
|
|
return field.getRow() >= 0 && field.getRow() < 8 &&
|
|
field.getColumn() >= 0 && field.getColumn() < 8;
|
|
|
|
}
|
|
|
|
private boolean wouldBeInCheckAfterMove(Color kingColor, Field from, Field to) {
|
|
Piece temp = board.getPiece(Field.from(to.getRow(), to.getColumn()));
|
|
board.setPiece(to.getRow(), to.getColumn(), board.getPiece(to));
|
|
board.setPiece(from.getRow(), from.getColumn(), null);
|
|
|
|
boolean inCheck = isInCheck(kingColor);
|
|
|
|
board.setPiece(from.getRow(), from.getColumn(), board.getPiece(to.getRow(), to.getColumn()));
|
|
board.setPiece(to.getRow(), to.getColumn(), temp);
|
|
|
|
return inCheck;
|
|
}
|
|
|
|
public List<Field> getLegalMovesForPieceAt(Field field) {
|
|
Piece selectedPiece = board.getPiece(field.getRow(), field.getColumn());
|
|
if (selectedPiece == null)
|
|
return new ArrayList<>();
|
|
|
|
List<Field> legalMoves = new ArrayList<>();
|
|
switch (selectedPiece.getClass().getSimpleName()) {
|
|
case "Pawn":
|
|
addPawnMoves(field, selectedPiece.getColor(), legalMoves);
|
|
break;
|
|
case "Rook":
|
|
addLineMoves(field, new int[][] { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }, legalMoves);
|
|
break;
|
|
case "Knight":
|
|
addSingleMoves(field, new int[][] { { 2, 1 }, { 2, -1 }, { -2, 1 }, { -2, -1 }, { 1, 2 }, { -1, 2 },
|
|
{ 1, -2 }, { -1, -2 } }, legalMoves);
|
|
break;
|
|
case "Bishop":
|
|
addLineMoves(field, new int[][] { { 1, 1 }, { -1, -1 }, { 1, -1 }, { -1, 1 } }, legalMoves);
|
|
break;
|
|
case "Queen":
|
|
addLineMoves(field, new int[][] { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 }, { 1, 1 }, { -1, -1 },
|
|
{ 1, -1 }, { -1, 1 } }, legalMoves);
|
|
break;
|
|
case "King":
|
|
addSingleMoves(field, new int[][] { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 }, { 1, 1 }, { -1, -1 },
|
|
{ 1, -1 }, { -1, 1 } }, legalMoves);
|
|
break;
|
|
}
|
|
return legalMoves;
|
|
}
|
|
|
|
private void addLineMoves(Field field, int[][] directions, List<Field> legalMoves) {
|
|
for (int[] d : directions) {
|
|
Field newPos = new Field(field.getRow() + d[0], field.getColumn() + d[1]);
|
|
while (isPositionOnBoard(newPos)) {
|
|
if (board.getPiece(newPos.getRow(), newPos.getColumn()) == null) {
|
|
legalMoves.add(new Field(newPos.getRow(), newPos.getColumn()));
|
|
newPos = new Field(newPos.getRow() + d[0], newPos.getColumn() + d[1]);
|
|
} else {
|
|
if (board.getPiece(newPos.getRow(), newPos.getColumn()).getColor() != board
|
|
.getPiece(field.getRow(), field.getColumn()).getColor()) {
|
|
legalMoves.add(newPos);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void addSingleMoves(Field field, int[][] moves, List<Field> legalMoves) {
|
|
for (int[] move : moves) {
|
|
Field newPos = new Field(field.getRow() + move[0], field.getColumn() + move[1]);
|
|
if (isPositionOnBoard(newPos) && (board.getPiece(newPos.getRow(), newPos.getColumn()) == null ||
|
|
board.getPiece(newPos.getRow(), newPos.getColumn()).getColor() != board
|
|
.getPiece(field.getRow(), field.getColumn()).getColor())) {
|
|
legalMoves.add(newPos);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void addPawnMoves(Field field, Color color, List<Field> legalMoves) {
|
|
int direction = color == WHITE ? -1 : 1;
|
|
Field newPos = new Field(field.getRow() + direction, field.getColumn());
|
|
if (isPositionOnBoard(newPos) && board.getPiece(newPos.getRow(), newPos.getColumn()) == null) {
|
|
legalMoves.add(newPos);
|
|
}
|
|
|
|
if ((color == Color.WHITE && field.getRow() == 6)
|
|
|| (color == Color.BLACK && field.getRow() == 1)) {
|
|
newPos = new Field(field.getRow() + 2 * direction, field.getColumn());
|
|
Field intermediatePos = new Field(field.getRow() + direction, field.getColumn());
|
|
if (isPositionOnBoard(newPos) && board.getPiece(newPos.getRow(), newPos.getColumn()) == null
|
|
&& board.getPiece(intermediatePos.getRow(), intermediatePos.getColumn()) == null) {
|
|
legalMoves.add(newPos);
|
|
}
|
|
}
|
|
|
|
int[] captureCols = { field.getColumn() - 1, field.getColumn() + 1 };
|
|
for (int col : captureCols) {
|
|
newPos = new Field(field.getRow() + direction, col);
|
|
if (isPositionOnBoard(newPos) && board.getPiece(newPos.getRow(), newPos.getColumn()) != null &&
|
|
board.getPiece(newPos.getRow(), newPos.getColumn()).getColor() != color) {
|
|
legalMoves.add(newPos);
|
|
}
|
|
}
|
|
}
|
|
}
|