diff --git a/src/Bishop.java b/src/Bishop.java index 74f9cd7..85c5b06 100644 --- a/src/Bishop.java +++ b/src/Bishop.java @@ -9,8 +9,8 @@ public class Bishop extends Piece { return 3; } - public ArrayList getPossibleMoves(BoardCoordinate position, Board board) { - ArrayList possibleMoves = new ArrayList<>(); + public ArrayList getPossibleMoves(BoardCoordinate position, Board board) { + ArrayList possibleMoves = new ArrayList<>(); getPossibleMovesInDirection(1, 1, position, board, possibleMoves); getPossibleMovesInDirection(-1, -1, position, board, possibleMoves); diff --git a/src/Board.java b/src/Board.java index 51833ab..d85a837 100644 --- a/src/Board.java +++ b/src/Board.java @@ -27,20 +27,15 @@ public class Board { Piece[][] board; // The current board coordinate that's being dragged BoardCoordinate dragging = null; - ArrayList legalMoves = null; + ArrayList legalMoves = null; Stack moveHistory; public boolean isGameOver; - public boolean victor; - Image youWin; - Image youLose; public Board() { moveHistory = new Stack<>(); // Initialize DrawingPanel panel = new DrawingPanel(DIMENSION, DIMENSION); - youWin = panel.loadImage("you-win.png"); - youLose = panel.loadImage("you-lose.png"); graphics = panel.getGraphics(); // Connect up event handlers @@ -51,11 +46,6 @@ public class Board { }); panel.onMouseUp(this::handleMouseUp); - // Initialize board - setup(); - } - - public void setup() { // Initialize board board = new Piece[BOARD_SIZE][BOARD_SIZE]; @@ -134,24 +124,13 @@ public class Board { public void undoMove() { if (moveHistory.isEmpty()) return; Move lastMove = moveHistory.pop(); - undoMove(lastMove); - undoMove(lastMove.submove); - } - - void undoMove(Move move) { - if (move == null) return; - set(move.from, get(move.to)); - set(move.to, move.captured); + set(lastMove.from, get(lastMove.to)); + set(lastMove.to, lastMove.captured); } // Mouse down event handler // This sets the currently dragging piece void handleMouseDown(int x, int y) { - if (isGameOver) { - isGameOver = false; - setup(); - return; - } // Get board coordinate of mouse click BoardCoordinate coordinate = new ScreenCoordinate(x, y).toBoard(); // If there's no piece there, return @@ -164,10 +143,6 @@ public class Board { draw(x, y); } - void setLastMovedPieceAsMoved() { - get(moveHistory.peek().to).moved = true; - } - void handleMouseUp(int x, int y) { // Get board coordinate of mouse release BoardCoordinate newCoordinate = new ScreenCoordinate(x, y).toBoard(); @@ -175,17 +150,27 @@ public class Board { if (dragging != null && !newCoordinate.equals(dragging)) { // dragging is BoardCoordinate of piece being dragged Piece piece = get(dragging); - ArrayList legalMoves = piece.getLegalMoves(dragging, this); - for (Move legalMove : legalMoves) { - if (newCoordinate.equals(legalMove.to)) { + ArrayList legalMoves = piece.getLegalMoves(dragging, this); + for (BoardCoordinate legalMove : legalMoves) { + if (newCoordinate.equals(legalMove)) { move(dragging, newCoordinate); - setLastMovedPieceAsMoved(); - checkForCheckmate(); - if (!isGameOver) { - move(ChessAI.findBestMove(this)); - setLastMovedPieceAsMoved(); - checkForCheckmate(); + // QUICK TESTING CODE + Piece movedPiece = get(newCoordinate); + King oppositeKing = movedPiece.black ? whiteKing : blackKing; + BoardCoordinate oppositeKingPosition = null; + boolean inCheck = false; + for (BoardCoordinate move : movedPiece.getLegalMoves(newCoordinate, this)) { + if (get(move) == oppositeKing) { + oppositeKingPosition = move; + inCheck = true; + break; + } } + if (inCheck && oppositeKing.getLegalMoves(oppositeKingPosition, this).size() == 0) + isGameOver = true; + + + move(ChessAI.findBestMove(this)); break; } } @@ -196,34 +181,6 @@ public class Board { draw(); } - public void checkForCheckmate() { - BoardCoordinate movedCoordinate = moveHistory.peek().to; - Piece movedPiece = get(movedCoordinate); - King oppositeKing = movedPiece.black ? whiteKing : blackKing; - BoardCoordinate oppositeKingPosition = null; - boolean inCheck = false; - for (Move move : movedPiece.getLegalMoves(movedCoordinate, this)) { - if (get(move.to) == oppositeKing) { - oppositeKingPosition = move.to; - inCheck = true; - break; - } - } - if (inCheck) { - isGameOver = true; - for (Move move : getAllLegalMoves(!movedPiece.black)) { - move(move); - if (!oppositeKing.isInCheck(move, this)) { - isGameOver = false; - undoMove(); - break; - } - undoMove(); - } - } - victor = movedPiece.black; - } - public void draw() { draw(null); } @@ -250,16 +207,13 @@ public class Board { drawRect(x, y); if (dragging != null) { graphics.setColor(new Color(0, 128, 0, 128)); - for (Move legalMove : legalMoves) - drawRect(legalMove.to); + for (BoardCoordinate legalMove : legalMoves) + drawRect(legalMove); if (mousePosition != null) { BoardCoordinate hovering = mousePosition.toBoard(); - for (Move legalMove : legalMoves) { - if (legalMove.to.equals(hovering)) { - graphics.setColor(get(hovering) == null ? new Color(0, 0, 255, 128) : new Color(255, 0, 0, 128)); - drawRect(mousePosition.toBoard()); - break; - } + if (legalMoves.contains(hovering)) { + graphics.setColor(get(hovering) == null ? new Color(0, 0, 255, 128) : new Color(255, 0, 0, 128)); + drawRect(mousePosition.toBoard()); } } } @@ -270,11 +224,6 @@ public class Board { // Otherwise, render it at the center of the board tile piece.draw(graphics, panel, boardCoordinate.equals(dragging) ? mousePosition : boardCoordinate.toScreen()); }); - - // Draw game over text - if (isGameOver) { - graphics.drawImage(victor ? youLose : youWin, 0, 0, panel); - } } // Functional interfaces for forEachPiece @@ -313,12 +262,14 @@ public class Board { forEachPiece((x, y, piece) -> tileAction.forEachTile(new BoardCoordinate(x, y), get(x, y))); } - public ArrayList getAllLegalMoves(boolean black) { + public ArrayList getAllLegalMoves() { ArrayList allLegalMoves = new ArrayList<>(); forEachPiece((from, piece) -> { - if (piece.black != black) return; - ArrayList legalTiles = piece.getLegalMoves(from, this); - allLegalMoves.addAll(legalTiles); + if (!piece.black) return; + ArrayList legalTiles = piece.getLegalMoves(from, this); + for (BoardCoordinate to : legalTiles) { + allLegalMoves.add(new Move(from, to)); + } }); return allLegalMoves; } diff --git a/src/ChessAI.java b/src/ChessAI.java index 8fe8ce5..24b642e 100644 --- a/src/ChessAI.java +++ b/src/ChessAI.java @@ -5,7 +5,7 @@ public class ChessAI { int bestScore = Integer.MIN_VALUE; Move bestMove = null; - for (Move move : board.getAllLegalMoves(true)) { + for (Move move : board.getAllLegalMoves()) { board.move(move); int score = minimax(board, MAX_DEPTH, Integer.MIN_VALUE, Integer.MAX_VALUE, false); board.undoMove(); @@ -27,7 +27,7 @@ public class ChessAI { int score; if (maximizingPlayer) { score = Integer.MIN_VALUE; - for (Move move : board.getAllLegalMoves(true)) { + for (Move move : board.getAllLegalMoves()) { board.move(move); score = Math.max(score, minimax(board, depth - 1, alpha, beta, false)); board.undoMove(); @@ -38,7 +38,7 @@ public class ChessAI { } } else { score = Integer.MAX_VALUE; - for (Move move : board.getAllLegalMoves(true)) { + for (Move move : board.getAllLegalMoves()) { board.move(move); score = Math.min(score, minimax(board, depth - 1, alpha, beta, true)); board.undoMove(); diff --git a/src/King.java b/src/King.java index 95ed8f2..cbf987a 100644 --- a/src/King.java +++ b/src/King.java @@ -9,19 +9,16 @@ public class King extends Piece { return 12; } - public ArrayList getPossibleMoves(BoardCoordinate position, Board board) { - ArrayList possibleMoves = new ArrayList<>(); - - possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 1, position.y - 1))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 1, position.y + 1))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 1, position.y))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 1, position.y - 1))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 1, position.y + 1))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 1, position.y))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x, position.y + 1))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x, position.y - 1))); - Piece rightRook = board.get(position.x + 3, position.y); - + public ArrayList getPossibleMoves(BoardCoordinate position, Board board) { + ArrayList possibleMoves = new ArrayList<>(); + possibleMoves.add(new BoardCoordinate(position.x - 1, position.y - 1)); + possibleMoves.add(new BoardCoordinate(position.x - 1, position.y + 1)); + possibleMoves.add(new BoardCoordinate(position.x - 1, position.y)); + possibleMoves.add(new BoardCoordinate(position.x + 1, position.y - 1)); + possibleMoves.add(new BoardCoordinate(position.x + 1, position.y + 1)); + possibleMoves.add(new BoardCoordinate(position.x + 1, position.y)); + possibleMoves.add(new BoardCoordinate(position.x, position.y + 1)); + possibleMoves.add(new BoardCoordinate(position.x, position.y - 1)); return possibleMoves; } } \ No newline at end of file diff --git a/src/Knight.java b/src/Knight.java index 2af73ac..c9ed6e4 100644 --- a/src/Knight.java +++ b/src/Knight.java @@ -10,16 +10,17 @@ public class Knight extends Piece { return 3; } - public ArrayList getPossibleMoves(BoardCoordinate position, Board board) { - ArrayList possibleMoves = new ArrayList<>(); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 2, position.y - 1))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 1, position.y - 2))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 1, position.y - 2))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 2, position.y - 1))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 2, position.y + 1))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 1, position.y + 2))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 1, position.y + 2))); - possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 2, position.y + 1))); + public ArrayList getPossibleMoves(BoardCoordinate position, Board board) { + ArrayList possibleMoves = new ArrayList<>(); + possibleMoves.add(new BoardCoordinate(position.x - 2, position.y - 1)); + possibleMoves.add(new BoardCoordinate(position.x - 1, position.y - 2)); + possibleMoves.add(new BoardCoordinate(position.x + 1, position.y - 2)); + possibleMoves.add(new BoardCoordinate(position.x + 2, position.y - 1)); + possibleMoves.add(new BoardCoordinate(position.x + 2, position.y + 1)); + possibleMoves.add(new BoardCoordinate(position.x + 1, position.y + 2)); + possibleMoves.add(new BoardCoordinate(position.x - 1, position.y + 2)); + possibleMoves.add(new BoardCoordinate(position.x - 2, position.y + 1)); + // test return possibleMoves; } } diff --git a/src/Move.java b/src/Move.java index 13bbd1f..a8f9c59 100644 --- a/src/Move.java +++ b/src/Move.java @@ -1,11 +1,7 @@ -import java.util.ArrayList; - public class Move { public BoardCoordinate from; public BoardCoordinate to; public Piece captured; - // e.g. castling, castle move. Done after. - public Move submove; public Move(BoardCoordinate from, BoardCoordinate to) { this.from = from; @@ -17,4 +13,4 @@ public class Move { this.to = to; this.captured = captured; } -} \ No newline at end of file +} diff --git a/src/Pawn.java b/src/Pawn.java index ecbd95f..1d1ea90 100644 --- a/src/Pawn.java +++ b/src/Pawn.java @@ -9,14 +9,12 @@ public class Pawn extends Piece { return 1; } - public ArrayList getPossibleMoves(BoardCoordinate position, Board board) { - ArrayList possibleMoves = new ArrayList<>(); + public ArrayList getPossibleMoves(BoardCoordinate position, Board board) { + ArrayList possibleMoves = new ArrayList<>(); if (this.black) { - possibleMoves.add(new Move(position, new BoardCoordinate(position.x, position.y + 1))); - if (!moved) possibleMoves.add(new Move(position, new BoardCoordinate(position.x, position.y + 2))); + possibleMoves.add(new BoardCoordinate(position.x, position.y + 1)); } else { - possibleMoves.add(new Move(position, new BoardCoordinate(position.x, position.y - 1))); - if (!moved) possibleMoves.add(new Move(position, new BoardCoordinate(position.x, position.y - 2))); + possibleMoves.add(new BoardCoordinate(position.x, position.y - 1)); } return possibleMoves; } diff --git a/src/Piece.java b/src/Piece.java index 9309ce8..a98ad2e 100644 --- a/src/Piece.java +++ b/src/Piece.java @@ -8,7 +8,6 @@ public abstract class Piece { static final int DIMENSION = 48; Image image; public boolean black; - public boolean moved = false; public abstract int getValue(); @@ -17,29 +16,29 @@ public abstract class Piece { image = panel.loadImage(black ? blackImagePath : whiteImagePath); } - public abstract ArrayList getPossibleMoves(BoardCoordinate position, Board board); + public abstract ArrayList getPossibleMoves(BoardCoordinate position, Board board); - public ArrayList getLegalMoves(BoardCoordinate position, Board board) { + public ArrayList getLegalMoves(BoardCoordinate position, Board board) { return getLegalMoves(position, board, true); } - public ArrayList getLegalMoves(BoardCoordinate position, Board board, boolean doCheckChecks) { - ArrayList legalMoves = getPossibleMoves(position, board); + public ArrayList getLegalMoves(BoardCoordinate position, Board board, boolean doCheckChecks) { + ArrayList legalMoves = getPossibleMoves(position, board); for (int i = 0; i < legalMoves.size(); i++) { - Move possibleMove = legalMoves.get(i); - Piece targetPiece = board.get(possibleMove.to); + BoardCoordinate possibleMove = legalMoves.get(i); + Piece targetPiece = board.get(possibleMove); if ( // other piece of same color (targetPiece != null && targetPiece.black == black) || // outside of bounds of board - possibleMove.to.x < 0 || - possibleMove.to.y < 0 || - possibleMove.to.x >= Board.BOARD_SIZE || - possibleMove.to.y >= Board.BOARD_SIZE || + possibleMove.x < 0 || + possibleMove.y < 0 || + possibleMove.x >= Board.BOARD_SIZE || + possibleMove.y >= Board.BOARD_SIZE || // is in check - (doCheckChecks && isInCheck(new Move(position, possibleMove.to), board)) + (doCheckChecks && isInCheck(position, possibleMove, board)) ) { legalMoves.remove(i); i--; @@ -49,16 +48,16 @@ public abstract class Piece { return legalMoves; } - boolean isInCheck(Move move, Board board) { + boolean isInCheck(BoardCoordinate from, BoardCoordinate to, Board board) { boolean isInCheck = false; - board.move(move); + board.move(from, to); outer: for (int y = 0; y < Board.BOARD_SIZE; y++) { for (int x = 0; x < Board.BOARD_SIZE; x++) { Piece piece = board.get(x, y); if (piece == null || piece.black == black) continue; - ArrayList legalMoves = piece.getLegalMoves(new BoardCoordinate(x, y), board, false); - for (Move legalMove : legalMoves) { - Piece pieceAtMove = board.get(legalMove.to); + ArrayList legalMoves = piece.getLegalMoves(new BoardCoordinate(x, y), board, false); + for (BoardCoordinate move : legalMoves) { + Piece pieceAtMove = board.get(move); if (pieceAtMove instanceof King) { isInCheck = true; break outer; @@ -80,13 +79,13 @@ public abstract class Piece { draw(graphics, observer, coordinate.x, coordinate.y); } - void getPossibleMovesInDirection(int dx, int dy, BoardCoordinate position, Board board, ArrayList possibleMoves) { + void getPossibleMovesInDirection(int dx, int dy, BoardCoordinate position, Board board, ArrayList possibleMoves) { for ( int x = position.x + dx, y = position.y + dy; !board.outOfBounds(x, y); x += dx, y += dy) { BoardCoordinate coordinate = new BoardCoordinate(x, y); - possibleMoves.add(new Move(position, coordinate)); + possibleMoves.add(coordinate); if (board.get(coordinate) != null) break; } } diff --git a/src/Queen.java b/src/Queen.java index 7451c86..833f34f 100644 --- a/src/Queen.java +++ b/src/Queen.java @@ -9,8 +9,8 @@ public class Queen extends Piece { return 9; } - public ArrayList getPossibleMoves(BoardCoordinate position, Board board) { - ArrayList possibleMoves = new ArrayList<>(); + public ArrayList getPossibleMoves(BoardCoordinate position, Board board) { + ArrayList possibleMoves = new ArrayList<>(); getPossibleMovesInDirection(0, 1, position, board, possibleMoves); getPossibleMovesInDirection(0, -1, position, board, possibleMoves); diff --git a/src/Rook.java b/src/Rook.java index 80ea001..e9aba63 100644 --- a/src/Rook.java +++ b/src/Rook.java @@ -9,14 +9,15 @@ public class Rook extends Piece { return 5; } - public ArrayList getPossibleMoves(BoardCoordinate position, Board board) { - ArrayList possibleMoves = new ArrayList<>(); + public ArrayList getPossibleMoves(BoardCoordinate position, Board board) { + ArrayList possibleMoves = new ArrayList<>(); getPossibleMovesInDirection(0, 1, position, board, possibleMoves); getPossibleMovesInDirection(0, -1, position, board, possibleMoves); getPossibleMovesInDirection(1, 0, position, board, possibleMoves); getPossibleMovesInDirection(-1, 0, position, board, possibleMoves); + return possibleMoves; } } \ No newline at end of file diff --git a/you-lose.png b/you-lose.png deleted file mode 100644 index 588a0de..0000000 Binary files a/you-lose.png and /dev/null differ diff --git a/you-lose.svg b/you-lose.svg deleted file mode 100644 index e6eee75..0000000 --- a/you-lose.svg +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - YOU LOSE - click to play again - - diff --git a/you-win.png b/you-win.png deleted file mode 100644 index b813cd7..0000000 Binary files a/you-win.png and /dev/null differ diff --git a/you-win.svg b/you-win.svg deleted file mode 100644 index 51a18d0..0000000 --- a/you-win.svg +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - YOU WIN! - click to play again - -