Castling without undo+ sound (by arnaud)
This commit is contained in:
parent
37d37f96d0
commit
11b6995f1e
|
|
@ -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();}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,5 +46,6 @@ public class GameSoundManager {
|
|||
public void stopAllSounds() {
|
||||
if (jblClip != null) jblClip.stop();
|
||||
if (backgroundClip != null) backgroundClip.stop();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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;}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue