En passant bugfix & improved javadoc

This commit is contained in:
Filip Znachor 2023-05-07 20:42:18 +02:00
parent 91608f1f7b
commit c02c98f11f
4 changed files with 102 additions and 58 deletions

View file

@ -243,14 +243,6 @@ public abstract class APiece {
return y;
}
/**
* Get piece's color
* @return piece's color
*/
public PieceColor getColor() {
return color;
}
/**
* Get piece's player
* @return piece's player
@ -292,20 +284,22 @@ public abstract class APiece {
/**
* Tests whether the player will be in check if the piece moves to a new position
* @param piece selected piece
* @param x new X position
* @param y new Y position
* @param piece piece on the new position
* @param newX new X position
* @param newY new Y position
* @return true, if player will be in check
*/
public boolean tryMove(APiece piece, int x, int y) {
chessboard.removePiece(this.x, this.y);
chessboard.addPiece(this, x, y);
int xBefore = this.x, yBefore = this.y;
this.x = x; this.y = y;
public boolean tryMove(APiece piece, int newX, int newY) {
chessboard.removePiece(x, y);
chessboard.addPiece(this, newX, newY);
PiecePosition old = new PiecePosition(x, y);
x = newX;
y = newY;
boolean inCheck = player.inCheck();
this.x = xBefore; this.y = yBefore;
chessboard.addPiece(piece, x, y);
chessboard.addPiece(this, this.x, this.y);
x = old.x;
y = old.y;
chessboard.addPiece(piece, newX, newY);
chessboard.addPiece(this, old);
return inCheck;
}

View file

@ -24,12 +24,24 @@ import java.util.List;
*/
public class Chess {
/**
* Window frame
*/
static JFrame window;
/**
* Chessboard instance
*/
static Chessboard chessboard;
/**
* Menu bar instance
*/
static JMenuBar menuBar;
/**
* Default chessboard FEN
*/
static final String DEFAULT_FEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
/**

View file

@ -1,6 +1,7 @@
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.*;
import java.util.Timer;
@ -243,10 +244,10 @@ public class Chessboard extends JPanel {
}
/**
* Add passed piece to the specified coordinates
* Add passed piece to the specified position
* @param piece piece
* @param x piece's X location
* @param y piese's Y location
* @param x piece's X position
* @param y piece's Y position
*/
public void addPiece(APiece piece, int x, int y) {
if(!isOnBoard(x, y)) return;
@ -257,9 +258,18 @@ public class Chessboard extends JPanel {
}
/**
* Remove piece at specified coordinates
* @param x piece's X location
* @param y piece's Y location
* Add passed piece to the specified position
* @param piece piece
* @param pos piece's position
*/
public void addPiece(APiece piece, PiecePosition pos) {
addPiece(piece, pos.x, pos.y);
}
/**
* Remove piece at specified position
* @param x piece's X position
* @param y piece's Y position
* @return removed piece
*/
public APiece removePiece(int x, int y) {
@ -270,6 +280,35 @@ public class Chessboard extends JPanel {
return piece;
}
/**
* Remove piece at specified position
* @param pos piece's position
* @return removed piece
*/
public APiece removePiece(PiecePosition pos) {
return removePiece(pos.x, pos.y);
}
/**
* Get piece at specified position
* @param x piece's X position
* @param y piece's Y position
* @return piece
*/
public APiece getPiece(int x, int y) {
if(!isOnBoard(x, y)) return null;
return pieces[y][x];
}
/**
* Get piece at specified position
* @param pos piece's position
* @return piece
*/
public APiece getPiece(PiecePosition pos) {
return getPiece(pos.x, pos.y);
}
/**
* Paint the chessboard
* @param g Graphics context
@ -301,18 +340,24 @@ public class Chessboard extends JPanel {
AffineTransform beforeSquares = g2.getTransform();
boolean isBlack = true;
boolean isDark = false;
g2.setStroke(new BasicStroke(16));
g.setColor(theme.lightSquare);
g.fillRect(0, 0, SQUARE_SIZE*SQUARE_COUNT, SQUARE_SIZE*SQUARE_COUNT);
for(int i=0; i<SQUARE_COUNT; i++) {
if(SQUARE_COUNT % 2 == 0) isBlack = !isBlack;
if(SQUARE_COUNT % 2 == 0) isDark = !isDark;
for(int j=0; j<SQUARE_COUNT; j++) {
isDark = !isDark;
g2.setTransform(beforeSquares);
g2.translate(i*SQUARE_SIZE, j*SQUARE_SIZE);
paintSquare(g2, isBlack);
if(isDark) {
g.setColor(theme.darkSquare);
g.fillRect(0, 0, SQUARE_SIZE, SQUARE_SIZE);
}
paintHighlights(g2, i, j);
isBlack = !isBlack;
}
}
@ -349,17 +394,6 @@ public class Chessboard extends JPanel {
}
/**
* Paint dark or light square
* @param g Graphics context
* @param isBlack whether square is dark or not
*/
private void paintSquare(Graphics g, boolean isBlack) {
if(isBlack) g.setColor(theme.darkSquare);
else g.setColor(theme.lightSquare);
g.fillRect(0, 0, SQUARE_SIZE+1, SQUARE_SIZE+1);
}
/**
* Paint last move and possible moves
* @param g Graphics context
@ -423,7 +457,7 @@ public class Chessboard extends JPanel {
}
/**
* Setup Graphics2D with anti-aliasing
* Setup Graphics2D with antialiasing
* @param g Graphics instance
* @return Graphics2D instance
*/
@ -453,17 +487,6 @@ public class Chessboard extends JPanel {
);
}
/**
* Get piece on specified piece position
* @param x piece's X location
* @param y piece's Y location
* @return piece
*/
public APiece getPiece(int x, int y) {
if(!isOnBoard(x, y)) return null;
return pieces[y][x];
}
/**
* Set piece as selected
* @return piece

View file

@ -49,7 +49,7 @@ public class Pawn extends APiece {
if(moveCount == 0 && firstPlaceEmpty && secondPlaceEmpty && !attack) setPossibleMove(moves, x, y + directionY*2);
for (int directionX : new int[]{-1, 1}) {
if(checkEnPassant(directionX)) setPossibleMove(moves, x+directionX, y+directionY);
if(checkEnPassant(directionX, directionY)) setPossibleMove(moves, x+directionX, y+directionY);
}
return moves;
@ -59,13 +59,27 @@ public class Pawn extends APiece {
/**
* Check if en passant possible
* @param directionX en passant X direction
* @param directionY Pawn's Y direction
* @return true, if possible
*/
private boolean checkEnPassant(int directionX) {
APiece piece = chessboard.getPiece(x+directionX, y);
if(piece == null) return false;
private boolean checkEnPassant(int directionX, int directionY) {
PiecePosition removedPiece = new PiecePosition(x+directionX, y);
PiecePosition movedPiece = new PiecePosition(x+directionX, y+directionY);
APiece piece = chessboard.getPiece(removedPiece);
if(!(piece instanceof Pawn)) return false;
int pieceY = piece.getPlayer().getStartPosition() == StartPosition.TOP ? 3 : 4;
return chessboard.lastMove[y][x+directionX] && piece instanceof Pawn && y == pieceY && piece.getMoveCount() == 1;
if(!chessboard.lastMove[y][x+directionX] || y != pieceY || piece.getMoveCount() != 1) return false;
chessboard.addPiece(this, movedPiece);
chessboard.removePiece(x, y);
chessboard.removePiece(removedPiece);
boolean inCheck = player.inCheck();
chessboard.removePiece(movedPiece);
chessboard.addPiece(this, x, y);
chessboard.addPiece(piece, removedPiece);
if(inCheck) return false;
return true;
}
/**
@ -77,8 +91,9 @@ public class Pawn extends APiece {
@Override
public void move(int newX, int newY, boolean animate) {
int directionY = player.getStartPosition() == StartPosition.TOP ? 1 : -1;
for (int directionX : new int[]{-1, 1}) {
if(checkEnPassant(directionX) && newX == x+directionX) {
if(checkEnPassant(directionX, directionY) && newX == x+directionX) {
APiece piece = chessboard.getPiece(x+directionX, y);
if(piece != null) piece.remove(true);
}