Added basic movement rules & possible move visualization

This commit is contained in:
Filip Znachor 2023-04-11 19:04:44 +02:00
parent aba20330ef
commit fbceecd80f
11 changed files with 180 additions and 26 deletions

View file

@ -37,6 +37,8 @@ public abstract class AbstractPiece implements IPiece {
*/
protected PieceColor color;
public int moveCount = 0;
/**
* Create new piece
* @param chessboard chessboard
@ -191,4 +193,37 @@ public abstract class AbstractPiece implements IPiece {
return y;
}
public PieceColor getColor() {
return color;
}
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;
IPiece piece = chessboard.getPiece(new PiecePosition(x, y));
if(piece != null && color == piece.getColor()) return;
moves[y][x] = true;
}
public void move(PiecePosition pos) {
boolean[][] moves = getPossibleMoves();
if(moves[pos.y][pos.x]) {
chessboard.returnPiece(pos);
moveCount++;
}
chessboard.returnPiece(null);
chessboard.showPossibleMoves(null);
}
public void tracePath(boolean[][] moves, int xDirection, int yDirection) {
int i = x + xDirection;
int j = y + yDirection;
while(i >= 0 && i < moves.length && j >= 0 && j < moves.length) {
setPossibleMove(moves, i, j);
if(chessboard.getPiece(new PiecePosition(i, j)) != null) break;
i += xDirection;
j += yDirection;
}
}
}

View file

@ -1,6 +1,8 @@
import java.awt.*;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
/**
* Bishop piece class
@ -42,4 +44,16 @@ public class Bishop extends AbstractPiece {
}
@Override
public boolean[][] getPossibleMoves() {
boolean[][] moves = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
int[] directions = new int[]{-1, 1};
for (int xDirection : directions) {
for (int yDirection : directions) {
tracePath(moves, xDirection, yDirection);
}
}
return moves;
}
}

View file

@ -19,7 +19,7 @@ public class Chess {
Chessboard chessboard = new Chessboard();
PieceColor[] colors = new PieceColor[]{PieceColor.BLACK, PieceColor.WHITE};
PieceColor[] colors = new PieceColor[]{PieceColor.WHITE, PieceColor.BLACK};
for (int i = 0; i < colors.length; i++) {
int first = i == 0 ? 7 : 0;
int second = i == 0 ? 6 : 1;
@ -27,10 +27,10 @@ public class Chess {
new Knight(chessboard, 1, first, colors[i]);
new Rook(chessboard, 7, first, colors[i]);
new Knight(chessboard, 6, first, colors[i]);
new Queen(chessboard, 4, first, colors[i]);
new Queen(chessboard, 3, first, colors[i]);
new Bishop(chessboard, 5, first, colors[i]);
new Bishop(chessboard, 2, first, colors[i]);
new King(chessboard, 3, first, colors[i]);
new King(chessboard, 4, first, colors[i]);
for (int j = 0; j < 8; j++) {
new Pawn(chessboard, j, second, colors[i]);
}

View file

@ -1,7 +1,6 @@
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
/**
* Chessboard class
@ -11,7 +10,7 @@ public class Chessboard extends JPanel {
/**
* Size of single square
*/
private final double SQUARE_SIZE = 100;
private final int SQUARE_SIZE = 100;
/**
* Count of squares on the board
@ -53,6 +52,8 @@ public class Chessboard extends JPanel {
*/
public IPiece[][] pieces = new IPiece[SQUARE_COUNT][SQUARE_COUNT];
private boolean[][] possibleMoves;
/**
* Constructor of the chessboard
*/
@ -108,19 +109,38 @@ public class Chessboard extends JPanel {
boolean isBlack = true;
AffineTransform beforeSquares = g2.getTransform();
for(int i=0; i<SQUARE_COUNT; i++) {
isBlack = !isBlack;
for(int j=0; j<SQUARE_COUNT; j++) {
g2.setTransform(beforeSquares);
if(isBlack) g2.setColor(Color.LIGHT_GRAY);
else g2.setColor(Color.WHITE);
isBlack = !isBlack;
Rectangle2D rect = new Rectangle2D.Double(SQUARE_SIZE * i, SQUARE_SIZE * j, SQUARE_SIZE, SQUARE_SIZE);
g2.fill(rect);
g2.translate(i*SQUARE_SIZE, j*SQUARE_SIZE);
g2.fillRect(0, 0, SQUARE_SIZE, SQUARE_SIZE);
}
}
g2.setStroke(new BasicStroke(10));
for(int i=0; i<SQUARE_COUNT; i++) {
for(int j=0; j<SQUARE_COUNT; j++) {
if(possibleMoves != null && possibleMoves[j][i]) {
g2.setTransform(beforeSquares);
g2.translate(i*SQUARE_SIZE, j*SQUARE_SIZE);
g2.setColor(new Color(255, 0, 0, 25));
g2.fillRect(0, 0, SQUARE_SIZE, SQUARE_SIZE);
g2.setColor(new Color(255, 50, 50));
g2.drawRect(0, 0, SQUARE_SIZE, SQUARE_SIZE);
}
}
}
g2.setTransform(beforeSquares);
AffineTransform beforePieces = g2.getTransform();
pieceScale = SQUARE_SIZE /140.0;
pieceScale = SQUARE_SIZE / 140.0;
for (IPiece[] pieces2: pieces) {
for (IPiece piece : pieces2) {
@ -212,11 +232,15 @@ public class Chessboard extends JPanel {
*/
public void returnPiece(PiecePosition pos) {
if(floating != null) {
floating.setPosition(pos);
if(pos != null) floating.setPosition(pos);
floating.setOverride(0, 0);
}
floating = null;
this.repaint();
}
void showPossibleMoves(boolean[][] moves) {
possibleMoves = moves;
}
}

View file

@ -18,6 +18,7 @@ public class ChessboardMouseAdapter extends MouseAdapter {
double totalScale = c.pieceScale * c.boardScale;
piece.setOverride(me.getX() - 50 * totalScale, me.getY() - 50 * totalScale);
c.repaint();
c.showPossibleMoves(piece.getPossibleMoves());
}
}
@ -44,7 +45,10 @@ public class ChessboardMouseAdapter extends MouseAdapter {
public void mouseReleased(MouseEvent me) {
Chessboard c = (Chessboard) me.getSource();
PiecePosition pos = c.getPieceCoordinates(me.getX(), me.getY());
c.returnPiece(pos);
IPiece piece = c.getFloatingPiece();
if(piece != null) {
piece.move(pos);
}
c.getRootPane().repaint();
}

View file

@ -1,4 +1,5 @@
import java.awt.*;
import java.util.List;
/**
* Piece's interface
@ -48,5 +49,11 @@ public interface IPiece {
*/
void setPosition(PiecePosition pos);
boolean[][] getPossibleMoves();
PieceColor getColor();
void move(PiecePosition pos);
}

View file

@ -2,6 +2,8 @@ import java.awt.*;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.List;
/**
* King piece class
@ -26,20 +28,24 @@ public class King extends AbstractPiece {
@Override
public void paint(Graphics2D g2) {
double[] xObject1 = new double[]{18, 27, 34, 43, 50, 57, 66, 73, 82, 70, 70, 30, 30};
double[] yObject1 = new double[]{27, 33, 26, 33, 26, 33, 26, 33, 27, 52, 58, 58, 52};
double[] xObject1 = new double[]{46, 54, 54, 63, 63, 54, 54, 66, 77, 85, 15, 23, 34, 46, 46, 37, 37, 46};
double[] yObject1 = new double[]{0, 0, 8, 8, 16, 16, 19, 24, 24, 31, 31, 24, 24, 19, 16, 16, 8, 8};
double[] xObjectClip = new double[]{27, 73, 73, 66, 57, 50, 43, 34, 27};
double[] yObjectClip = new double[]{0, 0, 28, 21, 28, 21, 28, 21, 28};
double[] xObject2 = new double[]{15, 85, 70, 70, 30, 30};
double[] yObject2 = new double[]{35, 35, 51, 58, 58, 51};
Path2D objectClip = getObject(xObjectClip, yObjectClip);
Ellipse2D ellipse = getEllipse(30, 6, 40, 40);
Ellipse2D ellipse2 = getEllipse(44, 0, 12, 12);
Area intersection = new Area(ellipse);
intersection.intersect(new Area(objectClip));
paintObjects(g2, new Shape[]{getStand(), getObject(xObject1, yObject1), ellipse2, intersection});
paintObjects(g2, new Shape[]{getStand(), getObject(xObject1, yObject1), getObject(xObject2, yObject2)});
}
@Override
public boolean[][] getPossibleMoves() {
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++) {
setPossibleMove(moves, i, j);
}
}
return moves;
}
}

View file

@ -1,4 +1,6 @@
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* Knight piece class
@ -30,4 +32,21 @@ public class Knight extends AbstractPiece {
}
@Override
public boolean[][] getPossibleMoves() {
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);
}
}
}
return moves;
}
}

View file

@ -27,4 +27,13 @@ public class Pawn extends AbstractPiece {
}
@Override
public boolean[][] getPossibleMoves() {
boolean[][] moves = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
int directionY = color == PieceColor.BLACK ? 1 : -1;
setPossibleMove(moves, x, y + directionY);
if(moveCount == 0 && chessboard.getPiece(new PiecePosition(x, y+directionY)) == null) setPossibleMove(moves, x, y + directionY*2);
return moves;
}
}

View file

@ -1,4 +1,9 @@
import java.awt.*;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.List;
/**
* Queen piece class
@ -23,14 +28,32 @@ public class Queen extends AbstractPiece {
@Override
public void paint(Graphics2D g2) {
double[] xObject1 = new double[]{46, 54, 54, 63, 63, 54, 54, 66, 77, 85, 15, 23, 34, 46, 46, 37, 37, 46};
double[] yObject1 = new double[]{0, 0, 8, 8, 16, 16, 19, 24, 24, 31, 31, 24, 24, 19, 16, 16, 8, 8};
double[] xObject1 = new double[]{18, 27, 34, 43, 50, 57, 66, 73, 82, 70, 70, 30, 30};
double[] yObject1 = new double[]{27, 33, 26, 33, 26, 33, 26, 33, 27, 52, 58, 58, 52};
double[] xObject2 = new double[]{15, 85, 70, 70, 30, 30};
double[] yObject2 = new double[]{35, 35, 51, 58, 58, 51};
double[] xObjectClip = new double[]{27, 73, 73, 66, 57, 50, 43, 34, 27};
double[] yObjectClip = new double[]{0, 0, 28, 21, 28, 21, 28, 21, 28};
paintObjects(g2, new Shape[]{getStand(), getObject(xObject1, yObject1), getObject(xObject2, yObject2)});
Path2D objectClip = getObject(xObjectClip, yObjectClip);
Ellipse2D ellipse = getEllipse(30, 6, 40, 40);
Ellipse2D ellipse2 = getEllipse(44, 0, 12, 12);
Area intersection = new Area(ellipse);
intersection.intersect(new Area(objectClip));
paintObjects(g2, new Shape[]{getStand(), getObject(xObject1, yObject1), ellipse2, intersection});
}
@Override
public boolean[][] getPossibleMoves() {
boolean[][] moves = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
int[] directions = new int[]{-1, 0, 1};
for (int xDirection : directions) {
for (int yDirection : directions) {
tracePath(moves, xDirection, yDirection);
}
}
return moves;
}
}

View file

@ -30,4 +30,17 @@ public class Rook extends AbstractPiece {
}
@Override
public boolean[][] getPossibleMoves() {
boolean[][] moves = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
int[] directions = new int[]{-1, 0, 1};
for (int xDirection : directions) {
for (int yDirection : directions) {
if((xDirection == 1 || xDirection == -1) && (yDirection == 1 || yDirection == -1)) continue;
tracePath(moves, xDirection, yDirection);
}
}
return moves;
}
}