Chess/src/Chessboard.java
2023-04-17 19:49:53 +02:00

305 lines
8.2 KiB
Java

import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
/**
* Chessboard class
*/
public class Chessboard extends JPanel {
/**
* Size of single square
*/
private final int SQUARE_SIZE = 100;
/**
* Count of squares on the board
*/
public final int SQUARE_COUNT = 8;
/**
* Width of the chessboard
*/
private final double BOARD_WIDTH = SQUARE_COUNT*SQUARE_SIZE;
/**
* Scale of the chessboard
*/
public double boardScale;
/**
* Scale of single piece
*/
public double pieceScale;
/**
* Top location of the board
*/
private double startX;
/**
* Left location of the board
*/
private double startY;
/**
* Instance of the floating piece
*/
private IPiece floating;
/**
* Two-dimensional array of pieces
*/
public IPiece[][] pieces = new IPiece[SQUARE_COUNT][SQUARE_COUNT];
private boolean[][] possibleMoves;
private boolean[][] lastMove;
private Player player1;
private Player player2;
private Player activePlayer;
/**
* Constructor of the chessboard
*/
public Chessboard() {
ChessboardMouseAdapter ma = new ChessboardMouseAdapter();
addMouseListener(ma);
addMouseMotionListener(ma);
}
/**
* Add passed piece to the specified coordinates
* @param piece piece
* @param x piece's X location
* @param y piese's Y location
*/
public void addPiece(IPiece piece, int x, int y) {
if(!isOnBoard(x, y)) return;
pieces[y][x] = piece;
}
/**
* Remove piece at specified coordinates
* @param x piece's X location
* @param y piece's Y location
* @return removed piece
*/
public IPiece removePiece(int x, int y) {
if(!isOnBoard(x, y)) return null;
IPiece piece = pieces[y][x];
pieces[y][x] = null;
return piece;
}
/**
* Paint the chessboard
* @param g the <code>Graphics</code> context in which to paint
*/
public void paint(Graphics g) {
Graphics2D g2 = getGraphics2D(g);
double cx = this.getWidth() / 2.0;
double cy = this.getHeight() / 2.0;
boardScale = Math.min(this.getWidth(), this.getHeight())/ BOARD_WIDTH;
startX = cx-(BOARD_WIDTH /2.0*boardScale);
startY = cy-(BOARD_WIDTH /2.0*boardScale);
AffineTransform beforeBoard = g2.getTransform();
g2.translate(startX, startY);
g2.scale(boardScale, boardScale);
boolean isBlack = true;
AffineTransform beforeSquares = g2.getTransform();
for(int i=0; i<SQUARE_COUNT; i++) {
if(SQUARE_COUNT % 2 == 0) 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;
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(lastMove != null && lastMove[j][i]) {
g2.setTransform(beforeSquares);
g2.translate(i*SQUARE_SIZE, j*SQUARE_SIZE);
g2.setColor(new Color(50, 50, 250, 25));
g2.fillRect(0, 0, SQUARE_SIZE, SQUARE_SIZE);
}
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;
for (IPiece[] pieces2: pieces) {
for (IPiece piece : pieces2) {
if(piece != null && piece != floating) {
double xOffset = 20*pieceScale + SQUARE_SIZE*piece.getX();
double yOffset = 20*pieceScale + SQUARE_SIZE*piece.getY();
g2.translate(xOffset, yOffset);
g2.scale(pieceScale, pieceScale);
piece.paint(g2);
g2.setTransform(beforePieces);
}
}
}
if(floating != null) {
g2.setTransform(beforeBoard);
g2.translate(floating.getOverrideX(), floating.getOverrideY());
g2.scale(pieceScale * boardScale, pieceScale * boardScale);
floating.paint(g2);
}
g2.setTransform(beforeBoard);
}
/**
* Setup Graphics2D with anti-aliasing
* @param g Graphics instance
* @return Graphics2D instance
*/
public Graphics2D getGraphics2D(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
RenderingHints rh = new RenderingHints(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHints(rh);
return g2;
}
/**
* Get coordinates of piece from mouse X and Y location
* @param x mouse X location
* @param y mouse Y location
* @return piece position
*/
public PiecePosition getPieceCoordinates(int x, int y) {
int pieceX = (int) ((x-startX)/(SQUARE_SIZE*boardScale));
int pieceY = (int) ((y-startY)/(SQUARE_SIZE*boardScale));
return new PiecePosition(
Math.min(Math.max(pieceX, 0), SQUARE_COUNT-1),
Math.min(Math.max(pieceY, 0), SQUARE_COUNT-1)
);
}
/**
* Get piece on specified piece position
* @param pos piece position
* @return piece
*/
public IPiece getPiece(PiecePosition pos) {
if(!isOnBoard(pos.x, pos.y)) return null;
return pieces[pos.y][pos.x];
}
/**
* Grab piece at specified position and mark it as floating
* @param pos piece position
* @return piece
*/
public IPiece grabPiece(PiecePosition pos) {
if(!isOnBoard(pos.x, pos.y)) return null;
IPiece piece = getPiece(pos);
floating = piece;
this.repaint();
return piece;
}
/**
* Get current floating piece
* @return floating piece
*/
public IPiece getFloatingPiece() {
return floating;
}
/**
* Return piece at specified position to the board and unmark it from floating
* @param pos piece position
*/
public void returnPiece(PiecePosition pos) {
if(floating != null) {
if(pos != null) floating.setPosition(pos);
floating.setOverride(0, 0);
}
floating = null;
this.repaint();
}
public boolean isEndangered(PieceColor color, int x, int y) {
for (IPiece[] pieces : pieces) {
for (IPiece piece : pieces) {
if(piece != null && piece.getColor() != color) {
if(piece.getPossibleMoves()[y][x] == true) return true;
}
}
}
return false;
}
public void showPossibleMoves(boolean[][] moves) {
possibleMoves = moves;
}
public void showLastMove(boolean[][] move) {
lastMove = move;
}
public boolean isOnBoard(int x, int y) {
return !(y < 0 || y >= SQUARE_COUNT || x < 0 || x >= SQUARE_COUNT);
}
public void setPlayer1(Player player) {
player1 = player;
activePlayer = player;
}
public void setPlayer2(Player player) {
player2 = player;
}
public Player getActivePlayer() {
return activePlayer;
}
public void changeActivePlayer() {
if(activePlayer == player1) {
activePlayer = player2;
} else {
activePlayer = player1;
}
}
}