Compare commits
4 commits
f16448bdf0
...
c9cf5fa8fb
Author | SHA1 | Date | |
---|---|---|---|
c9cf5fa8fb | |||
dcde9d5ecd | |||
36f3873816 | |||
884fc44ed4 |
14 changed files with 378 additions and 87 deletions
|
@ -9,8 +9,8 @@ public class Bishop extends Piece {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<BoardCoordinate> getPossibleMoves(BoardCoordinate position, Board board) {
|
public ArrayList<Move> getPossibleMoves(BoardCoordinate position, Board board) {
|
||||||
ArrayList<BoardCoordinate> possibleMoves = new ArrayList<>();
|
ArrayList<Move> possibleMoves = new ArrayList<>();
|
||||||
|
|
||||||
getPossibleMovesInDirection(1, 1, position, board, possibleMoves);
|
getPossibleMovesInDirection(1, 1, position, board, possibleMoves);
|
||||||
getPossibleMovesInDirection(-1, -1, position, board, possibleMoves);
|
getPossibleMovesInDirection(-1, -1, position, board, possibleMoves);
|
||||||
|
|
115
src/Board.java
115
src/Board.java
|
@ -27,15 +27,20 @@ public class Board {
|
||||||
Piece[][] board;
|
Piece[][] board;
|
||||||
// The current board coordinate that's being dragged
|
// The current board coordinate that's being dragged
|
||||||
BoardCoordinate dragging = null;
|
BoardCoordinate dragging = null;
|
||||||
ArrayList<BoardCoordinate> legalMoves = null;
|
ArrayList<Move> legalMoves = null;
|
||||||
Stack<Move> moveHistory;
|
Stack<Move> moveHistory;
|
||||||
public boolean isGameOver;
|
public boolean isGameOver;
|
||||||
|
public boolean victor;
|
||||||
|
Image youWin;
|
||||||
|
Image youLose;
|
||||||
|
|
||||||
public Board() {
|
public Board() {
|
||||||
moveHistory = new Stack<>();
|
moveHistory = new Stack<>();
|
||||||
|
|
||||||
// Initialize DrawingPanel
|
// Initialize DrawingPanel
|
||||||
panel = new DrawingPanel(DIMENSION, DIMENSION);
|
panel = new DrawingPanel(DIMENSION, DIMENSION);
|
||||||
|
youWin = panel.loadImage("you-win.png");
|
||||||
|
youLose = panel.loadImage("you-lose.png");
|
||||||
graphics = panel.getGraphics();
|
graphics = panel.getGraphics();
|
||||||
|
|
||||||
// Connect up event handlers
|
// Connect up event handlers
|
||||||
|
@ -46,6 +51,11 @@ public class Board {
|
||||||
});
|
});
|
||||||
panel.onMouseUp(this::handleMouseUp);
|
panel.onMouseUp(this::handleMouseUp);
|
||||||
|
|
||||||
|
// Initialize board
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setup() {
|
||||||
// Initialize board
|
// Initialize board
|
||||||
board = new Piece[BOARD_SIZE][BOARD_SIZE];
|
board = new Piece[BOARD_SIZE][BOARD_SIZE];
|
||||||
|
|
||||||
|
@ -124,13 +134,24 @@ public class Board {
|
||||||
public void undoMove() {
|
public void undoMove() {
|
||||||
if (moveHistory.isEmpty()) return;
|
if (moveHistory.isEmpty()) return;
|
||||||
Move lastMove = moveHistory.pop();
|
Move lastMove = moveHistory.pop();
|
||||||
set(lastMove.from, get(lastMove.to));
|
undoMove(lastMove);
|
||||||
set(lastMove.to, lastMove.captured);
|
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
|
// Mouse down event handler
|
||||||
// This sets the currently dragging piece
|
// This sets the currently dragging piece
|
||||||
void handleMouseDown(int x, int y) {
|
void handleMouseDown(int x, int y) {
|
||||||
|
if (isGameOver) {
|
||||||
|
isGameOver = false;
|
||||||
|
setup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Get board coordinate of mouse click
|
// Get board coordinate of mouse click
|
||||||
BoardCoordinate coordinate = new ScreenCoordinate(x, y).toBoard();
|
BoardCoordinate coordinate = new ScreenCoordinate(x, y).toBoard();
|
||||||
// If there's no piece there, return
|
// If there's no piece there, return
|
||||||
|
@ -143,6 +164,10 @@ public class Board {
|
||||||
draw(x, y);
|
draw(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setLastMovedPieceAsMoved() {
|
||||||
|
get(moveHistory.peek().to).moved = true;
|
||||||
|
}
|
||||||
|
|
||||||
void handleMouseUp(int x, int y) {
|
void handleMouseUp(int x, int y) {
|
||||||
// Get board coordinate of mouse release
|
// Get board coordinate of mouse release
|
||||||
BoardCoordinate newCoordinate = new ScreenCoordinate(x, y).toBoard();
|
BoardCoordinate newCoordinate = new ScreenCoordinate(x, y).toBoard();
|
||||||
|
@ -150,27 +175,17 @@ public class Board {
|
||||||
if (dragging != null && !newCoordinate.equals(dragging)) {
|
if (dragging != null && !newCoordinate.equals(dragging)) {
|
||||||
// dragging is BoardCoordinate of piece being dragged
|
// dragging is BoardCoordinate of piece being dragged
|
||||||
Piece piece = get(dragging);
|
Piece piece = get(dragging);
|
||||||
ArrayList<BoardCoordinate> legalMoves = piece.getLegalMoves(dragging, this);
|
ArrayList<Move> legalMoves = piece.getLegalMoves(dragging, this);
|
||||||
for (BoardCoordinate legalMove : legalMoves) {
|
for (Move legalMove : legalMoves) {
|
||||||
if (newCoordinate.equals(legalMove)) {
|
if (newCoordinate.equals(legalMove.to)) {
|
||||||
move(dragging, newCoordinate);
|
move(dragging, newCoordinate);
|
||||||
// QUICK TESTING CODE
|
setLastMovedPieceAsMoved();
|
||||||
Piece movedPiece = get(newCoordinate);
|
checkForCheckmate();
|
||||||
King oppositeKing = movedPiece.black ? whiteKing : blackKing;
|
if (!isGameOver) {
|
||||||
BoardCoordinate oppositeKingPosition = null;
|
move(ChessAI.findBestMove(this));
|
||||||
boolean inCheck = false;
|
setLastMovedPieceAsMoved();
|
||||||
for (BoardCoordinate move : movedPiece.getLegalMoves(newCoordinate, this)) {
|
checkForCheckmate();
|
||||||
if (get(move) == oppositeKing) {
|
|
||||||
oppositeKingPosition = move;
|
|
||||||
inCheck = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (inCheck && oppositeKing.getLegalMoves(oppositeKingPosition, this).size() == 0)
|
|
||||||
isGameOver = true;
|
|
||||||
|
|
||||||
|
|
||||||
move(ChessAI.findBestMove(this));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,6 +196,34 @@ public class Board {
|
||||||
draw();
|
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() {
|
public void draw() {
|
||||||
draw(null);
|
draw(null);
|
||||||
}
|
}
|
||||||
|
@ -207,13 +250,16 @@ public class Board {
|
||||||
drawRect(x, y);
|
drawRect(x, y);
|
||||||
if (dragging != null) {
|
if (dragging != null) {
|
||||||
graphics.setColor(new Color(0, 128, 0, 128));
|
graphics.setColor(new Color(0, 128, 0, 128));
|
||||||
for (BoardCoordinate legalMove : legalMoves)
|
for (Move legalMove : legalMoves)
|
||||||
drawRect(legalMove);
|
drawRect(legalMove.to);
|
||||||
if (mousePosition != null) {
|
if (mousePosition != null) {
|
||||||
BoardCoordinate hovering = mousePosition.toBoard();
|
BoardCoordinate hovering = mousePosition.toBoard();
|
||||||
if (legalMoves.contains(hovering)) {
|
for (Move legalMove : legalMoves) {
|
||||||
graphics.setColor(get(hovering) == null ? new Color(0, 0, 255, 128) : new Color(255, 0, 0, 128));
|
if (legalMove.to.equals(hovering)) {
|
||||||
drawRect(mousePosition.toBoard());
|
graphics.setColor(get(hovering) == null ? new Color(0, 0, 255, 128) : new Color(255, 0, 0, 128));
|
||||||
|
drawRect(mousePosition.toBoard());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,6 +270,11 @@ public class Board {
|
||||||
// Otherwise, render it at the center of the board tile
|
// Otherwise, render it at the center of the board tile
|
||||||
piece.draw(graphics, panel, boardCoordinate.equals(dragging) ? mousePosition : boardCoordinate.toScreen());
|
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
|
// Functional interfaces for forEachPiece
|
||||||
|
@ -262,14 +313,12 @@ public class Board {
|
||||||
forEachPiece((x, y, piece) -> tileAction.forEachTile(new BoardCoordinate(x, y), get(x, y)));
|
forEachPiece((x, y, piece) -> tileAction.forEachTile(new BoardCoordinate(x, y), get(x, y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Move> getAllLegalMoves() {
|
public ArrayList<Move> getAllLegalMoves(boolean black) {
|
||||||
ArrayList<Move> allLegalMoves = new ArrayList<>();
|
ArrayList<Move> allLegalMoves = new ArrayList<>();
|
||||||
forEachPiece((from, piece) -> {
|
forEachPiece((from, piece) -> {
|
||||||
if (!piece.black) return;
|
if (piece.black != black) return;
|
||||||
ArrayList<BoardCoordinate> legalTiles = piece.getLegalMoves(from, this);
|
ArrayList<Move> legalTiles = piece.getLegalMoves(from, this);
|
||||||
for (BoardCoordinate to : legalTiles) {
|
allLegalMoves.addAll(legalTiles);
|
||||||
allLegalMoves.add(new Move(from, to));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return allLegalMoves;
|
return allLegalMoves;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ public class ChessAI {
|
||||||
int bestScore = Integer.MIN_VALUE;
|
int bestScore = Integer.MIN_VALUE;
|
||||||
Move bestMove = null;
|
Move bestMove = null;
|
||||||
|
|
||||||
for (Move move : board.getAllLegalMoves()) {
|
for (Move move : board.getAllLegalMoves(true)) {
|
||||||
board.move(move);
|
board.move(move);
|
||||||
int score = minimax(board, MAX_DEPTH, Integer.MIN_VALUE, Integer.MAX_VALUE, false);
|
int score = minimax(board, MAX_DEPTH, Integer.MIN_VALUE, Integer.MAX_VALUE, false);
|
||||||
board.undoMove();
|
board.undoMove();
|
||||||
|
@ -27,7 +27,7 @@ public class ChessAI {
|
||||||
int score;
|
int score;
|
||||||
if (maximizingPlayer) {
|
if (maximizingPlayer) {
|
||||||
score = Integer.MIN_VALUE;
|
score = Integer.MIN_VALUE;
|
||||||
for (Move move : board.getAllLegalMoves()) {
|
for (Move move : board.getAllLegalMoves(true)) {
|
||||||
board.move(move);
|
board.move(move);
|
||||||
score = Math.max(score, minimax(board, depth - 1, alpha, beta, false));
|
score = Math.max(score, minimax(board, depth - 1, alpha, beta, false));
|
||||||
board.undoMove();
|
board.undoMove();
|
||||||
|
@ -38,7 +38,7 @@ public class ChessAI {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
score = Integer.MAX_VALUE;
|
score = Integer.MAX_VALUE;
|
||||||
for (Move move : board.getAllLegalMoves()) {
|
for (Move move : board.getAllLegalMoves(true)) {
|
||||||
board.move(move);
|
board.move(move);
|
||||||
score = Math.min(score, minimax(board, depth - 1, alpha, beta, true));
|
score = Math.min(score, minimax(board, depth - 1, alpha, beta, true));
|
||||||
board.undoMove();
|
board.undoMove();
|
||||||
|
|
|
@ -9,16 +9,19 @@ public class King extends Piece {
|
||||||
return 12;
|
return 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<BoardCoordinate> getPossibleMoves(BoardCoordinate position, Board board) {
|
public ArrayList<Move> getPossibleMoves(BoardCoordinate position, Board board) {
|
||||||
ArrayList<BoardCoordinate> possibleMoves = new ArrayList<>();
|
ArrayList<Move> 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 Move(position, new BoardCoordinate(position.x - 1, position.y - 1)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x - 1, position.y));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 1, position.y + 1)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x + 1, position.y - 1));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 1, position.y)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x + 1, position.y + 1));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 1, position.y - 1)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x + 1, position.y));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 1, position.y + 1)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x, position.y + 1));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 1, position.y)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x, position.y - 1));
|
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;
|
return possibleMoves;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,17 +10,16 @@ public class Knight extends Piece {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<BoardCoordinate> getPossibleMoves(BoardCoordinate position, Board board) {
|
public ArrayList<Move> getPossibleMoves(BoardCoordinate position, Board board) {
|
||||||
ArrayList<BoardCoordinate> possibleMoves = new ArrayList<>();
|
ArrayList<Move> possibleMoves = new ArrayList<>();
|
||||||
possibleMoves.add(new BoardCoordinate(position.x - 2, position.y - 1));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 2, position.y - 1)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x - 1, position.y - 2));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 1, position.y - 2)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x + 1, position.y - 2));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 1, position.y - 2)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x + 2, position.y - 1));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 2, position.y - 1)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x + 2, position.y + 1));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 2, position.y + 1)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x + 1, position.y + 2));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x + 1, position.y + 2)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x - 1, position.y + 2));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 1, position.y + 2)));
|
||||||
possibleMoves.add(new BoardCoordinate(position.x - 2, position.y + 1));
|
possibleMoves.add(new Move(position, new BoardCoordinate(position.x - 2, position.y + 1)));
|
||||||
// test
|
|
||||||
return possibleMoves;
|
return possibleMoves;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class Move {
|
public class Move {
|
||||||
public BoardCoordinate from;
|
public BoardCoordinate from;
|
||||||
public BoardCoordinate to;
|
public BoardCoordinate to;
|
||||||
public Piece captured;
|
public Piece captured;
|
||||||
|
// e.g. castling, castle move. Done after.
|
||||||
|
public Move submove;
|
||||||
|
|
||||||
public Move(BoardCoordinate from, BoardCoordinate to) {
|
public Move(BoardCoordinate from, BoardCoordinate to) {
|
||||||
this.from = from;
|
this.from = from;
|
||||||
|
@ -13,4 +17,4 @@ public class Move {
|
||||||
this.to = to;
|
this.to = to;
|
||||||
this.captured = captured;
|
this.captured = captured;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,12 +9,14 @@ public class Pawn extends Piece {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<BoardCoordinate> getPossibleMoves(BoardCoordinate position, Board board) {
|
public ArrayList<Move> getPossibleMoves(BoardCoordinate position, Board board) {
|
||||||
ArrayList<BoardCoordinate> possibleMoves = new ArrayList<>();
|
ArrayList<Move> possibleMoves = new ArrayList<>();
|
||||||
if (this.black) {
|
if (this.black) {
|
||||||
possibleMoves.add(new BoardCoordinate(position.x, position.y + 1));
|
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 {
|
} else {
|
||||||
possibleMoves.add(new BoardCoordinate(position.x, position.y - 1));
|
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;
|
return possibleMoves;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ public abstract class Piece {
|
||||||
static final int DIMENSION = 48;
|
static final int DIMENSION = 48;
|
||||||
Image image;
|
Image image;
|
||||||
public boolean black;
|
public boolean black;
|
||||||
|
public boolean moved = false;
|
||||||
|
|
||||||
public abstract int getValue();
|
public abstract int getValue();
|
||||||
|
|
||||||
|
@ -16,29 +17,29 @@ public abstract class Piece {
|
||||||
image = panel.loadImage(black ? blackImagePath : whiteImagePath);
|
image = panel.loadImage(black ? blackImagePath : whiteImagePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract ArrayList<BoardCoordinate> getPossibleMoves(BoardCoordinate position, Board board);
|
public abstract ArrayList<Move> getPossibleMoves(BoardCoordinate position, Board board);
|
||||||
|
|
||||||
public ArrayList<BoardCoordinate> getLegalMoves(BoardCoordinate position, Board board) {
|
public ArrayList<Move> getLegalMoves(BoardCoordinate position, Board board) {
|
||||||
return getLegalMoves(position, board, true);
|
return getLegalMoves(position, board, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<BoardCoordinate> getLegalMoves(BoardCoordinate position, Board board, boolean doCheckChecks) {
|
public ArrayList<Move> getLegalMoves(BoardCoordinate position, Board board, boolean doCheckChecks) {
|
||||||
ArrayList<BoardCoordinate> legalMoves = getPossibleMoves(position, board);
|
ArrayList<Move> legalMoves = getPossibleMoves(position, board);
|
||||||
for (int i = 0; i < legalMoves.size(); i++) {
|
for (int i = 0; i < legalMoves.size(); i++) {
|
||||||
BoardCoordinate possibleMove = legalMoves.get(i);
|
Move possibleMove = legalMoves.get(i);
|
||||||
Piece targetPiece = board.get(possibleMove);
|
Piece targetPiece = board.get(possibleMove.to);
|
||||||
if (
|
if (
|
||||||
// other piece of same color
|
// other piece of same color
|
||||||
(targetPiece != null && targetPiece.black == black) ||
|
(targetPiece != null && targetPiece.black == black) ||
|
||||||
|
|
||||||
// outside of bounds of board
|
// outside of bounds of board
|
||||||
possibleMove.x < 0 ||
|
possibleMove.to.x < 0 ||
|
||||||
possibleMove.y < 0 ||
|
possibleMove.to.y < 0 ||
|
||||||
possibleMove.x >= Board.BOARD_SIZE ||
|
possibleMove.to.x >= Board.BOARD_SIZE ||
|
||||||
possibleMove.y >= Board.BOARD_SIZE ||
|
possibleMove.to.y >= Board.BOARD_SIZE ||
|
||||||
|
|
||||||
// is in check
|
// is in check
|
||||||
(doCheckChecks && isInCheck(position, possibleMove, board))
|
(doCheckChecks && isInCheck(new Move(position, possibleMove.to), board))
|
||||||
) {
|
) {
|
||||||
legalMoves.remove(i);
|
legalMoves.remove(i);
|
||||||
i--;
|
i--;
|
||||||
|
@ -48,16 +49,16 @@ public abstract class Piece {
|
||||||
return legalMoves;
|
return legalMoves;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isInCheck(BoardCoordinate from, BoardCoordinate to, Board board) {
|
boolean isInCheck(Move move, Board board) {
|
||||||
boolean isInCheck = false;
|
boolean isInCheck = false;
|
||||||
board.move(from, to);
|
board.move(move);
|
||||||
outer: for (int y = 0; y < Board.BOARD_SIZE; y++) {
|
outer: for (int y = 0; y < Board.BOARD_SIZE; y++) {
|
||||||
for (int x = 0; x < Board.BOARD_SIZE; x++) {
|
for (int x = 0; x < Board.BOARD_SIZE; x++) {
|
||||||
Piece piece = board.get(x, y);
|
Piece piece = board.get(x, y);
|
||||||
if (piece == null || piece.black == black) continue;
|
if (piece == null || piece.black == black) continue;
|
||||||
ArrayList<BoardCoordinate> legalMoves = piece.getLegalMoves(new BoardCoordinate(x, y), board, false);
|
ArrayList<Move> legalMoves = piece.getLegalMoves(new BoardCoordinate(x, y), board, false);
|
||||||
for (BoardCoordinate move : legalMoves) {
|
for (Move legalMove : legalMoves) {
|
||||||
Piece pieceAtMove = board.get(move);
|
Piece pieceAtMove = board.get(legalMove.to);
|
||||||
if (pieceAtMove instanceof King) {
|
if (pieceAtMove instanceof King) {
|
||||||
isInCheck = true;
|
isInCheck = true;
|
||||||
break outer;
|
break outer;
|
||||||
|
@ -79,13 +80,13 @@ public abstract class Piece {
|
||||||
draw(graphics, observer, coordinate.x, coordinate.y);
|
draw(graphics, observer, coordinate.x, coordinate.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getPossibleMovesInDirection(int dx, int dy, BoardCoordinate position, Board board, ArrayList<BoardCoordinate> possibleMoves) {
|
void getPossibleMovesInDirection(int dx, int dy, BoardCoordinate position, Board board, ArrayList<Move> possibleMoves) {
|
||||||
for (
|
for (
|
||||||
int x = position.x + dx, y = position.y + dy;
|
int x = position.x + dx, y = position.y + dy;
|
||||||
!board.outOfBounds(x, y);
|
!board.outOfBounds(x, y);
|
||||||
x += dx, y += dy) {
|
x += dx, y += dy) {
|
||||||
BoardCoordinate coordinate = new BoardCoordinate(x, y);
|
BoardCoordinate coordinate = new BoardCoordinate(x, y);
|
||||||
possibleMoves.add(coordinate);
|
possibleMoves.add(new Move(position, coordinate));
|
||||||
if (board.get(coordinate) != null) break;
|
if (board.get(coordinate) != null) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ public class Queen extends Piece {
|
||||||
return 9;
|
return 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<BoardCoordinate> getPossibleMoves(BoardCoordinate position, Board board) {
|
public ArrayList<Move> getPossibleMoves(BoardCoordinate position, Board board) {
|
||||||
ArrayList<BoardCoordinate> possibleMoves = new ArrayList<>();
|
ArrayList<Move> possibleMoves = new ArrayList<>();
|
||||||
|
|
||||||
getPossibleMovesInDirection(0, 1, position, board, possibleMoves);
|
getPossibleMovesInDirection(0, 1, position, board, possibleMoves);
|
||||||
getPossibleMovesInDirection(0, -1, position, board, possibleMoves);
|
getPossibleMovesInDirection(0, -1, position, board, possibleMoves);
|
||||||
|
|
|
@ -9,15 +9,14 @@ public class Rook extends Piece {
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<BoardCoordinate> getPossibleMoves(BoardCoordinate position, Board board) {
|
public ArrayList<Move> getPossibleMoves(BoardCoordinate position, Board board) {
|
||||||
ArrayList<BoardCoordinate> possibleMoves = new ArrayList<>();
|
ArrayList<Move> possibleMoves = new ArrayList<>();
|
||||||
|
|
||||||
getPossibleMovesInDirection(0, 1, position, board, possibleMoves);
|
getPossibleMovesInDirection(0, 1, position, board, possibleMoves);
|
||||||
getPossibleMovesInDirection(0, -1, position, board, possibleMoves);
|
getPossibleMovesInDirection(0, -1, position, board, possibleMoves);
|
||||||
getPossibleMovesInDirection(1, 0, position, board, possibleMoves);
|
getPossibleMovesInDirection(1, 0, position, board, possibleMoves);
|
||||||
getPossibleMovesInDirection(-1, 0, position, board, possibleMoves);
|
getPossibleMovesInDirection(-1, 0, position, board, possibleMoves);
|
||||||
|
|
||||||
|
|
||||||
return possibleMoves;
|
return possibleMoves;
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
you-lose.png
Normal file
BIN
you-lose.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
117
you-lose.svg
Normal file
117
you-lose.svg
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="512mm"
|
||||||
|
height="512mm"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
sodipodi:docname="you-lose.svg"
|
||||||
|
inkscape:export-filename="you-win.png"
|
||||||
|
inkscape:export-xdpi="25.4"
|
||||||
|
inkscape:export-ydpi="25.4"
|
||||||
|
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.3901936"
|
||||||
|
inkscape:cx="1232.7214"
|
||||||
|
inkscape:cy="1014.8808"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1048"
|
||||||
|
inkscape:window-x="1920"
|
||||||
|
inkscape:window-y="32"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<rect
|
||||||
|
x="380.73235"
|
||||||
|
y="551.6332"
|
||||||
|
width="1925.2562"
|
||||||
|
height="945.95678"
|
||||||
|
id="rect952" />
|
||||||
|
<filter
|
||||||
|
style="color-interpolation-filters:sRGB;"
|
||||||
|
inkscape:label="Drop Shadow"
|
||||||
|
id="filter1272"
|
||||||
|
x="-0.020339003"
|
||||||
|
y="0"
|
||||||
|
width="1.020339"
|
||||||
|
height="1.1324139">
|
||||||
|
<feFlood
|
||||||
|
flood-opacity="0.498039"
|
||||||
|
flood-color="rgb(0,0,0)"
|
||||||
|
result="flood"
|
||||||
|
id="feFlood1262" />
|
||||||
|
<feComposite
|
||||||
|
in="flood"
|
||||||
|
in2="SourceGraphic"
|
||||||
|
operator="in"
|
||||||
|
result="composite1"
|
||||||
|
id="feComposite1264" />
|
||||||
|
<feGaussianBlur
|
||||||
|
in="composite1"
|
||||||
|
stdDeviation="0"
|
||||||
|
result="blur"
|
||||||
|
id="feGaussianBlur1266" />
|
||||||
|
<feOffset
|
||||||
|
dx="-32"
|
||||||
|
dy="32"
|
||||||
|
result="offset"
|
||||||
|
id="feOffset1268" />
|
||||||
|
<feComposite
|
||||||
|
in="SourceGraphic"
|
||||||
|
in2="offset"
|
||||||
|
operator="over"
|
||||||
|
result="composite2"
|
||||||
|
id="feComposite1270" />
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<rect
|
||||||
|
style="fill:#333333;stroke-width:0.264583;fill-opacity:0.5"
|
||||||
|
id="rect111"
|
||||||
|
width="512"
|
||||||
|
height="512"
|
||||||
|
x="0"
|
||||||
|
y="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,-72.389152,55.55428)"
|
||||||
|
id="text950"
|
||||||
|
style="font-size:341.333px;white-space:pre;shape-inside:url(#rect952);display:inline;fill:#3d3d3d;fill-opacity:1;filter:url(#filter1272)"><tspan
|
||||||
|
x="380.73242"
|
||||||
|
y="859.09003"
|
||||||
|
id="tspan1803"><tspan
|
||||||
|
style="font-weight:bold;font-family:Arimo;-inkscape-font-specification:'Arimo Bold';fill:#ffffff"
|
||||||
|
id="tspan1801">YOU LOSE</tspan></tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:33.8667px;font-family:Arimo;-inkscape-font-specification:'Arimo Bold';fill:#ffffff;fill-opacity:0.75;stroke-width:0.264583"
|
||||||
|
x="110.52037"
|
||||||
|
y="328.68213"
|
||||||
|
id="text1451"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan1449"
|
||||||
|
style="font-size:33.8667px;fill:#ffffff;fill-opacity:0.75;stroke-width:0.264583"
|
||||||
|
x="110.52037"
|
||||||
|
y="328.68213">click to play again</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
BIN
you-win.png
Normal file
BIN
you-win.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
117
you-win.svg
Normal file
117
you-win.svg
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="512mm"
|
||||||
|
height="512mm"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
sodipodi:docname="you-win.svg"
|
||||||
|
inkscape:export-filename="you-win.png"
|
||||||
|
inkscape:export-xdpi="25.4"
|
||||||
|
inkscape:export-ydpi="25.4"
|
||||||
|
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.3901936"
|
||||||
|
inkscape:cx="1232.7214"
|
||||||
|
inkscape:cy="1014.8808"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1048"
|
||||||
|
inkscape:window-x="1920"
|
||||||
|
inkscape:window-y="32"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<rect
|
||||||
|
x="380.73235"
|
||||||
|
y="551.6332"
|
||||||
|
width="1925.2562"
|
||||||
|
height="945.95678"
|
||||||
|
id="rect952" />
|
||||||
|
<filter
|
||||||
|
style="color-interpolation-filters:sRGB;"
|
||||||
|
inkscape:label="Drop Shadow"
|
||||||
|
id="filter1272"
|
||||||
|
x="-0.020339003"
|
||||||
|
y="0"
|
||||||
|
width="1.020339"
|
||||||
|
height="1.1324139">
|
||||||
|
<feFlood
|
||||||
|
flood-opacity="0.498039"
|
||||||
|
flood-color="rgb(0,0,0)"
|
||||||
|
result="flood"
|
||||||
|
id="feFlood1262" />
|
||||||
|
<feComposite
|
||||||
|
in="flood"
|
||||||
|
in2="SourceGraphic"
|
||||||
|
operator="in"
|
||||||
|
result="composite1"
|
||||||
|
id="feComposite1264" />
|
||||||
|
<feGaussianBlur
|
||||||
|
in="composite1"
|
||||||
|
stdDeviation="0"
|
||||||
|
result="blur"
|
||||||
|
id="feGaussianBlur1266" />
|
||||||
|
<feOffset
|
||||||
|
dx="-32"
|
||||||
|
dy="32"
|
||||||
|
result="offset"
|
||||||
|
id="feOffset1268" />
|
||||||
|
<feComposite
|
||||||
|
in="SourceGraphic"
|
||||||
|
in2="offset"
|
||||||
|
operator="over"
|
||||||
|
result="composite2"
|
||||||
|
id="feComposite1270" />
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<rect
|
||||||
|
style="fill:#333333;stroke-width:0.264583;fill-opacity:0.5"
|
||||||
|
id="rect111"
|
||||||
|
width="512"
|
||||||
|
height="512"
|
||||||
|
x="0"
|
||||||
|
y="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,-50.184205,55.55428)"
|
||||||
|
id="text950"
|
||||||
|
style="font-size:341.333px;white-space:pre;shape-inside:url(#rect952);display:inline;fill:#3d3d3d;fill-opacity:1;filter:url(#filter1272)"><tspan
|
||||||
|
x="380.73242"
|
||||||
|
y="859.09003"
|
||||||
|
id="tspan1767"><tspan
|
||||||
|
style="font-weight:bold;font-family:Arimo;-inkscape-font-specification:'Arimo Bold';fill:#ffffff"
|
||||||
|
id="tspan1765">YOU WIN!</tspan></tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:33.8667px;font-family:Arimo;-inkscape-font-specification:'Arimo Bold';fill:#ffffff;fill-opacity:0.75;stroke-width:0.264583"
|
||||||
|
x="110.52037"
|
||||||
|
y="328.68213"
|
||||||
|
id="text1451"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan1449"
|
||||||
|
style="font-size:33.8667px;fill:#ffffff;fill-opacity:0.75;stroke-width:0.264583"
|
||||||
|
x="110.52037"
|
||||||
|
y="328.68213">click to play again</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
Reference in a new issue