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 *

* 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 getLegalMovesForPieceAt(Field field) { Piece selectedPiece = board.getPiece(field.getRow(), field.getColumn()); if (selectedPiece == null) return new ArrayList<>(); List 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 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 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 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); } } } }