From 884fc44ed4f32e8a3684488f9d7f441aecf9d556 Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Wed, 15 Mar 2023 16:34:37 -0700 Subject: [PATCH 1/4] Add win/lose screen --- src/Board.java | 57 +++++++++++++++++------- you-lose.png | Bin 0 -> 28638 bytes you-lose.svg | 117 +++++++++++++++++++++++++++++++++++++++++++++++++ you-win.png | Bin 0 -> 26953 bytes you-win.svg | 117 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 275 insertions(+), 16 deletions(-) create mode 100644 you-lose.png create mode 100644 you-lose.svg create mode 100644 you-win.png create mode 100644 you-win.svg diff --git a/src/Board.java b/src/Board.java index d85a837..eaaa012 100644 --- a/src/Board.java +++ b/src/Board.java @@ -30,12 +30,17 @@ public class Board { 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 @@ -46,6 +51,11 @@ public class Board { }); panel.onMouseUp(this::handleMouseUp); + // Initialize board + setup(); + } + + public void setup() { // Initialize board board = new Piece[BOARD_SIZE][BOARD_SIZE]; @@ -131,6 +141,11 @@ public class Board { // 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 @@ -154,23 +169,11 @@ public class Board { for (BoardCoordinate legalMove : legalMoves) { if (newCoordinate.equals(legalMove)) { move(dragging, newCoordinate); - // 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; - } + checkForCheckmate(); + if (!isGameOver) { + move(ChessAI.findBestMove(this)); + checkForCheckmate(); } - if (inCheck && oppositeKing.getLegalMoves(oppositeKingPosition, this).size() == 0) - isGameOver = true; - - - move(ChessAI.findBestMove(this)); break; } } @@ -181,6 +184,23 @@ 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 (BoardCoordinate move : movedPiece.getLegalMoves(movedCoordinate, this)) { + if (get(move) == oppositeKing) { + oppositeKingPosition = move; + inCheck = true; + break; + } + } + isGameOver = inCheck && oppositeKing.getLegalMoves(oppositeKingPosition, this).size() == 0; + victor = movedPiece.black; + } + public void draw() { draw(null); } @@ -224,6 +244,11 @@ 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 diff --git a/you-lose.png b/you-lose.png new file mode 100644 index 0000000000000000000000000000000000000000..588a0de65fd5224e0b79b8275c6dca2e8f679884 GIT binary patch literal 28638 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 DdBXC~ literal 0 HcmV?d00001 diff --git a/you-lose.svg b/you-lose.svg new file mode 100644 index 0000000..e6eee75 --- /dev/null +++ b/you-lose.svg @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + YOU LOSE + click to play again + + diff --git a/you-win.png b/you-win.png new file mode 100644 index 0000000000000000000000000000000000000000..b813cd7faf2e97d592a12658d3dd09bb3cc10334 GIT binary patch literal 26953 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

TBKW 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 literal 0 HcmV?d00001 diff --git a/you-win.svg b/you-win.svg new file mode 100644 index 0000000..51a18d0 --- /dev/null +++ b/you-win.svg @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + YOU WIN! + click to play again + + From 36f3873816c7ede65008946910763bb9fd987908 Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Wed, 15 Mar 2023 17:00:04 -0700 Subject: [PATCH 2/4] Fix checkmate logic to account for other piece taking attacker --- src/Board.java | 17 ++++++++++++++--- src/ChessAI.java | 6 +++--- src/Piece.java | 10 +++++----- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/Board.java b/src/Board.java index eaaa012..74ff175 100644 --- a/src/Board.java +++ b/src/Board.java @@ -197,7 +197,18 @@ public class Board { break; } } - isGameOver = inCheck && oppositeKing.getLegalMoves(oppositeKingPosition, this).size() == 0; + 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; } @@ -287,10 +298,10 @@ public class Board { forEachPiece((x, y, piece) -> tileAction.forEachTile(new BoardCoordinate(x, y), get(x, y))); } - public ArrayList getAllLegalMoves() { + public ArrayList getAllLegalMoves(boolean black) { ArrayList allLegalMoves = new ArrayList<>(); forEachPiece((from, piece) -> { - if (!piece.black) return; + if (piece.black != black) return; ArrayList legalTiles = piece.getLegalMoves(from, this); for (BoardCoordinate to : legalTiles) { allLegalMoves.add(new Move(from, to)); diff --git a/src/ChessAI.java b/src/ChessAI.java index 24b642e..8fe8ce5 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()) { + for (Move move : board.getAllLegalMoves(true)) { 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()) { + for (Move move : board.getAllLegalMoves(true)) { 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()) { + for (Move move : board.getAllLegalMoves(true)) { board.move(move); score = Math.min(score, minimax(board, depth - 1, alpha, beta, true)); board.undoMove(); diff --git a/src/Piece.java b/src/Piece.java index a98ad2e..c0579f0 100644 --- a/src/Piece.java +++ b/src/Piece.java @@ -38,7 +38,7 @@ public abstract class Piece { possibleMove.y >= Board.BOARD_SIZE || // is in check - (doCheckChecks && isInCheck(position, possibleMove, board)) + (doCheckChecks && isInCheck(new Move(position, possibleMove), board)) ) { legalMoves.remove(i); i--; @@ -48,16 +48,16 @@ public abstract class Piece { return legalMoves; } - boolean isInCheck(BoardCoordinate from, BoardCoordinate to, Board board) { + boolean isInCheck(Move move, Board board) { boolean isInCheck = false; - board.move(from, to); + board.move(move); 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 (BoardCoordinate move : legalMoves) { - Piece pieceAtMove = board.get(move); + for (BoardCoordinate legalMove : legalMoves) { + Piece pieceAtMove = board.get(legalMove); if (pieceAtMove instanceof King) { isInCheck = true; break outer; From dcde9d5ecdbde2c3a1d917a2ace9334490c6995e Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Wed, 15 Mar 2023 17:00:15 -0700 Subject: [PATCH 3/4] Add two space pawn movement --- src/Pawn.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Pawn.java b/src/Pawn.java index 1d1ea90..8c30774 100644 --- a/src/Pawn.java +++ b/src/Pawn.java @@ -13,8 +13,10 @@ public class Pawn extends Piece { ArrayList possibleMoves = new ArrayList<>(); if (this.black) { possibleMoves.add(new BoardCoordinate(position.x, position.y + 1)); + if (position.y == 1) possibleMoves.add(new BoardCoordinate(position.x, position.y + 2)); } else { possibleMoves.add(new BoardCoordinate(position.x, position.y - 1)); + if (position.y == 6) possibleMoves.add(new BoardCoordinate(position.x, position.y - 2)); } return possibleMoves; } From c9cf5fa8fb19521f7488fea1151d7bd40f31599a Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Wed, 15 Mar 2023 18:43:33 -0700 Subject: [PATCH 4/4] Switch from BoardCoordinate to Move for most move handling --- src/Bishop.java | 4 ++-- src/Board.java | 49 +++++++++++++++++++++++++++++++------------------ src/King.java | 23 +++++++++++++---------- src/Knight.java | 21 ++++++++++----------- src/Move.java | 6 +++++- src/Pawn.java | 12 ++++++------ src/Piece.java | 33 +++++++++++++++++---------------- src/Queen.java | 4 ++-- src/Rook.java | 5 ++--- 9 files changed, 88 insertions(+), 69 deletions(-) diff --git a/src/Bishop.java b/src/Bishop.java index 85c5b06..74f9cd7 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 74ff175..51833ab 100644 --- a/src/Board.java +++ b/src/Board.java @@ -27,7 +27,7 @@ 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; @@ -134,8 +134,14 @@ public class Board { public void undoMove() { if (moveHistory.isEmpty()) return; Move lastMove = moveHistory.pop(); - set(lastMove.from, get(lastMove.to)); - set(lastMove.to, lastMove.captured); + undoMove(lastMove); + undoMove(lastMove.submove); + } + + void undoMove(Move move) { + if (move == null) return; + set(move.from, get(move.to)); + set(move.to, move.captured); } // Mouse down event handler @@ -158,6 +164,10 @@ 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(); @@ -165,13 +175,15 @@ 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 (BoardCoordinate legalMove : legalMoves) { - if (newCoordinate.equals(legalMove)) { + ArrayList legalMoves = piece.getLegalMoves(dragging, this); + for (Move legalMove : legalMoves) { + if (newCoordinate.equals(legalMove.to)) { move(dragging, newCoordinate); + setLastMovedPieceAsMoved(); checkForCheckmate(); if (!isGameOver) { move(ChessAI.findBestMove(this)); + setLastMovedPieceAsMoved(); checkForCheckmate(); } break; @@ -190,9 +202,9 @@ public class Board { King oppositeKing = movedPiece.black ? whiteKing : blackKing; BoardCoordinate oppositeKingPosition = null; boolean inCheck = false; - for (BoardCoordinate move : movedPiece.getLegalMoves(movedCoordinate, this)) { - if (get(move) == oppositeKing) { - oppositeKingPosition = move; + for (Move move : movedPiece.getLegalMoves(movedCoordinate, this)) { + if (get(move.to) == oppositeKing) { + oppositeKingPosition = move.to; inCheck = true; break; } @@ -238,13 +250,16 @@ public class Board { drawRect(x, y); if (dragging != null) { graphics.setColor(new Color(0, 128, 0, 128)); - for (BoardCoordinate legalMove : legalMoves) - drawRect(legalMove); + for (Move legalMove : legalMoves) + drawRect(legalMove.to); if (mousePosition != null) { BoardCoordinate hovering = mousePosition.toBoard(); - if (legalMoves.contains(hovering)) { - graphics.setColor(get(hovering) == null ? new Color(0, 0, 255, 128) : new Color(255, 0, 0, 128)); - drawRect(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; + } } } } @@ -302,10 +317,8 @@ public class Board { ArrayList allLegalMoves = new ArrayList<>(); forEachPiece((from, piece) -> { if (piece.black != black) return; - ArrayList legalTiles = piece.getLegalMoves(from, this); - for (BoardCoordinate to : legalTiles) { - allLegalMoves.add(new Move(from, to)); - } + ArrayList legalTiles = piece.getLegalMoves(from, this); + allLegalMoves.addAll(legalTiles); }); return allLegalMoves; } diff --git a/src/King.java b/src/King.java index cbf987a..95ed8f2 100644 --- a/src/King.java +++ b/src/King.java @@ -9,16 +9,19 @@ public class King extends Piece { return 12; } - 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)); + 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); + return possibleMoves; } } \ No newline at end of file diff --git a/src/Knight.java b/src/Knight.java index c9ed6e4..2af73ac 100644 --- a/src/Knight.java +++ b/src/Knight.java @@ -10,17 +10,16 @@ public class Knight extends Piece { return 3; } - 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 + 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))); return possibleMoves; } } diff --git a/src/Move.java b/src/Move.java index a8f9c59..13bbd1f 100644 --- a/src/Move.java +++ b/src/Move.java @@ -1,7 +1,11 @@ +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; @@ -13,4 +17,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 8c30774..ecbd95f 100644 --- a/src/Pawn.java +++ b/src/Pawn.java @@ -9,14 +9,14 @@ 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 BoardCoordinate(position.x, position.y + 1)); - if (position.y == 1) possibleMoves.add(new BoardCoordinate(position.x, position.y + 2)); + 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))); } else { - possibleMoves.add(new BoardCoordinate(position.x, position.y - 1)); - if (position.y == 6) possibleMoves.add(new BoardCoordinate(position.x, position.y - 2)); + 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))); } return possibleMoves; } diff --git a/src/Piece.java b/src/Piece.java index c0579f0..9309ce8 100644 --- a/src/Piece.java +++ b/src/Piece.java @@ -8,6 +8,7 @@ public abstract class Piece { static final int DIMENSION = 48; Image image; public boolean black; + public boolean moved = false; public abstract int getValue(); @@ -16,29 +17,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++) { - BoardCoordinate possibleMove = legalMoves.get(i); - Piece targetPiece = board.get(possibleMove); + Move possibleMove = legalMoves.get(i); + Piece targetPiece = board.get(possibleMove.to); if ( // other piece of same color (targetPiece != null && targetPiece.black == black) || // outside of bounds of board - possibleMove.x < 0 || - possibleMove.y < 0 || - possibleMove.x >= Board.BOARD_SIZE || - possibleMove.y >= Board.BOARD_SIZE || + possibleMove.to.x < 0 || + possibleMove.to.y < 0 || + possibleMove.to.x >= Board.BOARD_SIZE || + possibleMove.to.y >= Board.BOARD_SIZE || // is in check - (doCheckChecks && isInCheck(new Move(position, possibleMove), board)) + (doCheckChecks && isInCheck(new Move(position, possibleMove.to), board)) ) { legalMoves.remove(i); i--; @@ -55,9 +56,9 @@ public abstract class Piece { 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 (BoardCoordinate legalMove : legalMoves) { - Piece pieceAtMove = board.get(legalMove); + ArrayList legalMoves = piece.getLegalMoves(new BoardCoordinate(x, y), board, false); + for (Move legalMove : legalMoves) { + Piece pieceAtMove = board.get(legalMove.to); if (pieceAtMove instanceof King) { isInCheck = true; break outer; @@ -79,13 +80,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(coordinate); + possibleMoves.add(new Move(position, coordinate)); if (board.get(coordinate) != null) break; } } diff --git a/src/Queen.java b/src/Queen.java index 833f34f..7451c86 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 e9aba63..80ea001 100644 --- a/src/Rook.java +++ b/src/Rook.java @@ -9,15 +9,14 @@ 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