Actualiser src/backend/ChessTimer.java
This commit is contained in:
parent
df366fa41e
commit
1c570c3d01
|
|
@ -3,21 +3,26 @@ package backend;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ChessTimer manages the time control for both players in a chess game
|
||||||
|
*/
|
||||||
public class ChessTimer {
|
public class ChessTimer {
|
||||||
private long whiteTimeMillis; // Time remaining for white player in milliseconds
|
private long whiteTimeMillis; // Time remaining for white player in milliseconds
|
||||||
private long blackTimeMillis; // Time remaining for black player in milliseconds
|
private long blackTimeMillis; // Time remaining for black player in milliseconds
|
||||||
private long lastUpdateTime; // Time when the timer was last updated
|
private long lastUpdateTime; // The timestamp when timer was last updated
|
||||||
private boolean isRunning; // Is the timer currently running?
|
private boolean isRunning; // Flag to track if timer is active
|
||||||
private boolean isWhiteTurn; // Is it white's turn?
|
private boolean isWhiteTurn; // Flag to track which player's clock is running
|
||||||
private Timer timer; // Java util timer to handle periodic updates
|
private Timer timer; // Java Timer object that handles periodic updates
|
||||||
private TimerUpdateListener listener; // Listener to notify UI when time changes
|
private TimerUpdateListener listener; // Callback interface to notify UI of time changes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for notifying time updates
|
* Interface for notifying time updates to the UI or other components
|
||||||
*/
|
*/
|
||||||
public interface TimerUpdateListener {
|
public interface TimerUpdateListener {
|
||||||
|
// Called periodically to update displayed time
|
||||||
void onTimeUpdate(long whiteTimeMillis, long blackTimeMillis);
|
void onTimeUpdate(long whiteTimeMillis, long blackTimeMillis);
|
||||||
void onTimeExpired(boolean isWhiteExpired); // Called when a player's time runs out
|
// Called when a player runs out of time
|
||||||
|
void onTimeExpired(boolean isWhiteExpired);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -26,40 +31,43 @@ public class ChessTimer {
|
||||||
* @param listener Listener to receive time updates
|
* @param listener Listener to receive time updates
|
||||||
*/
|
*/
|
||||||
public ChessTimer(int initialTimeMinutes, TimerUpdateListener listener) {
|
public ChessTimer(int initialTimeMinutes, TimerUpdateListener listener) {
|
||||||
|
// Convert minutes to milliseconds for internal tracking
|
||||||
this.whiteTimeMillis = initialTimeMinutes * 60 * 1000;
|
this.whiteTimeMillis = initialTimeMinutes * 60 * 1000;
|
||||||
this.blackTimeMillis = initialTimeMinutes * 60 * 1000;
|
this.blackTimeMillis = initialTimeMinutes * 60 * 1000;
|
||||||
this.isRunning = false;
|
this.isRunning = false; // Timer starts paused
|
||||||
this.isWhiteTurn = true; // White starts in chess
|
this.isWhiteTurn = true; // White always starts in chess
|
||||||
this.listener = listener;
|
this.listener = listener; // Store the listener for callbacks
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the timer
|
* Start the timer - begins counting down for the current player
|
||||||
*/
|
*/
|
||||||
public void start() {
|
public void start() {
|
||||||
if (!isRunning) {
|
if (!isRunning) {
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
|
// Record the current time to measure elapsed time later
|
||||||
lastUpdateTime = System.currentTimeMillis();
|
lastUpdateTime = System.currentTimeMillis();
|
||||||
|
|
||||||
// Schedule periodic updates (every 100ms)
|
// Create a timer that updates every 100ms (10 times per second)
|
||||||
timer = new Timer(true);
|
timer = new Timer(true); // true = daemon thread
|
||||||
timer.scheduleAtFixedRate(new TimerTask() {
|
timer.scheduleAtFixedRate(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
updateTime();
|
updateTime(); // Update the clock on each tick
|
||||||
}
|
}
|
||||||
}, 0, 100);
|
}, 0, 100); // Initial delay 0ms, then every 100ms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop the timer
|
* Stop the timer - pauses countdown for both players
|
||||||
*/
|
*/
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (isRunning) {
|
if (isRunning) {
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
updateTime(); // Update one last time
|
updateTime(); // Update one last time before stopping
|
||||||
|
|
||||||
|
// Clean up the timer resources
|
||||||
if (timer != null) {
|
if (timer != null) {
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
timer = null;
|
timer = null;
|
||||||
|
|
@ -72,56 +80,65 @@ public class ChessTimer {
|
||||||
* @param initialTimeMinutes New initial time in minutes
|
* @param initialTimeMinutes New initial time in minutes
|
||||||
*/
|
*/
|
||||||
public void reset(int initialTimeMinutes) {
|
public void reset(int initialTimeMinutes) {
|
||||||
stop();
|
stop(); // Stop any running timer first
|
||||||
|
// Reset both clocks to the specified time
|
||||||
this.whiteTimeMillis = initialTimeMinutes * 60 * 1000;
|
this.whiteTimeMillis = initialTimeMinutes * 60 * 1000;
|
||||||
this.blackTimeMillis = initialTimeMinutes * 60 * 1000;
|
this.blackTimeMillis = initialTimeMinutes * 60 * 1000;
|
||||||
this.isWhiteTurn = true;
|
this.isWhiteTurn = true; // White starts again
|
||||||
notifyTimeUpdate();
|
notifyTimeUpdate(); // Update the UI with new times
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch the active player
|
* Switch the active player when a move is made
|
||||||
* @param isWhiteTurn True if it's now white's turn
|
* @param isWhiteTurn True if it's now white's turn
|
||||||
*/
|
*/
|
||||||
public void switchTurn(boolean isWhiteTurn) {
|
public void switchTurn(boolean isWhiteTurn) {
|
||||||
if (isRunning) {
|
if (isRunning) {
|
||||||
updateTime(); // Update time for the player who just completed their move
|
// Before changing turns, update the current player's elapsed time
|
||||||
|
updateTime();
|
||||||
}
|
}
|
||||||
|
// Switch to the other player's clock
|
||||||
this.isWhiteTurn = isWhiteTurn;
|
this.isWhiteTurn = isWhiteTurn;
|
||||||
notifyTimeUpdate();
|
notifyTimeUpdate(); // Update the UI with current times
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the time based on elapsed time
|
* Update the time based on elapsed time since last update
|
||||||
*/
|
*/
|
||||||
private void updateTime() {
|
private void updateTime() {
|
||||||
if (!isRunning) return;
|
if (!isRunning) return; // Don't update if timer is paused
|
||||||
|
|
||||||
|
// Calculate elapsed time since last update
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
long elapsedTime = currentTime - lastUpdateTime;
|
long elapsedTime = currentTime - lastUpdateTime;
|
||||||
lastUpdateTime = currentTime;
|
lastUpdateTime = currentTime; // Reset for next update
|
||||||
|
|
||||||
// Deduct time from the active player
|
// Deduct time from the active player's clock
|
||||||
if (isWhiteTurn) {
|
if (isWhiteTurn) {
|
||||||
|
// White's turn - deduct from white's clock
|
||||||
whiteTimeMillis -= elapsedTime;
|
whiteTimeMillis -= elapsedTime;
|
||||||
if (whiteTimeMillis <= 0) {
|
if (whiteTimeMillis <= 0) {
|
||||||
whiteTimeMillis = 0;
|
// White ran out of time
|
||||||
stop();
|
whiteTimeMillis = 0; // Don't go negative
|
||||||
|
stop(); // Stop the timer
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onTimeExpired(true);
|
listener.onTimeExpired(true); // Notify that white's time expired
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Black's turn - deduct from black's clock
|
||||||
blackTimeMillis -= elapsedTime;
|
blackTimeMillis -= elapsedTime;
|
||||||
if (blackTimeMillis <= 0) {
|
if (blackTimeMillis <= 0) {
|
||||||
blackTimeMillis = 0;
|
// Black ran out of time
|
||||||
stop();
|
blackTimeMillis = 0; // Don't go negative
|
||||||
|
stop(); // Stop the timer
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onTimeExpired(false);
|
listener.onTimeExpired(false); // Notify that black's time expired
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notify the UI to update displayed times
|
||||||
notifyTimeUpdate();
|
notifyTimeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,6 +147,7 @@ public class ChessTimer {
|
||||||
*/
|
*/
|
||||||
private void notifyTimeUpdate() {
|
private void notifyTimeUpdate() {
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
|
// Send current times to the UI
|
||||||
listener.onTimeUpdate(whiteTimeMillis, blackTimeMillis);
|
listener.onTimeUpdate(whiteTimeMillis, blackTimeMillis);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -149,11 +167,13 @@ public class ChessTimer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format milliseconds as "mm:ss"
|
* Format milliseconds as "mm:ss" for display
|
||||||
*/
|
*/
|
||||||
public static String formatTime(long timeMillis) {
|
public static String formatTime(long timeMillis) {
|
||||||
|
// Extract minutes and seconds from milliseconds
|
||||||
int seconds = (int) (timeMillis / 1000) % 60;
|
int seconds = (int) (timeMillis / 1000) % 60;
|
||||||
int minutes = (int) (timeMillis / (60 * 1000));
|
int minutes = (int) (timeMillis / (60 * 1000));
|
||||||
|
// Format as two digits for minutes and seconds
|
||||||
return String.format("%02d:%02d", minutes, seconds);
|
return String.format("%02d:%02d", minutes, seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue