From cf3c9ef0ba76f1d2a3b6a0a2e5f273c9153a321f Mon Sep 17 00:00:00 2001 From: Romain Murphy Date: Wed, 7 May 2025 20:49:46 +0200 Subject: [PATCH] timer added --- OOP_2B1_Project/src/backend/Board.java | 12 +++- OOP_2B1_Project/src/backend/Game.java | 34 ++++++---- .../src/windowInterface/MyInterface.java | 31 +++++++-- .../src/windowInterface/TimerManager.java | 68 +++++++++++++++++++ 4 files changed, 122 insertions(+), 23 deletions(-) create mode 100644 OOP_2B1_Project/src/windowInterface/TimerManager.java diff --git a/OOP_2B1_Project/src/backend/Board.java b/OOP_2B1_Project/src/backend/Board.java index 5cecb07..d41aaaa 100644 --- a/OOP_2B1_Project/src/backend/Board.java +++ b/OOP_2B1_Project/src/backend/Board.java @@ -19,6 +19,7 @@ public class Board { private Move lastMove; // new field private ArrayList> possibleMoves = new ArrayList<>(); private LinkedList boardHistory = new LinkedList<>(); + public boolean timerSwitch = false; public Board(int colNum, int lineNum) { this.width = colNum; @@ -225,7 +226,7 @@ public class Board { if (isHighlighted(x,y)) { this.movePiece(x, y); select = false; - + timerSwitch = true; this.turnColor = !this.turnColor; if(!this.turnColor) { @@ -398,6 +399,15 @@ public class Board { return lastMove; } + public boolean isTimerSwitch() { + return timerSwitch; + } + + public void setTimerSwitch(boolean timerSwitch) { + this.timerSwitch = timerSwitch; + } + + } ///// diff --git a/OOP_2B1_Project/src/backend/Game.java b/OOP_2B1_Project/src/backend/Game.java index be2e4d9..0283312 100644 --- a/OOP_2B1_Project/src/backend/Game.java +++ b/OOP_2B1_Project/src/backend/Game.java @@ -6,7 +6,7 @@ public class Game extends Thread { private AutoPlayer aiPlayer; private Board board; - private MyInterface mjf; + public MyInterface mjf; private int COL_NUM = 8; private int LINE_NUM = 8; private int loopDelay = 250; @@ -41,7 +41,7 @@ public class Game extends Thread { } } } - + private boolean isAITurn() { return activationAIFlags[board.isTurnWhite()?1:0]; } @@ -53,6 +53,7 @@ public class Game extends Thread { } else { board.playMove(aiPlayer.computeBestMove(board.getBoard(),board.isTurnWhite(),board.getLastMove())); + mjf.timerManager.switchTurn(); } } } @@ -67,13 +68,16 @@ public class Game extends Thread { if(!isAITurn()) { if (aiPlayer.getAllLegalMoves(board.getBoard(), board.isTurnWhite(),board.getLastMove()).size() != 0){ board.userTouch(x, y); - } - else { - mjf.showGameOverMessage("Game Over"); - } - + } + else { + mjf.showGameOverMessage("Game Over"); + } + if (board.isTimerSwitch()) { + mjf.timerManager.switchTurn(); + board.setTimerSwitch(false); + } } - + } public void setPiece(int x, int y, PieceType type, boolean isWhite) { @@ -100,11 +104,11 @@ public class Game extends Thread { public Iterable getPieces() { return board.getPieces(); } - + public boolean isCheck(int x, int y) { return board.isCheck(x, y); } - + public boolean isSelected(int x, int y) { return board.isSelected(x, y); } @@ -118,25 +122,25 @@ public class Game extends Thread { } public void toggleAI(boolean isWhite) { -// System.out.println(isWhite); + // System.out.println(isWhite); this.activationAIFlags[isWhite?1:0] = !this.activationAIFlags[isWhite?1:0]; if (this.activationAIFlags[isWhite?1:0]) { soundEffect.aiSound(); } } - + public void setTurnNumber(int turnNumber) { board.setTurnNumber(turnNumber); } - + public void setTurnColor(boolean turnColor) { board.setTurnColor(turnColor); } - + public int getTurnNumber() { return board.getTurnNumber(); } - + public boolean getTurnColor() { return board.isTurnColor(); } diff --git a/OOP_2B1_Project/src/windowInterface/MyInterface.java b/OOP_2B1_Project/src/windowInterface/MyInterface.java index 349ba00..527b33c 100644 --- a/OOP_2B1_Project/src/windowInterface/MyInterface.java +++ b/OOP_2B1_Project/src/windowInterface/MyInterface.java @@ -32,6 +32,7 @@ import javax.swing.JToggleButton; import javax.swing.JRadioButton; import javax.swing.JCheckBox; + public class MyInterface extends JFrame { private static final long serialVersionUID = -6840815447618468846L; @@ -44,7 +45,9 @@ public class MyInterface extends JFrame { private JLabel actionLabel; private JCheckBox chckbxBlackAI; private JCheckBox chckbxWhiteAI; - + private JLabel whiteTimerLabel; + private JLabel blackTimerLabel; + public TimerManager timerManager; /** * Create the frame. */ @@ -138,6 +141,11 @@ public class MyInterface extends JFrame { panelDraw = new JPanelChessBoard(this); contentPane.add(panelDraw, BorderLayout.CENTER); + + whiteTimerLabel = new JLabel("White: X"); + blackTimerLabel = new JLabel("Black: X"); + panelTop.add(whiteTimerLabel); + panelTop.add(blackTimerLabel); } public void setStepBanner(String s) { @@ -163,9 +171,13 @@ public class MyInterface extends JFrame { public void clicButtonStart() { this.instantiateSimu(); int depth = askDifficulty(); - int time=askTime(); + int time = askTime(); game.setAutoPlayerDepth(depth); game.setDefaultSetup(); + if (timerManager == null) + timerManager = new TimerManager(whiteTimerLabel, blackTimerLabel, () -> gameOverByTimeout(), time); + timerManager.reset(); + timerManager.start(true); // white starts } public void clickButtonAdder() { @@ -317,11 +329,16 @@ public class MyInterface extends JFrame { ); switch (choice) { - case 0: return 1; // 1 min - case 1: return 2; // 2 min - case 2: return 3; // 5 min - case 3: return 4;// 10 min - default: return 4; // 10 min + case 0: return 60; // 1 min + case 1: return 120; // 2 min + case 2: return 300; // 5 min + case 3: return 600;// 10 min + default: return 600; // 10 min } } + + public void gameOverByTimeout() { + // disable board input, show message + JOptionPane.showMessageDialog(this, "Time's up! The game is over."); + } } diff --git a/OOP_2B1_Project/src/windowInterface/TimerManager.java b/OOP_2B1_Project/src/windowInterface/TimerManager.java new file mode 100644 index 0000000..bd2cab6 --- /dev/null +++ b/OOP_2B1_Project/src/windowInterface/TimerManager.java @@ -0,0 +1,68 @@ +package windowInterface; + +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.Timer; + +public class TimerManager { + private int whiteSeconds = 300; + private int blackSeconds = 300; + private boolean whiteTurn = true; + private Timer timer; + private Runnable onTimeout; + private JLabel whiteLabel; + private JLabel blackLabel; + + public TimerManager(JLabel whiteLabel, JLabel blackLabel, Runnable onTimeout, int time) { + this.whiteLabel = whiteLabel; + this.blackLabel = blackLabel; + this.onTimeout = onTimeout; + this.whiteSeconds = time; + this.blackSeconds = time; + + timer = new Timer(1000, e -> tick()); + } + + public void start(boolean whiteStarts) { + this.whiteTurn = whiteStarts; + timer.start(); + } + + public void switchTurn() { + whiteTurn = !whiteTurn; + } + + private void tick() { + if (whiteTurn) { + whiteSeconds--; + updateLabel(whiteLabel, whiteSeconds); + if (whiteSeconds <= 0) timeout("White"); + } else { + blackSeconds--; + updateLabel(blackLabel, blackSeconds); + if (blackSeconds <= 0) timeout("Black"); + } + } + + private void updateLabel(JLabel label, int seconds) { + int mins = seconds / 60; + int secs = seconds % 60; + label.setText(String.format("%s: %02d:%02d", label == whiteLabel ? "White" : "Black", mins, secs)); + } + + private void timeout(String player) { + timer.stop(); + onTimeout.run(); // you define what happens on timeout + JOptionPane.showMessageDialog(null, player + " ran out of time! Game over."); + } + + public void stop() { + timer.stop(); + } + +public void reset() { + updateLabel(whiteLabel, whiteSeconds); + updateLabel(blackLabel, blackSeconds); + } + +} \ No newline at end of file