Added check support, removed attack area

This commit is contained in:
Filip Znachor 2023-04-29 20:49:07 +02:00
parent 450f4e04e8
commit 07c8d0b835
7 changed files with 96 additions and 78 deletions

View file

@ -163,7 +163,7 @@ public abstract class APiece {
if(animate) animateMove(x, y, pos.x, pos.y);
moveCount++;
chessboard.removePiece(x, y);
APiece piece = chessboard.getPiece(pos);
APiece piece = chessboard.getPiece(pos.x, pos.y);
if(piece != null) {
piece.remove();
}
@ -233,15 +233,33 @@ public abstract class APiece {
}
public void setPossibleMove(boolean[][] moves, int x, int y) {
if(x == this.x && y == this.y) return;
if(x < 0 || x >= moves.length || y < 0 || y >= moves.length) return;
APiece piece = chessboard.getPiece(new PiecePosition(x, y));
if(piece != null && piece != chessboard.getSelectedPiece() && player == piece.getPlayer()) return;
APiece piece = chessboard.getPiece(x, y);
if(piece != null && player == piece.getPlayer()) return;
if(tryMove(piece, x, y)) return;
moves[y][x] = true;
}
public boolean tryMove(APiece piece, int x, int y) {
chessboard.removePiece(this.x, this.y);
chessboard.addPiece(this, x, y);
int xBefore = this.x;
int yBefore = this.y;
this.x = x;
this.y = y;
boolean inCheck = player.inCheck();
this.x = xBefore;
this.y = yBefore;
chessboard.addPiece(piece, x, y);
chessboard.addPiece(this, this.x, this.y);
return inCheck;
}
public boolean isEndangered() {
return chessboard.isEndangered(player, x, y);
return chessboard.isEndangered(x, y);
}
public void move(PiecePosition pos) {
@ -275,7 +293,7 @@ public abstract class APiece {
int j = y + yDirection;
while(i >= 0 && i < moves.length && j >= 0 && j < moves.length) {
setPossibleMove(moves, i, j);
APiece piece = chessboard.getPiece(new PiecePosition(i, j));
APiece piece = chessboard.getPiece(i, j);
if(piece != null && piece != chessboard.getSelectedPiece()) break;
i += xDirection;
j += yDirection;
@ -338,14 +356,14 @@ public abstract class APiece {
double decrement = .01;
public void run() {
scale -= decrement;
decrement *= 1.2;
decrement *= 1.1;
if(scale < 0) {
timer.cancel();
scale = 0;
}
chessboard.repaint(getRepaintRectangle());
}
}, 5, 5);
}, 10, 10);
}
public double getScale() {

View file

@ -125,7 +125,7 @@ public class Chessboard extends JPanel {
Player pieceOwner = pieceType != item ? white : black;
int rookX = pieceType == 'q' ? 0 : 7;
int rookY = pieceType != item ? 7 : 0;
APiece rook = c.getPiece(new PiecePosition(rookX, rookY));
APiece rook = c.getPiece(rookX, rookY);
if(rook != null && rook.getPlayer() == pieceOwner) rook.setMoveCount(0);
}
}
@ -245,7 +245,7 @@ public class Chessboard extends JPanel {
}
if(possibleMoves != null && possibleMoves[y][x]) {
g.setColor(new Color(0, 0, 0, 40));
if(otherPlayer.getAttackArea()[y][x]) g.setColor(new Color(255, 0, 0, 40));
//if(otherPlayer.getAttackArea()[y][x]) g.setColor(new Color(255, 0, 0, 40));
if(pieces[y][x] == null) g.fillOval(50, 50, 40, 40);
else g.drawRect(8, 8, SQUARE_SIZE-16, SQUARE_SIZE-16);
}
@ -295,12 +295,13 @@ public class Chessboard extends JPanel {
/**
* Get piece on specified piece position
* @param pos piece position
* @param x piece's X location
* @param y piece's Y location
* @return piece
*/
public APiece getPiece(PiecePosition pos) {
if(!isOnBoard(pos.x, pos.y)) return null;
return pieces[pos.y][pos.x];
public APiece getPiece(int x, int y) {
if(!isOnBoard(x, y)) return null;
return pieces[y][x];
}
/**
@ -316,18 +317,59 @@ public class Chessboard extends JPanel {
/**
* Get current selected piece
* @return floating piece
* @return selected piece
*/
public APiece getSelectedPiece() {
return selected;
}
public boolean isEndangered(Player player, int x, int y) {
if(!isOnBoard(x, y)) return false;
boolean[][] coverageArea;
if(player == activePlayer) coverageArea = otherPlayer.getAttackArea();
else coverageArea = activePlayer.getAttackArea();
return coverageArea[y][x];
public boolean isEndangered(int x, int y) {
APiece piece = getPiece(x, y);
if(piece == null) return false;
int[] directions = new int[]{-1, 0, 1};
for (int i : directions) {
for (int j : directions) {
if(i == 0 && j == 0) continue;
int relX = i, relY = j;
while(isOnBoard(x+relX, y+relY)) {
APiece currentPiece = pieces[y+relY][x+relX];
if(currentPiece != null) {
if(currentPiece.getPlayer() != piece.getPlayer()) {
if(currentPiece instanceof Queen) return true;
if(Math.abs(j) == 1 && Math.abs(i) == 1) {
if(currentPiece instanceof Bishop) return true;
} else {
if(currentPiece instanceof Rook) return true;
}
if(relX != 0 && currentPiece instanceof Pawn) {
StartPosition sp = currentPiece.getPlayer().getStartPosition();
if(relY == -1 && sp == StartPosition.TOP || relY == 1 && sp == StartPosition.BOTTOM) {
return true;
}
}
if(relX == i && relY == j && currentPiece instanceof King) {
return true;
}
}
break;
}
relX += i;
relY += j;
}
}
}
for (int i : new int[]{-1, 1}) {
for (int j : new int[]{-2, 2}) {
APiece piece1 = getPiece(x+j, y+i);
APiece piece2 = getPiece(x+i, y+j);
if(piece1 instanceof Knight && piece1.getPlayer() != piece.getPlayer() || piece2 instanceof Knight && piece2.getPlayer() != piece.getPlayer()) {
return true;
}
}
}
return false;
}
public void showPossibleMoves(boolean[][] moves) {
@ -358,30 +400,6 @@ public class Chessboard extends JPanel {
Player tempPlayer = activePlayer;
activePlayer = otherPlayer;
otherPlayer = tempPlayer;
generateAttackAreas();
}
public void generateAttackAreas() {
boolean[][] player1Area = new boolean[SQUARE_COUNT][SQUARE_COUNT];
boolean[][] player2Area = new boolean[SQUARE_COUNT][SQUARE_COUNT];
for (APiece[] pieces2 : pieces) {
for (APiece piece : pieces2) {
if(piece != null && piece != selected) {
if(piece.getPlayer() == activePlayer) mergeAttackAreas(player1Area, piece.getPossibleMoves(true));
if(piece.getPlayer() == otherPlayer) mergeAttackAreas(player2Area, piece.getPossibleMoves(true));
}
}
}
activePlayer.setAttackArea(player1Area);
otherPlayer.setAttackArea(player2Area);
}
private void mergeAttackAreas(boolean[][] area1, boolean[][] area2) {
for (int y = 0; y < area2.length; y++) {
for (int x = 0; x < area2[y].length; x++) {
if(area2[y][x]) area1[y][x] = true;
}
}
}
}

View file

@ -48,11 +48,10 @@ public class ChessboardMouseAdapter extends MouseAdapter {
public void onClick(MouseEvent me) {
Chessboard c = (Chessboard) me.getSource();
PiecePosition pos = c.getPieceCoordinates(me.getX(), me.getY());
APiece piece = c.getPiece(pos);
APiece piece = c.getPiece(pos.x, pos.y);
APiece selectedPiece = c.getSelectedPiece();
if (piece != null && piece.getPlayer() == c.getActivePlayer() && selectedPiece != piece) {
c.setSelectedPiece(piece);
c.generateAttackAreas();
c.showPossibleMoves(piece.getPossibleMoves());
} else if(selectedPiece != null) {
if(selectedPiece.getPossibleMoves()[pos.y][pos.x]) {
@ -70,10 +69,9 @@ public class ChessboardMouseAdapter extends MouseAdapter {
public void onDragStart(MouseEvent me) {
Chessboard c = (Chessboard) me.getSource();
PiecePosition pos = c.getPieceCoordinates(me.getX(), me.getY());
APiece piece = c.getPiece(pos);
APiece piece = c.getPiece(pos.x, pos.y);
if (piece != null && piece.getPlayer() == c.getActivePlayer()) {
c.setSelectedPiece(piece);
c.generateAttackAreas();
c.showPossibleMoves(piece.getPossibleMoves());
c.getRootPane().repaint();
}

View file

@ -38,7 +38,7 @@ public class King extends APiece {
boolean[][] moves = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
for(int i = x-1; i <= x+1; i++) {
for(int j = y-1; j <= y+1; j++) {
if(!chessboard.isEndangered(player, i, j)) setPossibleMove(moves, i, j);
setPossibleMove(moves, i, j);
}
}
if(!attack && checkCastling(-1)) setPossibleMove(moves, 1, y);
@ -49,7 +49,7 @@ public class King extends APiece {
private boolean checkCastling(int direction) {
if(moveCount == 0 && !player.inCheck() && checkRook(direction)) {
for (int pX = x + direction; (pX > 0 && pX < 7); pX += direction) {
if(chessboard.isEndangered(player, pX, y) || chessboard.getPiece(new PiecePosition(pX, y)) != null) return false;
if(chessboard.isEndangered(pX, y) || chessboard.getPiece(pX, y) != null) return false;
}
return true;
}
@ -58,7 +58,7 @@ public class King extends APiece {
private boolean checkRook(int direction) {
int rookX = direction == -1 ? 0 : 7;
APiece rook = chessboard.getPiece(new PiecePosition(rookX, y));
APiece rook = chessboard.getPiece(rookX, y);
return rook != null && rook instanceof Rook && rook.getMoveCount() == 0;
}
@ -66,11 +66,11 @@ public class King extends APiece {
public void move(PiecePosition pos, boolean animate) {
super.move(pos, animate);
if(moveCount == 1 && x == 6) {
APiece rook = chessboard.getPiece(new PiecePosition(7, y));
APiece rook = chessboard.getPiece(7, y);
if(rook != null) rook.setPosition(new PiecePosition(5, y));
}
if(moveCount == 1 && x == 1) {
APiece rook = chessboard.getPiece(new PiecePosition(0, y));
APiece rook = chessboard.getPiece(0, y);
if(rook != null) rook.setPosition(new PiecePosition(3, y));
}
}

View file

@ -32,15 +32,10 @@ public class Knight extends APiece {
@Override
public boolean[][] getPossibleMoves(boolean attack) {
boolean[][] moves = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
int[] directions = new int[]{-1, 1};
boolean[] trueFalse = new boolean[]{false, true};
for (int i : directions) {
for (int j : directions) {
for (boolean horizontal : trueFalse) {
int relX = 2*i, relY = j;
if(horizontal) setPossibleMove(moves, relX+x, relY+y);
else setPossibleMove(moves, relY+x, relX+y);
}
for (int i : new int[]{-1, 1}) {
for (int j : new int[]{-2, 2}) {
setPossibleMove(moves, x+i, y+j);
setPossibleMove(moves, x+j, y+i);
}
}
return moves;

View file

@ -35,12 +35,12 @@ public class Pawn extends APiece {
int directionY = player.getStartPosition() == StartPosition.TOP ? 1 : -1;
for (int i = -1; i <= 1; i++) {
boolean isPieceThere = chessboard.getPiece(new PiecePosition(x+i, y+directionY)) != null;
boolean isPieceThere = chessboard.getPiece(x+i, y+directionY) != null;
if((i != 0 && (attack || isPieceThere)) || (i == 0 && (!attack && !isPieceThere))) setPossibleMove(moves, x+i, y+directionY);
}
boolean firstPlaceEmpty = chessboard.getPiece(new PiecePosition(x, y+directionY*2)) == null;
boolean secondPlaceEmpty = chessboard.getPiece(new PiecePosition(x, y+directionY)) == null;
boolean firstPlaceEmpty = chessboard.getPiece(x, y+directionY*2) == null;
boolean secondPlaceEmpty = chessboard.getPiece(x, y+directionY) == null;
if(moveCount == 0 && firstPlaceEmpty && secondPlaceEmpty && !attack) setPossibleMove(moves, x, y + directionY*2);
for (int directionX : new int[]{-1, 1}) {
@ -52,7 +52,7 @@ public class Pawn extends APiece {
}
private boolean checkEnPassant(int directionX) {
APiece piece = chessboard.getPiece(new PiecePosition(x+directionX, y));
APiece piece = chessboard.getPiece(x+directionX, y);
if(piece == null) 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;
@ -63,7 +63,7 @@ public class Pawn extends APiece {
for (int directionX : new int[]{-1, 1}) {
if(checkEnPassant(directionX) && pos.x == x+directionX) {
APiece piece = chessboard.getPiece(new PiecePosition(x+directionX, y));
APiece piece = chessboard.getPiece(x+directionX, y);
if(piece != null) piece.remove();
}
}

View file

@ -8,13 +8,10 @@ public class Player {
private King king;
private boolean[][] attackArea;
public Player(Chessboard chessboard, StartPosition startPosition, PieceColor color) {
this.chessboard = chessboard;
this.color = color;
this.startPosition = startPosition;
this.attackArea = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
}
public boolean inCheck() {
@ -33,14 +30,6 @@ public class Player {
return startPosition;
}
public void setAttackArea(boolean[][] area) {
attackArea = area;
}
public boolean[][] getAttackArea() {
return attackArea;
}
public King getKing() {
return king;
}