Castling without undo+ sound (by arnaud)

This commit is contained in:
MSI-AB\antoineB 2025-05-22 23:22:05 +02:00
parent 37d37f96d0
commit 11b6995f1e
7 changed files with 159 additions and 18 deletions

32
src/backend/Audio.java Normal file
View File

@ -0,0 +1,32 @@
package backend;
import javax.sound.sampled.*;
public class Audio {
// No static methods, so these are now instance methods
public void playMoveSound() {
playSound("moveSound.wav");
}
public void playCheckSound() {
playSound("check.wav");
}
public void playCastkingSound() {
playSound("castling.wav");
}
// Private helper method to avoid code duplication
private void playSound(String resourceName) {
try {
AudioInputStream audioIn = AudioSystem.getAudioInputStream(
Audio.class.getResource(resourceName)
);
Clip clip = AudioSystem.getClip();
clip.open(audioIn);
clip.start();
} catch (Exception e) {
System.err.println("Could not play " + resourceName);
e.printStackTrace();}
}
}

View File

@ -1,7 +1,7 @@
package backend;
import java.util.ArrayList;
import backend.Audio;
public class Board {
@ -16,6 +16,7 @@ public class Board {
private ArrayList<Move> moveHistory = new ArrayList<>();
private int[] enPassantTarget = null;
private GameSoundManager soundManager;
public Board(int colNum, int lineNum) {
@ -148,6 +149,12 @@ public class Board {
// Otherwise, try to move
Piece selectedPiece = getPieceAt(selectedX, selectedY);
Audio audio = new Audio();
if (isKingInCheck(false)) {
audio.playCheckSound();
} else {
audio.playMoveSound();
}
if (selectedPiece == null) {
// Somehow no piece at selected position (safety check)
selectedX = null;
@ -172,6 +179,27 @@ public class Board {
highlightedSquares.clear();
return;
}
// Detect and apply castling rook move
if (selectedPiece.getType() == PieceType.King && Math.abs(x - selectedX) == 2) {
if (x == 6) { // Kingside
Piece rook = getPieceAt(7, selectedY);
if (rook != null) {
pieces.remove(rook);
Piece newRook = new Piece(rook.isWhite(), PieceType.Rook, 5, selectedY);
newRook.setHasMoved(true);
pieces.add(newRook);
}
} else if (x == 2) { // Queenside
Piece rook = getPieceAt(0, selectedY);
if (rook != null) {
pieces.remove(rook);
Piece newRook = new Piece(rook.isWhite(), PieceType.Rook, 3, selectedY);
newRook.setHasMoved(true);
pieces.add(newRook);
}
}
}
// Move is valid capture if needed
Piece target = getPieceAt(x, y);
@ -195,7 +223,9 @@ public class Board {
pieces.remove(selectedPiece);
// Add new piece at destination
setPiece(selectedPiece.isWhite(), selectedPiece.getType(), x, y);
Piece newPiece = new Piece(selectedPiece.isWhite(), selectedPiece.getType(), x, y);
newPiece.setHasMoved(true); // <--- Mark the piece as having moved
pieces.add(newPiece);
// Update turn
turnNumber++;
@ -350,7 +380,9 @@ public class Board {
}
// Restore moved piece to original location
setPiece(lastMove.isWhite(), lastMove.getType(), lastMove.getFromX(), lastMove.getFromY());
Piece restored = new Piece(lastMove.isWhite(), lastMove.getType(), lastMove.getFromX(), lastMove.getFromY());
restored.setHasMoved(false); // <--- assume undo reverts first move
pieces.add(restored);
// Restore captured piece if there was one
if (lastMove.getCapturedPiece() != null) {
@ -405,7 +437,9 @@ public class Board {
pieces.remove(pieceToMove);
// Add the moved piece at new location
setPiece(move.isWhite(), move.getType(), move.getToX(), move.getToY());
Piece newPiece = new Piece(move.isWhite(), move.getType(), move.getToX(), move.getToY());
newPiece.setHasMoved(true); // <--- Track movement
pieces.add(newPiece);
// Save move to history
moveHistory.add(move);
@ -466,8 +500,49 @@ public boolean isKingInCheck(boolean isWhite) {
System.out.println("kingfound");
return false; // king is not in check
}
private boolean canCastleKingside(boolean isWhite) {
int y = isWhite ? 7 : 0;
Piece king = getPieceAt(4, y);
Piece rook = getPieceAt(7, y);
public ArrayList<int[]> computeLegalMoves(Piece piece) {
if (king == null || rook == null || king.hasMoved() || rook.hasMoved()) return false;
if (!isEmpty(5, y) || !isEmpty(6, y)) return false;
if (isKingInCheck(isWhite)) return false;
Board step1 = new Board(this);
step1.playMove(new Move(PieceType.King, isWhite, 4, y, 5, y, null));
if (step1.isKingInCheck(isWhite)) return false;
Board step2 = new Board(this);
step2.playMove(new Move(PieceType.King, isWhite, 4, y, 6, y, null));
if (step2.isKingInCheck(isWhite)) return false;
return true;
}
private boolean canCastleQueenside(boolean isWhite) {
int y = isWhite ? 7 : 0;
Piece king = getPieceAt(4, y);
Piece rook = getPieceAt(0, y);
if (king == null || rook == null || king.hasMoved() || rook.hasMoved()) return false;
if (!isEmpty(1, y) || !isEmpty(2, y) || !isEmpty(3, y)) return false;
if (isKingInCheck(isWhite)) return false;
Board step1 = new Board(this);
step1.playMove(new Move(PieceType.King, isWhite, 4, y, 3, y, null));
if (step1.isKingInCheck(isWhite)) return false;
Board step2 = new Board(this);
step2.playMove(new Move(PieceType.King, isWhite, 4, y, 2, y, null));
if (step2.isKingInCheck(isWhite)) return false;
return true;
}
public ArrayList<int[]> computeLegalMoves(Piece piece) {
ArrayList<int[]> moves = new ArrayList<>();
int x = piece.getX();
int y = piece.getY();
@ -607,9 +682,18 @@ public ArrayList<int[]> computeLegalMoves(Piece piece) {
}
}
}
// Add castling moves if King hasn't moved
if (!piece.hasMoved()) {
if (canCastleKingside(piece.isWhite())) {
moves.add(new int[]{x + 2, y}); // Kingside castling
}
if (canCastleQueenside(piece.isWhite())) {
moves.add(new int[]{x - 2, y}); // Queenside castling
}
}
}
return moves;
}
}
}
}

View File

@ -46,5 +46,6 @@ public class GameSoundManager {
public void stopAllSounds() {
if (jblClip != null) jblClip.stop();
if (backgroundClip != null) backgroundClip.stop();
}
}
}

View File

@ -6,6 +6,26 @@ public class Move {
private boolean isWhite;
private PieceType type;
private Piece capturedPiece;
private boolean isCastlingMove = false;
private boolean isKingside = false;
public boolean isCastlingMove() {
return isCastlingMove;
}
public void setCastling(boolean isCastling, boolean isKingside) {
this.isCastlingMove = isCastling;
this.isKingside = isKingside;
}
public boolean isKingsideCastling() {
return isCastlingMove && isKingside;
}
public boolean isQueensideCastling() {
return isCastlingMove && !isKingside;
}
public Move(PieceType type, boolean isWhite, int fromX, int fromY, int toX, int toY, Piece capturedPiece) {
this.fromX = fromX;
@ -23,8 +43,6 @@ public class Move {
public int getToY() { return toY; }
public boolean isWhite() { return isWhite; }
public PieceType getType() { return type; }
public Piece getCapturedPiece() { return capturedPiece; }
public Piece getCapturedPiece() { return capturedPiece;}
}

View File

@ -5,6 +5,16 @@ public class Piece {
private PieceType type;
private int x;
private int y;
private boolean hasMoved = false;
public boolean hasMoved() {
return hasMoved;
}
public void setHasMoved(boolean hasMoved) {
this.hasMoved = hasMoved;
}
// Constructor
public Piece(boolean isWhite, PieceType type, int x, int y) {
@ -42,9 +52,5 @@ public class Piece {
}
public void setX(int x) {
this.x = x;
}
}
this.x = x;
}}

BIN
src/backend/check.wav Normal file

Binary file not shown.

BIN
src/backend/moveSound.wav Normal file

Binary file not shown.