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 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); + } + } + } } diff --git a/chess/src/main/java/de/vivi/chess/pieces/Bishop.java b/chess/src/main/java/de/vivi/chess/pieces/Bishop.java new file mode 100644 index 0000000..c09addd --- /dev/null +++ b/chess/src/main/java/de/vivi/chess/pieces/Bishop.java @@ -0,0 +1,59 @@ +package de.vivi.chess.pieces; + +import de.vivi.chess.board.Board; +import de.vivi.chess.board.Field; + +public class Bishop extends Piece { + public Bishop(Color color, Type type) { + super(color, type); + } + + public Bishop(Color color, Type type, Field field) { + super(color, type, field); + } + + @Override + public char getSymbol() { + if (getColor() == Color.WHITE) { + if (getType() == Type.BISHOP) { + symbol = '\u265D'; + } + + } else if (getColor() == Color.BLACK) { + if (getType() == Type.BISHOP) { + symbol = '\u2657'; + } + } + return symbol; + } + + @Override + public boolean isValidMove(Board board, Field from, Field to) { + int rowDiff = Math.abs(from.getRow() - to.getRow()); + int colDiff = Math.abs(from.getColumn() - to.getColumn()); + + if (rowDiff != colDiff) { + return false; + } + + int rowStep = to.getRow() > from.getRow() ? 1 : -1; + int colStep = to.getColumn() > from.getColumn() ? 1 : -1; + int steps = rowDiff - 1; + + for (int i = 1; i <= steps; i++) { + if (board.getPiece(Field.from(from.getColumn() + i * rowStep, + from.getRow() + i * colStep)) != null) { + return false; + } + } + + Piece destinationPiece = board.getPiece(Field.from(to.getColumn(), to.getRow())); + 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/Color.java b/chess/src/main/java/de/vivi/chess/pieces/Color.java index 6ff2949..b3cf8d7 100644 --- a/chess/src/main/java/de/vivi/chess/pieces/Color.java +++ b/chess/src/main/java/de/vivi/chess/pieces/Color.java @@ -4,4 +4,6 @@ package de.vivi.chess.pieces; * TODO: add colors (white and black) */ public enum Color { + WHITE, + BLACK } diff --git a/chess/src/main/java/de/vivi/chess/pieces/King.java b/chess/src/main/java/de/vivi/chess/pieces/King.java new file mode 100644 index 0000000..f75e77f --- /dev/null +++ b/chess/src/main/java/de/vivi/chess/pieces/King.java @@ -0,0 +1,44 @@ +package de.vivi.chess.pieces; + +import de.vivi.chess.board.Board; +import de.vivi.chess.board.Field; + +public class King extends Piece { + public King(Color color, Type type) { + super(color, type); + } + + public King(Color color, Type type, Field field) { + super(color, type, field); + } + + @Override + public char getSymbol() { + if (getColor() == Color.WHITE) { + if (getType() == Type.KING) { + symbol = '\u265A'; + } + + } else if (getColor() == Color.BLACK) { + if (getType() == Type.KING) { + symbol = '\u2654'; + } + } + return symbol; + } + + @Override + public boolean isValidMove(Board board, Field from, Field to) { + int rowDiff = Math.abs(from.getRow() - to.getRow()); + int colDiff = Math.abs(from.getColumn() - to.getColumn()); + + boolean isOneSquareMove = rowDiff <= 1 && colDiff <= 1 && !(rowDiff == 0 && colDiff == 0); + + if (!isOneSquareMove) { + return false; + } + + 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/Knight.java b/chess/src/main/java/de/vivi/chess/pieces/Knight.java new file mode 100644 index 0000000..89ac729 --- /dev/null +++ b/chess/src/main/java/de/vivi/chess/pieces/Knight.java @@ -0,0 +1,53 @@ +package de.vivi.chess.pieces; + +import de.vivi.chess.board.Board; +import de.vivi.chess.board.Field; + +public class Knight extends Piece { + public Knight(Color color, Type type) { + super(color, type); + } + + public Knight(Color color, Type type, Field field) { + super(color, type, field); + } + + @Override + public char getSymbol() { + if (getColor() == Color.WHITE) { + if (getType() == Type.KNIGHT) { + symbol = '\u265E'; + } + + } else if (getColor() == Color.BLACK) { + if (getType() == Type.KNIGHT) { + symbol = '\u2658'; + } + } + return symbol; + } + + + @Override + public boolean isValidMove(Board board, Field from, Field to) { + if (to.equals(from)) { + return false; + } + + int rowDiff = Math.abs(from.getRow() - to.getRow()); + int colDiff = Math.abs(from.getColumn() - to.getColumn()); + + boolean isValidLMove = (rowDiff == 2 && colDiff == 1) || (rowDiff == 1 && colDiff == 2); + + if (!isValidLMove) { + return false; + } + + Piece targetPiece = board.getPiece(to); + if (targetPiece == null) { + return true; + } else { + return targetPiece.getColor() != this.getColor(); + } + } +} diff --git a/chess/src/main/java/de/vivi/chess/pieces/Pawn.java b/chess/src/main/java/de/vivi/chess/pieces/Pawn.java new file mode 100644 index 0000000..a2cbcfb --- /dev/null +++ b/chess/src/main/java/de/vivi/chess/pieces/Pawn.java @@ -0,0 +1,73 @@ +package de.vivi.chess.pieces; + +import de.vivi.chess.board.Board; +import de.vivi.chess.board.Field; + +public class Pawn extends Piece { + + public Pawn(Color color, Type type) { + super(color, type); + } + + public Pawn(Color color, Type type, Field field) { + super(color, type, field); + } + + @Override + public char getSymbol() { + if (getColor() == Color.WHITE) { + if (getType() == Type.PAWN) { + symbol = '\u265F'; + } + + } else if (getColor() == Color.BLACK) { + if (getType() == Type.PAWN) { + symbol = '\u2659'; + } + } + return symbol; + } + + @Override + public boolean isValidMove(Board board, Field from, Field to) { + int forwardDirection = getColor() == Color.WHITE ? -1 : 1; + System.out.println("forwardDirection " + forwardDirection); + System.out.println("to.getRow() " + to.getRow()); + System.out.println("from.getRow() " + from.getRow()); + int rowDiff = (to.getRow() - from.getRow()) * forwardDirection; + System.out.println("rowDiff " + rowDiff); + int colDiff = to.getColumn() - from.getColumn(); + System.out.println("colDiff " + colDiff); + System.out.println("black pawn links " + board.getPiece(0,1)); + + if (colDiff == 0 && rowDiff == 1 && board.getPiece(to) == null) { + return true; + } + + boolean isStartingField = (getColor() == Color.WHITE && from.getRow() == 6) || + (getColor() == Color.BLACK && from.getRow() == 1); + System.out.println("getColor() " + getColor()); + System.out.println("from.getRow() " + from.getRow()); + System.out.println("isStartingField " + isStartingField); + System.out.println("board.getPiece(to) " + board.getPiece(to)); + if (colDiff == 0 && rowDiff == 2 && isStartingField && + board.getPiece(to) == null) { + int middleRow = from.getRow() + forwardDirection; + System.out.println("from.getRow() " +from.getRow()); + System.out.println("middleRow " + middleRow); + System.out.println("from.getColumn() " + from.getColumn()); + + if (board.getPiece(Field.from(from.getColumn(), middleRow)) == null) { + return true; + } + } + + if (Math.abs(colDiff) == 1 && rowDiff == 1 && + board.getPiece(to) != null && + board.getPiece(to).getColor() != this.getColor()) { + return true; + } + + return false; + } +} diff --git a/chess/src/main/java/de/vivi/chess/pieces/Piece.java b/chess/src/main/java/de/vivi/chess/pieces/Piece.java index a685db8..2234b52 100644 --- a/chess/src/main/java/de/vivi/chess/pieces/Piece.java +++ b/chess/src/main/java/de/vivi/chess/pieces/Piece.java @@ -5,6 +5,28 @@ import de.vivi.chess.board.Field; public abstract class Piece { + Color color; + private Type type; + protected char symbol; + protected Field field; + + protected Piece(Color color, Type type) { + this.color = color; + this.type = type; + symbol = '\u0000'; + } + + protected Piece(Color color, Field field) { + this.color = color; + this.field = field; + } + + protected Piece(Color color, Type type, Field field) { + this.color = color; + this.type = type; + this.field = field; + } + /** * TODO: implement *

@@ -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 }