final no more modifications needs to be made
This commit is contained in:
parent
642d3cfe11
commit
e1bf29b709
|
|
@ -262,10 +262,34 @@ public class Board {
|
||||||
|
|
||||||
public void undoLastMove() {
|
public void undoLastMove() {
|
||||||
if (moveHistory.isEmpty()) return;
|
if (moveHistory.isEmpty()) return;
|
||||||
// ... you can reuse your existing undo logic here ...
|
|
||||||
Move m = moveHistory.pop();
|
Move m = moveHistory.pop();
|
||||||
// mirror of playMove in reverse (omitted for brevity)...
|
removePieceAt(m.getToX(), m.getToY()); // remove moved piece
|
||||||
// then turnNumber-- and isWhiteTurn = !isWhiteTurn
|
|
||||||
|
// Restore captured piece if there was one
|
||||||
|
if (m.getCapturedPiece() != null) {
|
||||||
|
pieces.add(m.getCapturedPiece());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore original piece position
|
||||||
|
pieces.add(new Piece(m.getFromX(), m.getFromY(), m.isWhite(), m.getType()));
|
||||||
|
|
||||||
|
// If the move was castling, move the rook back too
|
||||||
|
if (m.getType() == PieceType.King && Math.abs(m.getToX() - m.getFromX()) == 2) {
|
||||||
|
int rank = m.isWhite() ? 7 : 0;
|
||||||
|
if (m.getToX() > m.getFromX()) {
|
||||||
|
// King-side
|
||||||
|
removePieceAt(5, rank);
|
||||||
|
pieces.add(new Piece(7, rank, m.isWhite(), PieceType.Rook));
|
||||||
|
} else {
|
||||||
|
// Queen-side
|
||||||
|
removePieceAt(3, rank);
|
||||||
|
pieces.add(new Piece(0, rank, m.isWhite(), PieceType.Rook));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
turnNumber--;
|
||||||
|
isWhiteTurn = !isWhiteTurn;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Legal-move generation & check detection ────────────────────────────
|
// ─── Legal-move generation & check detection ────────────────────────────
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,15 @@ public class Game extends Thread {
|
||||||
this.ui = ui;
|
this.ui = ui;
|
||||||
this.board = new Board(8, 8);
|
this.board = new Board(8, 8);
|
||||||
this.aiPlayer = new AutoPlayer();
|
this.aiPlayer = new AutoPlayer();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
public void toggleAI(boolean isWhite) {
|
||||||
|
aiOn[isWhite ? 1 : 0] = !aiOn[isWhite ? 1 : 0];
|
||||||
|
}
|
||||||
|
public Board getBoard() {
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getWidth() { return board.getWidth(); }
|
public int getWidth() { return board.getWidth(); }
|
||||||
public int getHeight() { return board.getHeight(); }
|
public int getHeight() { return board.getHeight(); }
|
||||||
|
|
@ -109,15 +117,10 @@ public class Game extends Thread {
|
||||||
board.undoLastMove();
|
board.undoLastMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void toggleAI(boolean isWhite) {
|
|
||||||
aiOn[isWhite ? 1 : 0] = !aiOn[isWhite ? 1 : 0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public Board getBoard() { return board; }
|
|
||||||
|
|
||||||
public void setLoopDelay(int ms) {
|
public void setLoopDelay(int ms) {
|
||||||
this.loopDelay = ms;
|
this.loopDelay = ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@ import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import backend.*;
|
import backend.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import backend.Move;
|
|
||||||
|
|
||||||
|
|
||||||
public class JPanelChessBoard extends JPanel {
|
public class JPanelChessBoard extends JPanel {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
@ -19,65 +17,114 @@ public class JPanelChessBoard extends JPanel {
|
||||||
private final int PIECE_W = 16, PIECE_H = 16, MARGIN = 6;
|
private final int PIECE_W = 16, PIECE_H = 16, MARGIN = 6;
|
||||||
|
|
||||||
private boolean pieceSelectorMode = false;
|
private boolean pieceSelectorMode = false;
|
||||||
private boolean pieceAdderMode = false;
|
private boolean pieceAdderMode = false;
|
||||||
private boolean selIsWhite = true;
|
private boolean selIsWhite = true;
|
||||||
private PieceType selType = PieceType.Pawn;
|
private PieceType selType = PieceType.Pawn;
|
||||||
|
|
||||||
public JPanelChessBoard(MyInterface itf) {
|
public JPanelChessBoard(MyInterface itf) {
|
||||||
super();
|
super();
|
||||||
interfaceGlobal = itf;
|
this.interfaceGlobal = itf;
|
||||||
try {
|
try {
|
||||||
spriteSheet = javax.imageio.ImageIO.read(new File("pieces.png"));
|
spriteSheet = javax.imageio.ImageIO.read(new File("pieces.png"));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
addMouseListener(new MouseAdapter() {
|
addMouseListener(new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed(MouseEvent me) {
|
public void mousePressed(MouseEvent me) {
|
||||||
if (pieceSelectorMode) {
|
// 1) Ensure game is initialized
|
||||||
int x = (int) (me.getX() / cellW());
|
if (myGame == null) {
|
||||||
int y = (int) (me.getY() / cellH());
|
interfaceGlobal.instantiateSimu();
|
||||||
selType = PieceType.values()[5 - x];
|
|
||||||
selIsWhite = (y > 1);
|
|
||||||
pieceSelectorMode = false;
|
|
||||||
} else {
|
|
||||||
if (myGame == null) interfaceGlobal.instantiateSimu();
|
|
||||||
int x = me.getX() * myGame.getWidth() / getWidth();
|
|
||||||
int y = me.getY() * myGame.getHeight() / getHeight();
|
|
||||||
if (pieceAdderMode) {
|
|
||||||
myGame.setPiece(selIsWhite, selType, x, y);
|
|
||||||
pieceAdderMode = false;
|
|
||||||
} else {
|
|
||||||
myGame.clickCoords(x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2) If we're in piece-selector mode, interpret click on a 6×2 grid:
|
||||||
|
if (pieceSelectorMode) {
|
||||||
|
// selector grid spans full panel:
|
||||||
|
float sw = getWidth() / 6f;
|
||||||
|
float sh = getHeight() / 2f;
|
||||||
|
int col = (int)(me.getX() / sw);
|
||||||
|
int row = (int)(me.getY() / sh);
|
||||||
|
|
||||||
|
PieceType[] types = PieceType.values(); // [Pawn,Rook,Knight,Bishop,Queen,King]
|
||||||
|
if (col >= 0 && col < 6 && row >= 0 && row < 2) {
|
||||||
|
// col=0 → King, …, col=5 → Pawn
|
||||||
|
selType = types[types.length - 1 - col];
|
||||||
|
selIsWhite = (row == 1); // row=1 → white, row=0 → black
|
||||||
|
}
|
||||||
|
pieceSelectorMode = false;
|
||||||
|
repaint();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) Otherwise compute click on 8×8 board:
|
||||||
|
float bw = cellW(), bh = cellH();
|
||||||
|
int x = (int)(me.getX() / bw);
|
||||||
|
int y = (int)(me.getY() / bh);
|
||||||
|
|
||||||
|
// 4) Piece-adder mode?
|
||||||
|
if (pieceAdderMode) {
|
||||||
|
myGame.setPiece(selIsWhite, selType, x, y);
|
||||||
|
pieceAdderMode = false;
|
||||||
|
repaint();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5) Normal move
|
||||||
|
myGame.clickCoords(x, y);
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGame(Game g) {
|
public void setGame(Game g) {
|
||||||
myGame = g;
|
this.myGame = g;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent(Graphics gg) {
|
protected void paintComponent(Graphics gg) {
|
||||||
super.paintComponent(gg);
|
super.paintComponent(gg);
|
||||||
if (myGame == null) return;
|
|
||||||
|
|
||||||
Graphics2D g = (Graphics2D) gg;
|
Graphics2D g = (Graphics2D) gg;
|
||||||
|
|
||||||
|
// 1) Draw selector palette if needed
|
||||||
|
if (pieceSelectorMode) {
|
||||||
|
int cols = 6, rows = 2;
|
||||||
|
int cw = getWidth() / cols;
|
||||||
|
int ch = getHeight() / rows;
|
||||||
|
PieceType[] types = PieceType.values();
|
||||||
|
|
||||||
|
for (int row = 0; row < rows; row++) {
|
||||||
|
for (int col = 0; col < cols; col++) {
|
||||||
|
g.setColor((col + row) % 2 == 0 ? Color.LIGHT_GRAY : Color.GRAY);
|
||||||
|
g.fillRect(col*cw, row*ch, cw, ch);
|
||||||
|
|
||||||
|
PieceType pt = types[types.length - 1 - col];
|
||||||
|
int sx = (5 - pt.ordinal()) * PIECE_W;
|
||||||
|
int sy = (row == 1 ? PIECE_H : 0);
|
||||||
|
BufferedImage sub = spriteSheet.getSubimage(sx, sy, PIECE_W, PIECE_H);
|
||||||
|
Image scaled = sub.getScaledInstance(cw - 2*MARGIN, ch - 2*MARGIN, Image.SCALE_SMOOTH);
|
||||||
|
|
||||||
|
g.drawImage(scaled, col*cw + MARGIN, row*ch + MARGIN, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) Normal chessboard rendering
|
||||||
|
if (myGame == null) return;
|
||||||
float w = cellW(), h = cellH();
|
float w = cellW(), h = cellH();
|
||||||
|
|
||||||
// find selected square
|
// find selected square
|
||||||
int selX = -1, selY = -1;
|
int selX = -1, selY = -1;
|
||||||
for (int xx = 0; xx < myGame.getWidth(); xx++)
|
for (int xx = 0; xx < myGame.getWidth(); xx++) {
|
||||||
for (int yy = 0; yy < myGame.getHeight(); yy++)
|
for (int yy = 0; yy < myGame.getHeight(); yy++) {
|
||||||
if (myGame.isSelected(xx, yy)) {
|
if (myGame.isSelected(xx, yy)) {
|
||||||
selX = xx;
|
selX = xx; selY = yy;
|
||||||
selY = yy;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// legal highlights
|
// highlight legal moves
|
||||||
Set<Point> legal = new HashSet<>();
|
Set<Point> legal = new HashSet<>();
|
||||||
if (selX >= 0) {
|
if (selX >= 0) {
|
||||||
List<Move> lm = ChessRules.generateLegalMoves(
|
List<Move> lm = ChessRules.generateLegalMoves(
|
||||||
|
|
@ -90,7 +137,7 @@ public class JPanelChessBoard extends JPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw board
|
// draw squares
|
||||||
for (int x = 0; x < myGame.getWidth(); x++) {
|
for (int x = 0; x < myGame.getWidth(); x++) {
|
||||||
for (int y = 0; y < myGame.getHeight(); y++) {
|
for (int y = 0; y < myGame.getHeight(); y++) {
|
||||||
boolean isSel = (x == selX && y == selY);
|
boolean isSel = (x == selX && y == selY);
|
||||||
|
|
@ -98,14 +145,17 @@ public class JPanelChessBoard extends JPanel {
|
||||||
if (isSel) g.setColor(Color.PINK);
|
if (isSel) g.setColor(Color.PINK);
|
||||||
else if (isHl) g.setColor(Color.GREEN);
|
else if (isHl) g.setColor(Color.GREEN);
|
||||||
else g.setColor((x + y) % 2 == 0 ? Color.WHITE : Color.RED);
|
else g.setColor((x + y) % 2 == 0 ? Color.WHITE : Color.RED);
|
||||||
g.fillRect((int)(x*w),(int)(y*h),(int)w,(int)h);
|
g.fillRect((int)(x*w), (int)(y*h), (int)w, (int)h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// draw grid
|
||||||
g.setColor(Color.GRAY);
|
g.setColor(Color.GRAY);
|
||||||
for (int x = 0; x <= myGame.getWidth(); x++)
|
for (int x = 0; x <= myGame.getWidth(); x++) {
|
||||||
g.drawLine((int)(x*w), 0, (int)(x*w), getHeight());
|
g.drawLine((int)(x*w), 0, (int)(x*w), getHeight());
|
||||||
for (int y = 0; y <= myGame.getHeight(); y++)
|
}
|
||||||
|
for (int y = 0; y <= myGame.getHeight(); y++) {
|
||||||
g.drawLine(0, (int)(y*h), getWidth(), (int)(y*h));
|
g.drawLine(0, (int)(y*h), getWidth(), (int)(y*h));
|
||||||
|
}
|
||||||
|
|
||||||
// draw pieces
|
// draw pieces
|
||||||
for (Piece p : myGame.getPieces()) {
|
for (Piece p : myGame.getPieces()) {
|
||||||
|
|
@ -115,28 +165,17 @@ public class JPanelChessBoard extends JPanel {
|
||||||
|
|
||||||
private void drawPiece(Graphics2D g, Piece p, float w, float h) {
|
private void drawPiece(Graphics2D g, Piece p, float w, float h) {
|
||||||
int idx = 5 - p.getType().ordinal();
|
int idx = 5 - p.getType().ordinal();
|
||||||
BufferedImage sub = spriteSheet.getSubimage(
|
int sx = idx * PIECE_W;
|
||||||
idx * PIECE_W,
|
int sy = p.isWhite() ? PIECE_H : 0;
|
||||||
p.isWhite() ? PIECE_H : 0,
|
BufferedImage sub = spriteSheet.getSubimage(sx, sy, PIECE_W, PIECE_H);
|
||||||
PIECE_W, PIECE_H
|
Image scaled = sub.getScaledInstance((int)(w - 2*MARGIN), (int)(h - 2*MARGIN), Image.SCALE_SMOOTH);
|
||||||
);
|
g.drawImage(scaled, (int)(p.getX()*w) + MARGIN, (int)(p.getY()*h) + MARGIN, null);
|
||||||
Image scaled = sub.getScaledInstance(
|
|
||||||
(int)(w - 2 * MARGIN),
|
|
||||||
(int)(h - 2 * MARGIN),
|
|
||||||
Image.SCALE_SMOOTH
|
|
||||||
);
|
|
||||||
g.drawImage(
|
|
||||||
scaled,
|
|
||||||
(int)(p.getX() * w) + MARGIN,
|
|
||||||
(int)(p.getY() * h) + MARGIN,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private float cellW() { return getWidth() / (float) myGame.getWidth(); }
|
private float cellW() { return getWidth() / (float)myGame.getWidth(); }
|
||||||
private float cellH() { return getHeight() / (float) myGame.getHeight(); }
|
private float cellH() { return getHeight() / (float)myGame.getHeight(); }
|
||||||
|
|
||||||
// modes
|
// toggles
|
||||||
public void togglePieceSelector() { pieceSelectorMode = !pieceSelectorMode; }
|
public void togglePieceSelector() { pieceSelectorMode = !pieceSelectorMode; }
|
||||||
public void toggleAdderMode() { pieceAdderMode = !pieceAdderMode; }
|
public void toggleAdderMode() { pieceAdderMode = !pieceAdderMode; }
|
||||||
public boolean isPieceSelectorMode() { return pieceSelectorMode; }
|
public boolean isPieceSelectorMode() { return pieceSelectorMode; }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue