From fc76c4375400d7127906e0a2592532aa5f996ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw=20Jarocki?= Date: Sat, 10 Jun 2023 06:55:34 +0200 Subject: [PATCH] initial commit --- .gitignore | 29 ++ .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/uiDesigner.xml | 124 +++++++ .idea/vcs.xml | 6 + .idea/workspace.xml | 125 +++++++ chessEngine.iml | 11 + .../jarocki/stanislaw/chess/Board/Board.java | 333 ++++++++++++++++++ .../stanislaw/chess/Coordinate/Column.java | 39 ++ .../chess/Coordinate/Coordinate.java | 117 ++++++ .../stanislaw/chess/Coordinate/Row.java | 39 ++ src/com/jarocki/stanislaw/chess/Game.java | 112 ++++++ src/com/jarocki/stanislaw/chess/Main.java | 9 + .../jarocki/stanislaw/chess/Piece/Basic.java | 54 +++ .../jarocki/stanislaw/chess/Piece/Bishop.java | 54 +++ .../jarocki/stanislaw/chess/Piece/Color.java | 10 + .../jarocki/stanislaw/chess/Piece/King.java | 91 +++++ .../jarocki/stanislaw/chess/Piece/Knight.java | 31 ++ .../jarocki/stanislaw/chess/Piece/Pawn.java | 101 ++++++ .../jarocki/stanislaw/chess/Piece/Queen.java | 53 +++ .../jarocki/stanislaw/chess/Piece/Rook.java | 60 ++++ .../jarocki/stanislaw/chess/Piece/Symbol.java | 26 ++ .../stanislaw/chess/Player/Player.java | 128 +++++++ .../jarocki/stanislaw/chess/Player/Role.java | 10 + src/com/jarocki/stanislaw/chess/Test.java | 142 ++++++++ 25 files changed, 1718 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/uiDesigner.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml create mode 100644 chessEngine.iml create mode 100644 src/com/jarocki/stanislaw/chess/Board/Board.java create mode 100644 src/com/jarocki/stanislaw/chess/Coordinate/Column.java create mode 100644 src/com/jarocki/stanislaw/chess/Coordinate/Coordinate.java create mode 100644 src/com/jarocki/stanislaw/chess/Coordinate/Row.java create mode 100644 src/com/jarocki/stanislaw/chess/Game.java create mode 100644 src/com/jarocki/stanislaw/chess/Main.java create mode 100644 src/com/jarocki/stanislaw/chess/Piece/Basic.java create mode 100644 src/com/jarocki/stanislaw/chess/Piece/Bishop.java create mode 100644 src/com/jarocki/stanislaw/chess/Piece/Color.java create mode 100644 src/com/jarocki/stanislaw/chess/Piece/King.java create mode 100644 src/com/jarocki/stanislaw/chess/Piece/Knight.java create mode 100644 src/com/jarocki/stanislaw/chess/Piece/Pawn.java create mode 100644 src/com/jarocki/stanislaw/chess/Piece/Queen.java create mode 100644 src/com/jarocki/stanislaw/chess/Piece/Rook.java create mode 100644 src/com/jarocki/stanislaw/chess/Piece/Symbol.java create mode 100644 src/com/jarocki/stanislaw/chess/Player/Player.java create mode 100644 src/com/jarocki/stanislaw/chess/Player/Role.java create mode 100644 src/com/jarocki/stanislaw/chess/Test.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7464918 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..ba3b39c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..5367d73 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + "keyToString": { + "RunOnceActivity.OpenProjectViewOnStart": "true", + "RunOnceActivity.ShowReadmeOnStart": "true", + "last_opened_file_path": "/home/stanlee77/code/chessEngine/src/com/jarocki/stanislaw/chess/Piece", + "settings.editor.selected.configurable": "reference.settings.project.maven.runner" + } +} + + + + + + + + + + + + + + + + + 1685528867910 + + + + + + + + + + + file://$PROJECT_DIR$/src/com/jarocki/stanislaw/chess/Player/Player.java + 6 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/chessEngine.iml b/chessEngine.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/chessEngine.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/com/jarocki/stanislaw/chess/Board/Board.java b/src/com/jarocki/stanislaw/chess/Board/Board.java new file mode 100644 index 0000000..185592b --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Board/Board.java @@ -0,0 +1,333 @@ +package com.jarocki.stanislaw.chess.Board; + +import com.jarocki.stanislaw.chess.Coordinate.Column; +import com.jarocki.stanislaw.chess.Coordinate.Row; +import com.jarocki.stanislaw.chess.Piece.*; +import com.jarocki.stanislaw.chess.Piece.Color; + +import java.awt.*; + +public class Board { + private final Basic[][] fields; + private boolean hasWhiteKingMoved; + private boolean hasBlackKingMoved; + private Pawn lastMovedPawn; + + public Board() { + fields = new Basic[8][8]; + this.hasWhiteKingMoved = false; + this.hasBlackKingMoved = false; + this.setUpPieces(); + } + + public void setUpPieces() { + for (int col = 0; col < 8; col++) { + fields[Row.TWO.getNum()][col] = new Pawn(Color.WHITE, Row.TWO, Column.values()[col]); + fields[Row.SEVEN.getNum()][col] = new Pawn(Color.BLACK, Row.SEVEN, Column.values()[col]); + } + + fields[Row.ONE.getNum()][Column.A.getNum()] = new Rook(Color.WHITE, Row.ONE, Column.A); + fields[Row.ONE.getNum()][Column.H.getNum()] = new Rook(Color.WHITE, Row.ONE, Column.H); + fields[Row.EIGHT.getNum()][Column.A.getNum()] = new Rook(Color.BLACK, Row.EIGHT, Column.A); + fields[Row.EIGHT.getNum()][Column.H.getNum()] = new Rook(Color.BLACK, Row.EIGHT, Column.H); + + fields[Row.ONE.getNum()][Column.E.getNum()] = new King(Color.WHITE, Row.ONE, Column.E); + fields[Row.EIGHT.getNum()][Column.E.getNum()] = new King(Color.BLACK, Row.EIGHT, Column.E); + + fields[Row.ONE.getNum()][Column.D.getNum()] = new Queen(Color.WHITE, Row.ONE, Column.D); + fields[Row.EIGHT.getNum()][Column.D.getNum()] = new Queen(Color.BLACK, Row.EIGHT, Column.D); + + fields[Row.ONE.getNum()][Column.B.getNum()] = new Knight(Color.WHITE, Row.ONE, Column.B); + fields[Row.ONE.getNum()][Column.G.getNum()] = new Knight(Color.WHITE, Row.ONE, Column.G); + fields[Row.EIGHT.getNum()][Column.B.getNum()] = new Knight(Color.BLACK, Row.EIGHT, Column.B); + fields[Row.EIGHT.getNum()][Column.G.getNum()] = new Knight(Color.BLACK, Row.EIGHT, Column.G); + + fields[Row.ONE.getNum()][Column.C.ordinal()] = new Bishop(Color.WHITE, Row.ONE, Column.C); + fields[Row.ONE.getNum()][Column.F.ordinal()] = new Bishop(Color.WHITE, Row.ONE, Column.F); + fields[Row.EIGHT.getNum()][Column.C.ordinal()] = new Bishop(Color.BLACK, Row.EIGHT, Column.C); + fields[Row.EIGHT.getNum()][Column.F.ordinal()] = new Bishop(Color.BLACK, Row.EIGHT, Column.F); + } + + public void movePiece(Column currentColumn, Row currentRow, Column targetColumn, Row targetRow) { + int currRow = currentRow.ordinal(); + int currCol = currentColumn.ordinal(); + int targRow = targetRow.ordinal(); + int targCol = targetColumn.ordinal(); + Basic piece = fields[currRow][currCol]; + fields[currRow][currCol] = null; + fields[targRow][targCol] = piece; + } + + public void printBoard() { + System.out.println(); + + System.out.print(" "); + for (Column column : Column.values()) { + System.out.print(" " + column.name() + " "); + } + System.out.println(); + + for (int row = 7; row >= 0; row--) { + System.out.print(Row.values()[row].ordinal() + 1 + " "); + + for (int col = 0; col < 8; col++) { + Basic piece = fields[row][col]; + boolean isLightPurple = (row + col) % 2 == 0; + boolean isLightBlue = (row + col) % 2 != 0; + + if (isLightPurple) { + System.out.print("\u001B[48;5;53m"); + } else if (isLightBlue) { + System.out.print("\u001B[48;5;17m"); + } + + if (piece != null) { + if (piece.getColor() == Color.WHITE) { + System.out.print(" \u001B[93m" + piece.getSymbol().getChar() + " \u001B[0m"); // light yellow - white + } else { + System.out.print(" \u001B[94m" + piece.getSymbol().getChar() + " \u001B[0m"); // black - light blue + } + } else { + System.out.print(" "); + } + } + System.out.println("\u001B[0m"); + } + } + + public void makeMove(int fromRow, int fromCol, int toRow, int toCol) { + Basic piece = fields[fromRow][fromCol]; + fields[fromRow][fromCol] = null; + + Row targetRow = Row.getRowByNum(String.valueOf(toRow+1)); + Column targetCol = Column.getColByNum(String.valueOf(toCol+1)); + piece.setRow(targetRow); + piece.setColumn(targetCol); + + // handle pawn promotion to queen + if((toRow == 0 || toRow == 7) && piece.getSymbol().equals(Symbol.PAWN)){ + piece.setSymbol(Symbol.QUEEN); + Queen queen = new Queen(piece.getColor(), piece.getRow(), piece.getColumn()); + queen.setRow(targetRow); + queen.setColumn(targetCol); + fields[toRow][toCol] = queen; + return; + } + + // remove en passant captured pawn from board + if (piece.getSymbol().equals(Symbol.PAWN)) { + Pawn pawn = new Pawn(piece.getColor(), piece.getRow(), piece.getColumn()); + if (Math.abs(fromRow - toRow) == 1 && Math.abs(fromCol - toCol) == 1 && fields[toRow][toCol] == null) { + int capturedPawnRow = fromRow; + int capturedPawnCol = toCol; + removePiece(capturedPawnRow, capturedPawnCol); + } + } + + // castling check + if (piece.getSymbol().equals(Symbol.KING)) { + King king = new King(piece.getColor(), piece.getRow(), piece.getColumn()); + if (Math.abs(fromCol - toCol) == 2) { + // short castling + if (toCol > fromCol) { + // move closer rook + fields[toRow][toCol - 1] = fields[toRow][Column.H.getNum()]; + fields[toRow][Column.H.getNum()] = null; + } + // long castling + else { + // move far rook + fields[toRow][toCol + 1] = fields[toRow][Column.A.getNum()]; + fields[toRow][Column.A.getNum()] = null; + } + } + + // update status of the king + if (piece.getColor() == Color.WHITE) { + this.hasWhiteKingMoved = true; + } else { + this.hasBlackKingMoved = true; + } + } else if (piece.getSymbol().equals(Symbol.PAWN)) { + if (Math.abs(fromRow - toRow) == 2) { + lastMovedPawn = new Pawn(piece.getColor(), piece.getRow(), piece.getColumn()); + } else { + lastMovedPawn = null; + } + } + + + fields[toRow][toCol] = piece; + + // en passant, castling + if (piece instanceof King) { + if (piece.getColor() == Color.WHITE) { + this.hasWhiteKingMoved = true; + } else { + this.hasBlackKingMoved = true; + } + } else if (piece instanceof Pawn) { + if (Math.abs(fromRow - toRow) == 2) { + lastMovedPawn = (Pawn) piece; + } else { + lastMovedPawn = null; + } + } + } + + public boolean isMoveValid(int fromRow, int fromCol, int toRow, int toCol, Color currPlayerColor) { + // check if not trying to go from or to outside the board + if (fromRow < 0 || fromRow >= 8 || fromCol < 0 || fromCol >= 8 || + toRow < 0 || toRow >= 8 || toCol < 0 || toCol >= 8) { + System.out.println("Coordinates out of the board! (Board)"); + return false; + } + + Basic piece = fields[fromRow][fromCol]; + + // check if there's a piece to pick and move + if (piece == null) { + System.out.println("There's no piece in this field. (Board)"); + return false; + } + + // make sure the piece belongs to the current player + if (piece.getColor() != currPlayerColor) { + System.out.println("Oh come on, It's not even your piece! (Board)"); + return false; + } + + // check if target field is not occupied by piece of the same color + if (fields[toRow][toCol] != null && fields[toRow][toCol].getColor() == currPlayerColor) { + System.out.println("There is your piece already! (Board)"); + return false; + } + + // check stuff specific for particular piece + if (!piece.isMoveValid(toRow, toCol, this)) { + System.out.println("Move invalid for a particular piece. (Board)"); + return false; + } +// make sure the move doesnt lead to check + Board tempBoard = copy(); + + tempBoard.makeMove(fromRow, fromCol, toRow, toCol); + if (tempBoard.isKingInCheck(currPlayerColor)) { + System.out.println("The king is in check!"); + return false; + } + + return true; + } + + public Board copy() { + Board copy = new Board(); + // clean the board + for (int row = 0; row < 8; row++) { + for (int col = 0; col < 8; col++) { + copy.removePiece(row, col); + } + } + // copyt board state + for (int row = 0; row < 8; row++) { + for (int col = 0; col < 8; col++) { + Basic piece = fields[row][col]; + if (piece != null) { + Color color = piece.getColor(); + Row pieceRow = piece.getRow(); + Column pieceCol = piece.getColumn(); + copy.setPiece(row, col, piece.copy(color, pieceRow, pieceCol)); + } + } + } + + // copy other props + copy.hasWhiteKingMoved = this.hasWhiteKingMoved; + copy.hasBlackKingMoved = this.hasBlackKingMoved; + if (this.lastMovedPawn != null) { + int row = this.lastMovedPawn.getRow().getNum(); + int col = this.lastMovedPawn.getRow().getNum(); + Basic lastMovedPawnCopy = copy.getPiece(row, col); + if(lastMovedPawnCopy != null){ + copy.lastMovedPawn = new Pawn(lastMovedPawnCopy.getColor(), lastMovedPawnCopy.getRow(), lastMovedPawnCopy.getColumn()); + } else { + copy.lastMovedPawn = null; + } + } + + return copy; + } + + public void removePiece(int row, int col) { + fields[row][col] = null; + } + + public Basic getPiece(int row, int column) { + if (row >= 0 && row < 8 && column >= 0 && column < 8) { + return fields[row][column]; + } else { + return null; + } + } + + public Pawn getLastMovedPawn() { + return lastMovedPawn; + } + + public void setPiece(int row, int col, Basic piece) { + fields[row][col] = piece; + } + + public boolean isKingInCheck(Color kingColor) { + int kingRow = -1; + int kingCol = -1; + + // find king coordinates + for (int row = 0; row < 8; row++) { + for (int col = 0; col < 8; col++) { + Basic piece = fields[row][col]; + if (piece != null && piece.getSymbol().equals(Symbol.KING) && piece.getColor() == kingColor) { + kingRow = row; + kingCol = col; +// System.out.println("[DEBUG] " + kingColor + " king is in " + Column.getColByNum(String.valueOf(kingCol + 1)) + String.valueOf(kingRow + 1)); + break; + } + } + } + + // check for each opponent piece if can take the king out + for (int row = 0; row < 8; row++) { + for (int col = 0; col < 8; col++) { + Basic piece = fields[row][col]; + if (piece != null && piece.getColor() != kingColor) { + Basic particularPiece = piece; + if(piece.getSymbol().equals(Symbol.QUEEN)){ + particularPiece = (Queen) new Queen(particularPiece.getColor(), particularPiece.getRow(), particularPiece.getColumn()); + } + if(piece.getSymbol().equals(Symbol.KING)){ + particularPiece = (King) new King(particularPiece.getColor(), particularPiece.getRow(), particularPiece.getColumn()); + } + if(piece.getSymbol().equals(Symbol.KNIGHT)){ + particularPiece = (Knight) new Knight(particularPiece.getColor(), particularPiece.getRow(), particularPiece.getColumn()); + } + if(piece.getSymbol().equals(Symbol.BISHOP)){ + particularPiece = (Bishop) new Bishop(particularPiece.getColor(), particularPiece.getRow(), particularPiece.getColumn()); + } + if(piece.getSymbol().equals(Symbol.ROOK)){ + particularPiece = (Rook) new Rook(particularPiece.getColor(), particularPiece.getRow(), particularPiece.getColumn()); + } + if(piece.getSymbol().equals(Symbol.PAWN)){ + particularPiece = (Pawn) new Pawn(particularPiece.getColor(), particularPiece.getRow(), particularPiece.getColumn()); + } + + if (particularPiece.isMoveValid(kingRow, kingCol, this)) { + return true; + } + } + } + } + + return false; + } + +} diff --git a/src/com/jarocki/stanislaw/chess/Coordinate/Column.java b/src/com/jarocki/stanislaw/chess/Coordinate/Column.java new file mode 100644 index 0000000..3fb8d21 --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Coordinate/Column.java @@ -0,0 +1,39 @@ +package com.jarocki.stanislaw.chess.Coordinate; + +public enum Column { + A, + B, + C, + D, + E, + F, + G, + H; + + public int getNum() { + return this.ordinal(); + } + + public static Column getColByNum(String number) { + switch (number) { + case "1": + return Column.A; + case "2": + return Column.B; + case "3": + return Column.C; + case "4": + return Column.D; + case "5": + return Column.E; + case "6": + return Column.F; + case "7": + return Column.G; + case "8": + return Column.H; + default: + throw new IllegalArgumentException("Invalid column number: " + number); + } + } +} diff --git a/src/com/jarocki/stanislaw/chess/Coordinate/Coordinate.java b/src/com/jarocki/stanislaw/chess/Coordinate/Coordinate.java new file mode 100644 index 0000000..db532fc --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Coordinate/Coordinate.java @@ -0,0 +1,117 @@ +//package com.jarocki.stanislaw.chess.Coordinate; +// +//import com.jarocki.stanislaw.chess.Player.Role; +// +//public class Coordinate { +// private String lastMoveFrom; +// private String lastMoveTo; +// private Column lastMoveFromCol; +// private Row lastMoveFromRow; +// private Column lastMoveToCol; +// private Row lastMoveToRow; +// +// public void setLastMove(String moveFrom, String moveTo) { +// if(moveFrom == null || moveTo == null) { +// System.out.println("Some moves are missing: moveFrom = " + moveFrom + " and moveTo = " + moveTo + " (setLastMove)"); +// } +// setLastMoveFrom(moveFrom); +// setLastMoveTo(moveTo); +// } +// +// public void convertMoveToCoordinates() { +// String moveFrom = this.getLastMoveFrom(); +// String moveTo = this.getLastMoveTo(); +// +// if (moveFrom.length() != 2 || moveTo.length() != 2) { +// throw new RuntimeException("Incorrect move coordinates (convertMoveToCoordinates)"); +// } +// +// Column moveFromCol = Column.valueOf(moveFrom.substring(0, 1)); +// Row moveFromRow = Row.getRowByNumber(moveFrom.substring(1,2)); +// Column moveToCol = Column.valueOf(moveTo.substring(0, 1)); +// Row moveToRow = Row.getRowByNumber(moveTo.substring(1,2)); +// +// setLastMoveFromCol(moveFromCol); +// setLastMoveFromRow(moveFromRow); +// setLastMoveToCol(moveToCol); +// setLastMoveToRow(moveToRow); +// } +// +// public String convertMoveToString() { +// Row rowFrom = this.getLastMoveFromRow(); +// Row rowTo = this.getLastMoveToRow(); +// Column colFrom = this.getLastMoveFromCol(); +// Column colTo = this.getLastMoveToCol(); +// +// return ( +// colFrom.toString() + +// String.valueOf(rowFrom.getNum()) + +// colTo.toString() + +// String.valueOf(rowTo.getNum()) +// ); +// } +// +// public void displayMoveInfo() { +// String from = this.getLastMoveFrom(); +// String to = this.getLastMoveTo(); +// String playerName = this.getRole().formatName(); +// +// if (from == null || to == null) { +// System.out.println("Player " + playerName + " hasn't moved yet"); +// return; +// } +// +// System.out.println("Player " + playerName + " moved from " + from + " to " + to); +// } +// public Column getLastMoveFromCol() { +// return lastMoveFromCol; +// } +// +// public void setLastMoveFromCol(Column lastMoveFromCol) { +// this.lastMoveFromCol = lastMoveFromCol; +// } +// +// public Row getLastMoveFromRow() { +// return lastMoveFromRow; +// } +// +// public void setLastMoveFromRow(Row lastMoveFromRow) { +// this.lastMoveFromRow = lastMoveFromRow; +// } +// +// public Column getLastMoveToCol() { +// return lastMoveToCol; +// } +// +// public void setLastMoveToCol(Column lastMoveToCol) { +// this.lastMoveToCol = lastMoveToCol; +// } +// +// public Row getLastMoveToRow() { +// return lastMoveToRow; +// } +// +// public void setLastMoveToRow(Row lastMoveToRow) { +// this.lastMoveToRow = lastMoveToRow; +// } +// +// public Role getRole() { +// return role; +// } +// +// public String getLastMoveFrom() { +// return lastMoveFrom; +// } +// +// private void setLastMoveFrom(String lastMoveFrom) { +// this.lastMoveFrom = lastMoveFrom; +// } +// +// public String getLastMoveTo() { +// return lastMoveTo; +// } +// +// private void setLastMoveTo(String lastMoveTo) { +// this.lastMoveTo = lastMoveTo; +// } +//} diff --git a/src/com/jarocki/stanislaw/chess/Coordinate/Row.java b/src/com/jarocki/stanislaw/chess/Coordinate/Row.java new file mode 100644 index 0000000..42df46b --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Coordinate/Row.java @@ -0,0 +1,39 @@ +package com.jarocki.stanislaw.chess.Coordinate; + +public enum Row { + ONE, + TWO, + THREE, + FOUR, + FIVE, + SIX, + SEVEN, + EIGHT; + + public static Row getRowByNum(String number) { + switch (number) { + case "1": + return Row.ONE; + case "2": + return Row.TWO; + case "3": + return Row.THREE; + case "4": + return Row.FOUR; + case "5": + return Row.FIVE; + case "6": + return Row.SIX; + case "7": + return Row.SEVEN; + case "8": + return Row.EIGHT; + default: + throw new IllegalArgumentException("Invalid row number: " + number); + } + } + + public int getNum() { + return this.ordinal(); + } +} diff --git a/src/com/jarocki/stanislaw/chess/Game.java b/src/com/jarocki/stanislaw/chess/Game.java new file mode 100644 index 0000000..5780d19 --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Game.java @@ -0,0 +1,112 @@ +package com.jarocki.stanislaw.chess; + +import com.jarocki.stanislaw.chess.Board.Board; +import com.jarocki.stanislaw.chess.Piece.Color; +import com.jarocki.stanislaw.chess.Player.Player; +import com.jarocki.stanislaw.chess.Player.Role; + +import java.util.Scanner; + +public class Game { + private Board board; + + private boolean isGameOn; + + private boolean isWhiteTurn = true; + + public Game() { + board = new Board(); + } + + public void play() { + Scanner scanner = new Scanner(System.in); + this.setIsGameOn(true); + Board board = new Board(); + Player currPlayer = new Player(Role.WHITE); + + board.setUpPieces(); + + int iteration = 0; // tests only + +// String[] testMoves = Test.getOnlyPawnsOpening(); +// String[] testMoves = Test.getWrongPawnMoves(); +// String[] testMoves = Test.takeQueenOut(); +// String[] testMoves = Test.takeBishopOut(); +// String[] testMoves = Test.takeKnightsOut(); +// String[] testMoves = Test.takeRookOut(); +// String[] testMoves = Test.takeKingOut(); +// String[] testMoves = Test.getCastlingMoves(); + String[] testMoves = Test.getPawnPromotion(); +// String[] testMoves = Test.getOpeningMoves(); + + + while(getIsGameOn()) { + board.printBoard(); + + Color playerColor = this.getIsWhiteTurn() ? Color.WHITE : Color.BLACK; + + System.out.println("Enter " + playerColor.toString() + " next move: "); + + Test.delay(300); + + // tests + String input; + if(iteration >= testMoves.length) { + input = scanner.nextLine(); + } else { // tests only + input = testMoves[iteration]; + iteration = iteration + 1; + } + + String[] moves = input.toUpperCase().split(" "); + + if (moves.length != 2) { + System.out.println("Incorrect move format. Try \"e2 e4\". (Game)"); + continue; + } + + currPlayer.setLastMove(moves[0], moves[1]); + currPlayer.convertMoveToCoordinates(); + + int fromRow = currPlayer.getLastMoveFromRow().getNum(); + int fromCol = currPlayer.getLastMoveFromCol().getNum(); + int toRow = currPlayer.getLastMoveToRow().getNum(); + int toCol = currPlayer.getLastMoveToCol().getNum(); + + Test.displayCurrentMove(currPlayer.getRole().formatName(), moves[0], moves[1]); + + if (!board.isMoveValid(fromRow, fromCol, toRow, toCol, playerColor)) { + System.out.println("Moving " + currPlayer.getRole().formatName() + " from " + moves[0] + " to " + moves[1] + " is illegal. (Game)"); + this.switchTurn(); + currPlayer.switchRole(); + continue; + } + + board.makeMove(fromRow, fromCol, toRow, toCol); + currPlayer.displayMoveInfo(); + this.switchTurn(); + currPlayer.switchRole(); + } + scanner.close(); + } + + public void stopGame() { + this.setIsGameOn(false); + } + + private boolean getIsGameOn() { + return isGameOn; + } + + private void setIsGameOn(boolean isGameOn) { + this.isGameOn = isGameOn; + } + + public boolean getIsWhiteTurn() { + return isWhiteTurn; + } + + public void switchTurn() { + isWhiteTurn = !isWhiteTurn; + } +} diff --git a/src/com/jarocki/stanislaw/chess/Main.java b/src/com/jarocki/stanislaw/chess/Main.java new file mode 100644 index 0000000..de2a7f5 --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Main.java @@ -0,0 +1,9 @@ +package com.jarocki.stanislaw.chess; + +public class Main { + public static void main(String[] args) { + Game game = new Game(); + + game.play(); + } +} \ No newline at end of file diff --git a/src/com/jarocki/stanislaw/chess/Piece/Basic.java b/src/com/jarocki/stanislaw/chess/Piece/Basic.java new file mode 100644 index 0000000..19596f8 --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Piece/Basic.java @@ -0,0 +1,54 @@ +package com.jarocki.stanislaw.chess.Piece; + +import com.jarocki.stanislaw.chess.Board.Board; +import com.jarocki.stanislaw.chess.Coordinate.Column; +import com.jarocki.stanislaw.chess.Coordinate.Row; + +public class Basic { + private final Color color; + private Column column; + private Row row; + private Symbol symbol; + public Basic (Color color, Row row, Column column) { + this.color = color; + this.column = column; + this.row = row; + } + + public Color getColor() { + return color; + } + + public Column getColumn() { + return column; + } + + public void setColumn(Column column) { + this.column = column; + } + + public Row getRow() { + return row; + } + + public void setRow(Row row) { + this.row = row; + } + + public Symbol getSymbol() { + return this.symbol; + } + + public void setSymbol(Symbol symbol) { + this.symbol = symbol; + } + + public boolean isMoveValid(int targetRow, int targetColumn, Board board) { return false; } + + public Basic copy(Color color, Row row, Column column) { + Basic copy = new Basic(color, row, column); + copy.setSymbol(this.symbol); + return copy; + } + +} diff --git a/src/com/jarocki/stanislaw/chess/Piece/Bishop.java b/src/com/jarocki/stanislaw/chess/Piece/Bishop.java new file mode 100644 index 0000000..0226149 --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Piece/Bishop.java @@ -0,0 +1,54 @@ +package com.jarocki.stanislaw.chess.Piece; + +import com.jarocki.stanislaw.chess.Board.Board; +import com.jarocki.stanislaw.chess.Coordinate.Column; +import com.jarocki.stanislaw.chess.Coordinate.Row; + +public class Bishop extends Basic { + public Bishop(Color color, Row row, Column col) { + super(color, row, col); + setSymbol(getSymbol().BISHOP); + } + + @Override + public boolean isMoveValid(int toRow, int toCol, Board board) { + int row = this.getRow().getNum(); + int col = this.getColumn().getNum(); + + if (toRow < 0 || toRow >= 8 || toCol < 0 || toCol >= 8) { + return false; + } + + int dRow = toRow - row; + int dCol = toCol - col; + + // check if moving on diagonal + if (Math.abs(dRow) != Math.abs(dCol)) { + return false; + } + + // check if something between bishop and destination tile + int stepRow = dRow > 0 ? 1 : -1; + int stepCol = dCol > 0 ? 1 : -1; + + int currentRow = row + stepRow; + int currentCol = col + stepCol; + + while (currentRow != toRow || currentCol != toCol) { + if (board.getPiece(currentRow, currentCol) != null) { + return false; + } + + currentRow += stepRow; + currentCol += stepCol; + } + + // check destination clear/with opponent + Basic destinationPiece = board.getPiece(toRow, toCol); + return destinationPiece == null || destinationPiece.getColor() != this.getColor(); + } + + public Basic copy() { + return new Bishop(this.getColor(), this.getRow(), this.getColumn()); + } +} diff --git a/src/com/jarocki/stanislaw/chess/Piece/Color.java b/src/com/jarocki/stanislaw/chess/Piece/Color.java new file mode 100644 index 0000000..6b28060 --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Piece/Color.java @@ -0,0 +1,10 @@ +package com.jarocki.stanislaw.chess.Piece; + +public enum Color { + WHITE, + BLACK; + + public String toString() { + return this.name().substring(0,1) + this.name().substring(1).toLowerCase(); + } +} diff --git a/src/com/jarocki/stanislaw/chess/Piece/King.java b/src/com/jarocki/stanislaw/chess/Piece/King.java new file mode 100644 index 0000000..e3a43af --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Piece/King.java @@ -0,0 +1,91 @@ +package com.jarocki.stanislaw.chess.Piece; + +import com.jarocki.stanislaw.chess.Board.Board; +import com.jarocki.stanislaw.chess.Coordinate.Column; +import com.jarocki.stanislaw.chess.Coordinate.Row; + +public class King extends Basic { + private boolean hasMoved; + + public King(Color color, Row row, Column col) { + super(color, row, col); + this.setSymbol(Symbol.KING); + hasMoved = false; + } + + public boolean hasMoved() { + return hasMoved; + } + + public boolean isMoveValid(int toRow, int toCol, Board board) { + int row = this.getRow().getNum(); + int col = this.getColumn().getNum(); + + // check if inside the board + if (toRow < 0 || toRow >= 8 || toCol < 0 || toCol >= 8) { + return false; + } + + int dRow = Math.abs(toRow - row); + int dCol = Math.abs(toCol - col); + + // king can move only by one tile unless its a castling + if ((dRow != 1 || dCol != 0) && (dRow != 0 || dCol != 1) && (dRow != 1 || dCol != 1)) { + // Check for castling + if (isCastlingMove(toRow, toCol, board)) { + return true; + } + return false; + } + + // check if destination is empty or with opponent + Basic destinationPiece = board.getPiece(toRow, toCol); + return destinationPiece == null || destinationPiece.getColor() != this.getColor(); + } + + public Basic copy() { + King copy = new King(this.getColor(), this.getRow(), this.getColumn()); + copy.hasMoved = hasMoved; + return copy; + } + + private boolean isCastlingMove(int toRow, int toCol, Board board) { + int fromRow = this.getRow().getNum(); + int fromCol = this.getColumn().getNum(); + + // check if king moved + if (hasMoved()) { + return false; + } + + // check if pattern is right - long/short castling + if (toRow != fromRow || (toCol != 2 && toCol != 6)) { + return false; + } + + // check if not making the check + if (board.isKingInCheck(this.getColor())) { + return false; + } + + // + int rookCol = (toCol == 2) ? 0 : 7; + Rook rook = (Rook) board.getPiece(fromRow, rookCol); + if (!(rook instanceof Rook) || rook.getColor() != this.getColor()) { + return false; + } + + // Check if the path between the king and rook is clear + int startCol = (toCol == 2) ? 1 : 5; + int endCol = (toCol == 2) ? 3 : 6; + int row = fromRow; + for (int col = startCol; col <= endCol; col++) { + Basic piece = board.getPiece(row, col); + if (piece != null) { + return false; + } + } + + return true; + } +} diff --git a/src/com/jarocki/stanislaw/chess/Piece/Knight.java b/src/com/jarocki/stanislaw/chess/Piece/Knight.java new file mode 100644 index 0000000..9da5799 --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Piece/Knight.java @@ -0,0 +1,31 @@ +package com.jarocki.stanislaw.chess.Piece; + +import com.jarocki.stanislaw.chess.Board.Board; +import com.jarocki.stanislaw.chess.Coordinate.Column; +import com.jarocki.stanislaw.chess.Coordinate.Row; + +public class Knight extends Basic { + public Knight(Color color, Row row, Column col) { + super(color, row, col); + setSymbol(Symbol.KNIGHT); + } + @Override + public boolean isMoveValid(int toRow, int toCol, Board board) { + int row = this.getRow().getNum(); + int col = this.getColumn().getNum(); + // make sure the destination coordinates are on the board + if (toRow < 0 || toRow >= 8 || toCol < 0 || toCol >= 8) { + return false; + } + + int dRow = Math.abs(toRow - row); + int dCol = Math.abs(toCol - col); + + // knight can move only in "L" path = to cols up one row vert and vice versa + return (dRow == 2 && dCol == 1) || (dRow == 1 && dCol == 2); + } + + public Basic copy() { + return new Knight(this.getColor(), this.getRow(), this.getColumn()); + } +} diff --git a/src/com/jarocki/stanislaw/chess/Piece/Pawn.java b/src/com/jarocki/stanislaw/chess/Piece/Pawn.java new file mode 100644 index 0000000..579ecc6 --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Piece/Pawn.java @@ -0,0 +1,101 @@ +package com.jarocki.stanislaw.chess.Piece; + +import com.jarocki.stanislaw.chess.Board.Board; +import com.jarocki.stanislaw.chess.Coordinate.Column; +import com.jarocki.stanislaw.chess.Coordinate.Row; + +public class Pawn extends Basic { + + public Pawn(Color color, Row row, Column col) { + super(color, row, col); + this.setSymbol(Symbol.PAWN); + } + + @Override + public boolean isMoveValid(int targetRow, int targetColumn, Board board) { + // check if inside board + if (targetRow < 0 || targetRow >= 8 || targetColumn < 0 || targetColumn >= 8) { + return false; + } + + // destination tile empty/with opponent's pawn + if (board.getPiece(targetRow, targetColumn) == null) { + if (getColumn().getNum() == targetColumn) { + // moving forward by one row depending on the color + if (getColor() == Color.WHITE) { + if (targetRow - getRow().getNum() == 1) { + return true; + } else if (isStartingPosition(getRow(), getColor()) && targetRow - getRow().getNum() == 2) { + // check if can move two tiles + if (board.getPiece(getRow().getNum() + 1, targetColumn) == null) { + return true; + } + } + } else { + if (targetRow - getRow().getNum() == -1) { + return true; + } else if (isStartingPosition(getRow(), getColor()) && targetRow - getRow().getNum() == -2) { + // check if can move two tiles + if (board.getPiece(getRow().getNum() - 1, targetColumn) == null) { + return true; + } + } + } + } + // if en passant + return isValidCapture(targetRow, targetColumn, board); + } else { + // i know it's silly but works + return isValidCapture(targetRow, targetColumn, board); + } + } + + private boolean isValidCapture(int targetRow, int targetColumn, Board board) { + // inside board + if (targetRow < 0 || targetRow >= 8 || targetColumn < 0 || targetColumn >= 8) { + return false; + } + + Basic targetPiece = board.getPiece(targetRow, targetColumn); + if (targetPiece == null) { + // en passant check + if (targetColumn == getColumn().getNum() - 1 || targetColumn == getColumn().getNum() + 1) { + // check target tile + if (targetRow == getRow().getNum() + (getColor() == Color.WHITE ? 1 : -1)) { + Pawn lastMovedPawn = board.getLastMovedPawn(); + if (lastMovedPawn != null && lastMovedPawn.getRow() == getRow() && + lastMovedPawn.getColumn().getNum() == targetColumn) { + // correct en passant + return true; + } + } + } + return false; + } + int col = getColumn().getNum(); + if (targetColumn == getColumn().getNum() - 1) { + // diagonal to top left + Color color = getColor(); + if (getColor() == Color.WHITE && targetRow == getRow().getNum() + 1) { + return true; + } else if (getColor() == Color.BLACK && targetRow == getRow().getNum() - 1) { + return true; + } + } else if (targetColumn == getColumn().getNum() + 1) { + // one tile to top right + if (getColor() == Color.WHITE && targetRow == getRow().getNum() + 1) { + return true; + } else if (getColor() == Color.BLACK && targetRow == getRow().getNum() - 1) { + return true; + } + } + + return false; + } + + private boolean isStartingPosition(Row currentRow, Color color) { + // check if the pawn is in its starting position (white row - 2, black row - 7) + return (color == Color.WHITE && currentRow == Row.TWO) + || (color == Color.BLACK && currentRow == Row.SEVEN); + } +} diff --git a/src/com/jarocki/stanislaw/chess/Piece/Queen.java b/src/com/jarocki/stanislaw/chess/Piece/Queen.java new file mode 100644 index 0000000..e1283fa --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Piece/Queen.java @@ -0,0 +1,53 @@ +package com.jarocki.stanislaw.chess.Piece; + +import com.jarocki.stanislaw.chess.Board.Board; +import com.jarocki.stanislaw.chess.Coordinate.Column; +import com.jarocki.stanislaw.chess.Coordinate.Row; + +public class Queen extends Basic { + public Queen(Color color, Row row, Column col) { + super(color, row, col); + setSymbol(Symbol.QUEEN); + } + @Override + public boolean isMoveValid(int toRow, int toCol, Board board) { + int row = this.getRow().getNum(); + int col = this.getColumn().getNum(); + //check if inside the board + if (toRow < 0 || toRow >= 8 || toCol < 0 || toCol >= 8) { + return false; + } + + int dRow = toRow - row; + int dCol = toCol - col; + + // queen moving vertical/horizontally/diagonally + if (dRow != 0 && dCol != 0 && Math.abs(dRow) != Math.abs(dCol)) { + return false; + } + + // check if there's sth between her and the destination + int stepRow = dRow == 0 ? 0 : (dRow > 0 ? 1 : -1); + int stepCol = dCol == 0 ? 0 : (dCol > 0 ? 1 : -1); + + int currentRow = row + stepRow; + int currentCol = col + stepCol; + + while (currentRow != toRow || currentCol != toCol) { + if (board.getPiece(currentRow, currentCol) != null) { + return false; + } + + currentRow += stepRow; + currentCol += stepCol; + } + + // destination tile has to be empty or with opponent + Basic destinationPiece = board.getPiece(toRow, toCol); + return destinationPiece == null || destinationPiece.getColor() != this.getColor(); + } + + public Basic copy() { + return new Queen(this.getColor(), this.getRow(), this.getColumn()); + } +} diff --git a/src/com/jarocki/stanislaw/chess/Piece/Rook.java b/src/com/jarocki/stanislaw/chess/Piece/Rook.java new file mode 100644 index 0000000..ce706da --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Piece/Rook.java @@ -0,0 +1,60 @@ +package com.jarocki.stanislaw.chess.Piece; + +import com.jarocki.stanislaw.chess.Board.Board; +import com.jarocki.stanislaw.chess.Coordinate.Column; +import com.jarocki.stanislaw.chess.Coordinate.Row; + +public class Rook extends Basic { + private boolean hasMoved = false; + public Rook(Color color, Row row, Column col) { + super(color, row, col); + setSymbol(Symbol.ROOK); + } + + @Override + public boolean isMoveValid(int toRow, int toCol, Board board) { + int row = this.getRow().getNum(); + int col = this.getColumn().getNum(); + + if (toRow < 0 || toRow >= 8 || toCol < 0 || toCol >= 8) { + return false; + } + + + int dRow = toRow - row; + int dCol = toCol - col; + + // rook can move only vertical/horizontal + if (dRow != 0 && dCol != 0) { + return false; + } + + // check for objects on the path to destination + int stepRow = Integer.compare(dRow, 0); + int stepCol = Integer.compare(dCol, 0); + + int currentRow = row + stepRow; + int currentCol = col + stepCol; + + while (currentRow != toRow || currentCol != toCol) { + if (board.getPiece(currentRow, currentCol) != null) { + return false; + } + + currentRow += stepRow; + currentCol += stepCol; + } + + // check destination empty/with opponent + Basic destinationPiece = board.getPiece(toRow, toCol); + return destinationPiece == null || destinationPiece.getColor() != this.getColor(); + } + + public void setHasMoved() { + hasMoved = true; + } + + public Basic copy() { + return new Rook(this.getColor(), this.getRow(), this.getColumn()); + } +} diff --git a/src/com/jarocki/stanislaw/chess/Piece/Symbol.java b/src/com/jarocki/stanislaw/chess/Piece/Symbol.java new file mode 100644 index 0000000..7c9b6bf --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Piece/Symbol.java @@ -0,0 +1,26 @@ +package com.jarocki.stanislaw.chess.Piece; + +public enum Symbol { + KING("K"), + QUEEN("Q"), + ROOK("R"), + BISHOP("B"), + KNIGHT("N"), + PAWN("P"); + +// PAWN("♟"); +// QUEEN("♛"), +// ROOK("♜"), +// BISHOP("♝"), +// KNIGHT("♞"), + + private final String symbol; + + Symbol(String symbol) { + this.symbol = symbol; + } + + public String getChar() { + return symbol; + } +} diff --git a/src/com/jarocki/stanislaw/chess/Player/Player.java b/src/com/jarocki/stanislaw/chess/Player/Player.java new file mode 100644 index 0000000..75a28c3 --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Player/Player.java @@ -0,0 +1,128 @@ +package com.jarocki.stanislaw.chess.Player; + +import com.jarocki.stanislaw.chess.Coordinate.Column; +import com.jarocki.stanislaw.chess.Coordinate.Row; +import com.jarocki.stanislaw.chess.Piece.Color; + +public class Player { + private Role role; + private String lastMoveFrom; + private String lastMoveTo; + private Column lastMoveFromCol; + private Row lastMoveFromRow; + private Column lastMoveToCol; + private Row lastMoveToRow; + + public Player(Role role) { + this.role = role; + } + + public void switchRole (){ + this.role = getRole().equals(Role.WHITE) ? Role.BLACK : Role.WHITE; + } + + public void setLastMove(String moveFrom, String moveTo) { + if(moveFrom == null || moveTo == null) { + System.out.println("Some moves are missing: moveFrom = " + moveFrom + " and moveTo = " + moveTo + " (setLastMove)"); + } + setLastMoveFrom(moveFrom); + setLastMoveTo(moveTo); + } + + public void convertMoveToCoordinates() { + String moveFrom = this.getLastMoveFrom(); + String moveTo = this.getLastMoveTo(); + + if (moveFrom.length() != 2 || moveTo.length() != 2) { + throw new RuntimeException("Incorrect move coordinates (convertMoveToCoordinates)"); + } + + Column moveFromCol = Column.valueOf(moveFrom.substring(0, 1)); + Row moveFromRow = Row.getRowByNum(moveFrom.substring(1,2)); + Column moveToCol = Column.valueOf(moveTo.substring(0, 1)); + Row moveToRow = Row.getRowByNum(moveTo.substring(1,2)); + + setLastMoveFromCol(moveFromCol); + setLastMoveFromRow(moveFromRow); + setLastMoveToCol(moveToCol); + setLastMoveToRow(moveToRow); + } + + public String convertMoveToString() { + Row rowFrom = this.getLastMoveFromRow(); + Row rowTo = this.getLastMoveToRow(); + Column colFrom = this.getLastMoveFromCol(); + Column colTo = this.getLastMoveToCol(); + + return ( + colFrom.toString() + + String.valueOf(rowFrom.getNum()) + + colTo.toString() + + String.valueOf(rowTo.getNum()) + ); + } + + public void displayMoveInfo() { + String from = this.getLastMoveFrom(); + String to = this.getLastMoveTo(); + String playerName = this.getRole().formatName(); + + if (from == null || to == null) { + System.out.println("Player " + playerName + " hasn't moved yet"); + return; + } + + System.out.println("Player " + playerName + " moved from " + from + " to " + to); + } + public Column getLastMoveFromCol() { + return lastMoveFromCol; + } + + public void setLastMoveFromCol(Column lastMoveFromCol) { + this.lastMoveFromCol = lastMoveFromCol; + } + + public Row getLastMoveFromRow() { + return lastMoveFromRow; + } + + public void setLastMoveFromRow(Row lastMoveFromRow) { + this.lastMoveFromRow = lastMoveFromRow; + } + + public Column getLastMoveToCol() { + return lastMoveToCol; + } + + public void setLastMoveToCol(Column lastMoveToCol) { + this.lastMoveToCol = lastMoveToCol; + } + + public Row getLastMoveToRow() { + return lastMoveToRow; + } + + public void setLastMoveToRow(Row lastMoveToRow) { + this.lastMoveToRow = lastMoveToRow; + } + + public Role getRole() { + return role; + } + + public String getLastMoveFrom() { + return lastMoveFrom; + } + + private void setLastMoveFrom(String lastMoveFrom) { + this.lastMoveFrom = lastMoveFrom; + } + + public String getLastMoveTo() { + return lastMoveTo; + } + + private void setLastMoveTo(String lastMoveTo) { + this.lastMoveTo = lastMoveTo; + } +} diff --git a/src/com/jarocki/stanislaw/chess/Player/Role.java b/src/com/jarocki/stanislaw/chess/Player/Role.java new file mode 100644 index 0000000..af399ed --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Player/Role.java @@ -0,0 +1,10 @@ +package com.jarocki.stanislaw.chess.Player; + +public enum Role { + BLACK, + WHITE; + + public String formatName() { + return this.name().substring(0,1) + this.name().substring(1).toLowerCase(); + } +} \ No newline at end of file diff --git a/src/com/jarocki/stanislaw/chess/Test.java b/src/com/jarocki/stanislaw/chess/Test.java new file mode 100644 index 0000000..8b35e10 --- /dev/null +++ b/src/com/jarocki/stanislaw/chess/Test.java @@ -0,0 +1,142 @@ +package com.jarocki.stanislaw.chess; + +public class Test { + static public String[] getOnlyPawnsOpening() { + return new String[]{ + "e2 e4", "d7 d5", + "c2 c4", "e7 e5", + "e4 d5", "e5 e4", + "a2 a4", "a7 a6", + "h2 h3", "h7 h5", + "a4 a5", "c7 c5", + "d5 c6", "b7 b5", + "a5 b6", + }; + } + + static public String[] getWrongPawnMoves() { + return new String[]{ + "e2 e4", "d7 d5", + "c2 c4", "e7 e5", + "e4 d5", "f4 f5", + "c4 c6", "g6 g5", + "b2 b1", "d5 d4", + }; + } + + static public String[] takeRookOut() { + return new String[]{ + "h2 h4", "g7 g5", + "h4 g5", "b7 b5", + "h1 h7", "f7 f5", + "h7 d7", "a8 a5", // wrong move over opponents and self pieces + "h7 f7", "a7 a5", + "f7 f5", "h8 h7", + "f5 b5", "h7 h1", + "b5 f5", "h1 g1", + "f5 a5", "a8 a6", + }; + } + + static public String[] takeBishopOut() { + return new String[]{ + "e2 e4", "b7 b6", + "f1 c4", "c8 b7", + "c4 g8", "b7 a8", // wrong moves - over piece/onto own piece + "c4 d4", "b7 b4", // wrong moves - horizontal i vertical + "c4 f7", "b7 e4", + "f7 g8", "e4 c2", // in future there's a check + }; + } + + static public String[] takeKnightsOut() { + return new String[]{ + "b1 a3", "g8 f6", + "g1 g3", "f6 h7", // wrong moves - occupied own piece/illegal field + "a3 c4", "f6 d5", + "a3 c4", "f6 d5", + "c4 e3", "d5 e3", + }; + } + + static public String[] takeQueenOut() { + return new String[]{ + "e2 e4", "e7 e6", // move pawns out + "d1 f3", "d8 h4", // move queens out + "f3 b4", "h4 h1", // wrong move - random field/jump over piece <<< + "f3 b3", "h4 f6", // move queens other horizontally and diagonally + "b3 b7", "f6 b2", // capture pawns with queens + + }; + } + + static public String[] takeKingOut() { + return new String[]{ + "e2 e4", "b7 b6", // move pawns out + "e1 e2", "f7 f5", // move one king out and pawn to it + "e2 f3", "h7 h6", // move one king out and queen out + "f3 f4", "b8 c6", // come with king closer to pawn and move knight for castling + "f4 f5", "c8 b7", // take pawn by king and move bishop for castling + "f5 f4", "e7 e5", // get back with king and attack with pawn + "f4 e3", "d8 h4", // run away with king and get out queen for castling + "g2 g3", "h4 g5", // attack queen and check the white king with queen + "a2 a3", "a2 a3", // invalid move - makes CHECK, black invalid too for handicapp << + "f2 f4", "c6 e7", // valid move - hide behind the pawn and prepare knight to check king + "f4 g5", "e7 d5", // kill black queen with pawn and attack white king with knight + "d1 h5", // invalid move - try to check black king, but check from knight + }; + } + + static public String[] getOpeningMoves() { + return new String[]{ + "e2 e4", "e7 e5", + "g1 f3", "b8 c6", + "f1 c4", "g8 f6", + "d2 d4", "e5 d4", + "f3 d4", "f6 d5", + "e4 d5", "e7 e6", + "c1 g5", "d8 f6", + "d1 f3", "e8 g8", + "e1 g1", "f8 e7", // castling + "g1 h1", "d5 c6", + "d4 c5", "c8 d7", + "g5 h6", "f6 h6", + }; + } + + static public String[] getCastlingMoves() { + return new String[]{ + "e2 e4", "d7 d6", + "f1 c4", "c8 f5", + "g1 f3", "b8 c6", + "g1 f3", "b8 c6", + "e1 g1", "d8 d7", // castling 1 + "a2 a3", "e8 c8", // castling 2 + }; + } + + static public String[] getPawnPromotion() { + return new String[]{ + "e2 e4", "d7 d5", + "e4 e5", "d5 d4", + "e5 e6", "d4 d3", + "e6 f7", "e8 d7", + "h2 h3", "d3 c2", + "f7 g8", "c2 b1", // promote to queens both + "g8 b3", "b1 f5", // move queens to demonstrate + "b3 b7", // take pawn downs + }; + } + + static public void delay(int milliseconds) { + try { + Thread.sleep(milliseconds); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public static void displayCurrentMove(String playerColor, String moveFrom, String moveTo) { + System.out.println("[DEBUG] Moving " + playerColor + " from " + moveFrom + " to " + moveTo); + } +}