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;
|
package backend;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import backend.Audio;
|
||||||
|
|
||||||
public class Board {
|
public class Board {
|
||||||
|
|
||||||
|
|
@ -16,6 +16,7 @@ public class Board {
|
||||||
private ArrayList<Move> moveHistory = new ArrayList<>();
|
private ArrayList<Move> moveHistory = new ArrayList<>();
|
||||||
private int[] enPassantTarget = null;
|
private int[] enPassantTarget = null;
|
||||||
private GameSoundManager soundManager;
|
private GameSoundManager soundManager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Board(int colNum, int lineNum) {
|
public Board(int colNum, int lineNum) {
|
||||||
|
|
@ -148,6 +149,12 @@ public class Board {
|
||||||
|
|
||||||
// Otherwise, try to move
|
// Otherwise, try to move
|
||||||
Piece selectedPiece = getPieceAt(selectedX, selectedY);
|
Piece selectedPiece = getPieceAt(selectedX, selectedY);
|
||||||
|
Audio audio = new Audio();
|
||||||
|
if (isKingInCheck(false)) {
|
||||||
|
audio.playCheckSound();
|
||||||
|
} else {
|
||||||
|
audio.playMoveSound();
|
||||||
|
}
|
||||||
if (selectedPiece == null) {
|
if (selectedPiece == null) {
|
||||||
// Somehow no piece at selected position (safety check)
|
// Somehow no piece at selected position (safety check)
|
||||||
selectedX = null;
|
selectedX = null;
|
||||||
|
|
@ -172,6 +179,27 @@ public class Board {
|
||||||
highlightedSquares.clear();
|
highlightedSquares.clear();
|
||||||
return;
|
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
|
// Move is valid → capture if needed
|
||||||
Piece target = getPieceAt(x, y);
|
Piece target = getPieceAt(x, y);
|
||||||
|
|
@ -195,7 +223,9 @@ public class Board {
|
||||||
pieces.remove(selectedPiece);
|
pieces.remove(selectedPiece);
|
||||||
|
|
||||||
// Add new piece at destination
|
// 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
|
// Update turn
|
||||||
turnNumber++;
|
turnNumber++;
|
||||||
|
|
@ -350,7 +380,9 @@ public class Board {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore moved piece to original location
|
// 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
|
// Restore captured piece if there was one
|
||||||
if (lastMove.getCapturedPiece() != null) {
|
if (lastMove.getCapturedPiece() != null) {
|
||||||
|
|
@ -405,7 +437,9 @@ public class Board {
|
||||||
pieces.remove(pieceToMove);
|
pieces.remove(pieceToMove);
|
||||||
|
|
||||||
// Add the moved piece at new location
|
// 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
|
// Save move to history
|
||||||
moveHistory.add(move);
|
moveHistory.add(move);
|
||||||
|
|
@ -466,8 +500,49 @@ public boolean isKingInCheck(boolean isWhite) {
|
||||||
System.out.println("kingfound");
|
System.out.println("kingfound");
|
||||||
return false; // king is not in check
|
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<>();
|
ArrayList<int[]> moves = new ArrayList<>();
|
||||||
int x = piece.getX();
|
int x = piece.getX();
|
||||||
int y = piece.getY();
|
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;
|
return moves;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,5 +46,6 @@ public class GameSoundManager {
|
||||||
public void stopAllSounds() {
|
public void stopAllSounds() {
|
||||||
if (jblClip != null) jblClip.stop();
|
if (jblClip != null) jblClip.stop();
|
||||||
if (backgroundClip != null) backgroundClip.stop();
|
if (backgroundClip != null) backgroundClip.stop();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,26 @@ public class Move {
|
||||||
private boolean isWhite;
|
private boolean isWhite;
|
||||||
private PieceType type;
|
private PieceType type;
|
||||||
private Piece capturedPiece;
|
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) {
|
public Move(PieceType type, boolean isWhite, int fromX, int fromY, int toX, int toY, Piece capturedPiece) {
|
||||||
this.fromX = fromX;
|
this.fromX = fromX;
|
||||||
|
|
@ -23,8 +43,6 @@ public class Move {
|
||||||
public int getToY() { return toY; }
|
public int getToY() { return toY; }
|
||||||
public boolean isWhite() { return isWhite; }
|
public boolean isWhite() { return isWhite; }
|
||||||
public PieceType getType() { return type; }
|
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 PieceType type;
|
||||||
private int x;
|
private int x;
|
||||||
private int y;
|
private int y;
|
||||||
|
private boolean hasMoved = false;
|
||||||
|
|
||||||
|
public boolean hasMoved() {
|
||||||
|
return hasMoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHasMoved(boolean hasMoved) {
|
||||||
|
this.hasMoved = hasMoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
public Piece(boolean isWhite, PieceType type, int x, int y) {
|
public Piece(boolean isWhite, PieceType type, int x, int y) {
|
||||||
|
|
@ -42,9 +52,5 @@ public class Piece {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setX(int x) {
|
public void setX(int x) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
}
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue