diff --git a/chess/src/main/java/de/vivi/chess/Main.java b/chess/src/main/java/de/vivi/chess/Main.java index 8d2fb91..3f7628f 100644 --- a/chess/src/main/java/de/vivi/chess/Main.java +++ b/chess/src/main/java/de/vivi/chess/Main.java @@ -1,12 +1,18 @@ package de.vivi.chess; import de.vivi.chess.board.Board; +import de.vivi.chess.board.Field; import de.vivi.chess.game.Game; +import de.vivi.chess.pieces.Piece; + +import java.util.Arrays; public class Main { public static void main(String[] args) { Game game = new Game(); + game.play(); + } } diff --git a/chess/src/main/java/de/vivi/chess/board/Board.java b/chess/src/main/java/de/vivi/chess/board/Board.java index 7c7b246..3abd3a5 100644 --- a/chess/src/main/java/de/vivi/chess/board/Board.java +++ b/chess/src/main/java/de/vivi/chess/board/Board.java @@ -1,11 +1,11 @@ package de.vivi.chess.board; -import de.vivi.chess.pieces.Piece; +import de.vivi.chess.pieces.*; +import de.vivi.chess.game.Game; public class Board { private static final int SIZE = 8; - private final Piece[/* column */][/* row */] grid; public Board() { @@ -21,8 +21,52 @@ public class Board { * in the bottom two rows. "White queen, white field, black * queen, black field". */ - private void setup() { + private void setup() { + grid[0][0] = new Rook(Color.BLACK, Type.ROOK, new Field(0, 0)); + grid[1][0] = new Knight(Color.BLACK, Type.KNIGHT, new Field(1, 0)); + grid[2][0] = new Bishop(Color.BLACK, Type.BISHOP, new Field(2, 0)); + grid[3][0] = new Queen(Color.BLACK, Type.QUEEN, new Field(3, 0)); + grid[4][0] = new King(Color.BLACK, Type.KING, new Field(4, 0)); + grid[5][0] = new Bishop(Color.BLACK, Type.BISHOP, new Field(5, 0)); + grid[6][0] = new Knight(Color.BLACK, Type.KNIGHT, new Field(6, 0)); + grid[7][0] = new Rook(Color.BLACK, Type.ROOK, new Field(7, 0)); + //grid[0][0] = new Rook(Color.BLACK, Type.ROOK); +// grid[1][0] = new Knight(Color.BLACK, Type.KNIGHT); +// grid[2][0] = new Bishop(Color.BLACK, Type.BISHOP); +// grid[3][0] = new Queen(Color.BLACK, Type.QUEEN); +// grid[4][0] = new King(Color.BLACK, Type.KING); +// grid[5][0] = new Bishop(Color.BLACK, Type.BISHOP); +// grid[6][0] = new Knight(Color.BLACK, Type.KNIGHT); +// grid[7][0] = new Rook(Color.BLACK, Type.ROOK); + + for (int i = 0; i < SIZE; i++) { + //grid[i][1] = new Pawn(Color.BLACK, Type.PAWN); + grid[i][1] = new Pawn(Color.BLACK, Type.PAWN, new Field(i, 0)); + } + + grid[0][7] = new Rook(Color.WHITE, Type.ROOK, new Field(0, 7)); + grid[1][7] = new Knight(Color.WHITE, Type.KNIGHT, new Field(1, 7)); + grid[2][7] = new Bishop(Color.WHITE, Type.BISHOP, new Field(2, 7)); + grid[3][7] = new Queen(Color.WHITE, Type.QUEEN, new Field(3, 7)); + grid[4][7] = new King(Color.WHITE, Type.KING, new Field(4, 7)); + grid[5][7] = new Bishop(Color.WHITE, Type.BISHOP, new Field(5, 7)); + grid[6][7] = new Knight(Color.WHITE, Type.KNIGHT, new Field(6, 7)); + grid[7][7] = new Rook(Color.WHITE, Type.ROOK, new Field(7, 7)); + +// grid[0][7] = new Rook(Color.WHITE, Type.ROOK); +// grid[1][7] = new Knight(Color.WHITE, Type.KNIGHT); +// grid[2][7] = new Bishop(Color.WHITE, Type.BISHOP); +// grid[3][7] = new Queen(Color.WHITE, Type.QUEEN); +// grid[4][7] = new King(Color.WHITE, Type.KING); +// grid[5][7] = new Bishop(Color.WHITE, Type.BISHOP); +// grid[6][7] = new Knight(Color.WHITE, Type.KNIGHT); +// grid[7][7] = new Rook(Color.WHITE, Type.ROOK); + + for (int i = 0; i < SIZE; i++) { + //grid[i][6] = new Pawn(Color.WHITE, Type.PAWN); + grid[i][6] = new Pawn(Color.WHITE, Type.PAWN, new Field(i, 6)); + } } /** @@ -34,7 +78,11 @@ public class Board { * just getting replaced. */ public void move(Field from, Field to) { - + if (grid[from.getColumn()][from.getRow()] != null) { + grid[to.getColumn()][to.getRow()] = grid[from.getColumn()][from.getRow()]; + grid[to.getColumn()][to.getRow()].setField(to); + grid[from.getColumn()][from.getRow()] = null; + } } /** @@ -44,7 +92,22 @@ public class Board { * present it just returns null. */ public Piece getPiece(Field field) { - return null; + return grid[field.getColumn()][field.getRow()]; + } + + public Piece[][] getBoard() { + return grid; + } + + public Piece getPiece(int column, int row) { + return grid[column][row]; + } + + public void setPiece(int column, int row, Piece piece) { + grid[column][row] = piece; + if (piece != null) { + piece.setField(new Field(column, row)); + } } @Override diff --git a/chess/src/main/java/de/vivi/chess/board/Field.java b/chess/src/main/java/de/vivi/chess/board/Field.java index 735b06b..3d5e3a6 100644 --- a/chess/src/main/java/de/vivi/chess/board/Field.java +++ b/chess/src/main/java/de/vivi/chess/board/Field.java @@ -1,5 +1,7 @@ package de.vivi.chess.board; +import de.vivi.chess.pieces.Piece; + /** * TODO: implement fields and constructor *
@@ -8,6 +10,14 @@ package de.vivi.chess.board; */ public class Field { + private int column; + private int row; + + public Field(int column, int row) { + this.column = column; + this.row = row; + } + /** * TODO: implement *
@@ -15,7 +25,7 @@ public class Field {
* column and row indices.
*/
public static Field from(int column, int row) {
- return null;
+ return new Field(column, row);
}
/**
@@ -28,16 +38,81 @@ public class Field {
* it should throw an IllegalArgument exception.
*/
public static Field fromString(String value) throws IllegalArgumentException {
- return null;
+ try {
+ char[] array = value.toCharArray();
+ int column_ = 0;
+ int row_ = 0;
+
+ switch (array[0]) {
+ case 'A':
+ column_ = 0;
+ break;
+ case 'B':
+ column_ = 1;
+ break;
+ case 'C':
+ column_ = 2;
+ break;
+ case 'D':
+ column_ = 3;
+ break;
+ case 'E':
+ column_ = 4;
+ break;
+ case 'F':
+ column_ = 5;
+ break;
+ case 'G':
+ column_ = 6;
+ break;
+ case 'H':
+ column_ = 7;
+ break;
+ default:
+ System.out.println("Wrong input");
+ }
+
+ switch (array[1]) {
+ case '1':
+ row_ = 0;
+ break;
+ case '2':
+ row_ = 1;
+ break;
+ case '3':
+ row_ = 2;
+ break;
+ case '4':
+ row_ = 3;
+ break;
+ case '5':
+ row_ = 4;
+ break;
+ case '6':
+ row_ = 5;
+ break;
+ case '7':
+ row_ = 6;
+ break;
+ case '8':
+ row_ = 7;
+ break;
+ default:
+ System.out.println("Wrong input");
+ }
+ return from(column_, row_);
+ } catch (RuntimeException e) {
+ throw new RuntimeException(e);
+ }
}
public int getColumn() {
// TODO: implement
- return -1;
+ return column;
}
public int getRow() {
// TODO: implement
- return -1;
+ return row;
}
}
diff --git a/chess/src/main/java/de/vivi/chess/game/Game.java b/chess/src/main/java/de/vivi/chess/game/Game.java
index be43c30..671d3d4 100644
--- a/chess/src/main/java/de/vivi/chess/game/Game.java
+++ b/chess/src/main/java/de/vivi/chess/game/Game.java
@@ -1,19 +1,30 @@
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 final Board board;
-
+ private Board board;
private Color player;
+ private int count = 0;
+ private boolean whiteTurn = true;
/**
* TODO: implement
*/
public Game() {
- board = null;
+ this.board = new Board();
player = null;
}
@@ -24,6 +35,296 @@ public class Game {
* 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
@@ -16,14 +38,15 @@ public abstract class Piece {
*/
public abstract boolean isValidMove(Board board, Field from, Field to);
+
public Color getColor() {
// TODO: implement
- return null;
+ return color;
}
public Type getType() {
// TODO: implement
- return null;
+ return type;
}
/**
@@ -34,6 +57,14 @@ public abstract class Piece {
* Unicode chess pieces
*/
public char getSymbol() {
- return 0;
+ return symbol;
+ }
+
+ public Field getField() {
+ return field;
+ }
+
+ public void setField(Field field) {
+ this.field = field;
}
}
diff --git a/chess/src/main/java/de/vivi/chess/pieces/Queen.java b/chess/src/main/java/de/vivi/chess/pieces/Queen.java
new file mode 100644
index 0000000..2a0afb0
--- /dev/null
+++ b/chess/src/main/java/de/vivi/chess/pieces/Queen.java
@@ -0,0 +1,64 @@
+package de.vivi.chess.pieces;
+
+import de.vivi.chess.board.Board;
+import de.vivi.chess.board.Field;
+
+public class Queen extends Piece {
+ public Queen(Color color, Type type) {
+ super(color, type);
+ }
+
+ public Queen(Color color, Type type, Field field) {
+ super(color, type, field);
+ }
+
+ @Override
+ public char getSymbol() {
+ if (getColor() == Color.WHITE) {
+ if (getType() == Type.QUEEN) {
+ symbol = '\u265B';
+ }
+
+ } else if (getColor() == Color.BLACK) {
+ if (getType() == Type.QUEEN) {
+ symbol = '\u2655';
+ }
+ }
+ return symbol;
+ }
+
+ @Override
+ public boolean isValidMove(Board board, Field from, Field to) {
+ if (to.equals(from)) {
+ return false;
+ }
+
+ int rowDiff = Math.abs(to.getRow() - from.getRow());
+ int colDiff = Math.abs(to.getColumn() - from.getColumn());
+
+ boolean straightLine = from.getRow() == to.getRow()
+ || from.getColumn() == to.getColumn();
+
+ boolean diagonal = rowDiff == colDiff;
+
+ if (!straightLine && !diagonal) {
+ return false;
+ }
+
+ int rowDirection = Integer.compare(to.getRow(), from.getRow());
+ int colDirection = Integer.compare(to.getColumn(), from.getColumn());
+
+ int currentRow = from.getRow() + rowDirection;
+ int currentCol = from.getColumn() + colDirection;
+ while (currentRow != to.getRow() || currentCol != to.getColumn()) {
+ if (board.getPiece(Field.from(currentCol, currentRow)) != null) {
+ return false;
+ }
+ currentRow += rowDirection;
+ currentCol += colDirection;
+ }
+
+ Piece destinationPiece = board.getPiece(Field.from(to.getColumn(), to.getRow()));
+ return destinationPiece == null || destinationPiece.getColor() != this.getColor();
+ }
+}
diff --git a/chess/src/main/java/de/vivi/chess/pieces/Rook.java b/chess/src/main/java/de/vivi/chess/pieces/Rook.java
new file mode 100644
index 0000000..8fbd800
--- /dev/null
+++ b/chess/src/main/java/de/vivi/chess/pieces/Rook.java
@@ -0,0 +1,68 @@
+package de.vivi.chess.pieces;
+
+import de.vivi.chess.board.Board;
+import de.vivi.chess.board.Field;
+
+public class Rook extends Piece {
+
+ private boolean isValid = false;
+
+ public Rook(Color color, Type type) {
+ super(color, type);
+ }
+
+ public Rook(Color color, Field field) {
+ super(color, field);
+ }
+
+ public Rook(Color color, Type type, Field field) {
+ super(color, type, field);
+ }
+
+ @Override
+ public char getSymbol() {
+ if (getColor() == Color.WHITE) {
+ if (getType() == Type.ROOK) {
+ symbol = '\u265C';
+ }
+
+ } else if (getColor() == Color.BLACK) {
+ if (getType() == Type.ROOK) {
+ symbol = '\u2656';
+ }
+ }
+ return symbol;
+ }
+
+ @Override
+ public boolean isValidMove(Board board, Field from, Field to) {
+ if (from.getRow() == to.getRow()) {
+ int columnStart = Math.min(from.getColumn(), to.getColumn()) + 1;
+ int columnEnd = Math.max(from.getColumn(), to.getColumn());
+ for (int column = columnStart; column < columnEnd; column++) {
+ if (board.getPiece(Field.from(column, from.getRow())) != null) {
+ return false;
+ }
+ }
+ } else if (from.getColumn() == to.getColumn()) {
+ int rowStart = Math.min(from.getRow(), to.getRow()) + 1;
+ int rowEnd = Math.max(from.getRow(), to.getRow());
+ for (int row = rowStart; row < rowEnd; row++) {
+ if (board.getPiece(Field.from(from.getColumn(), row)) != null) {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+
+ Piece destinationPiece = board.getPiece(to);
+ if (destinationPiece == null) {
+ return true;
+ } else if (destinationPiece.getColor() != this.getColor()) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/chess/src/main/java/de/vivi/chess/pieces/Type.java b/chess/src/main/java/de/vivi/chess/pieces/Type.java
index adeef34..1b7f635 100644
--- a/chess/src/main/java/de/vivi/chess/pieces/Type.java
+++ b/chess/src/main/java/de/vivi/chess/pieces/Type.java
@@ -14,4 +14,10 @@ package de.vivi.chess.pieces;
* - pawn (Bauer)
*/
public enum Type {
+ KING,
+ QUEEN,
+ BISHOP,
+ KNIGHT,
+ ROOK,
+ PAWN
}