The fact is that when you plan a task, this task is performed in another thread, as you could use it to change the course of a player who is working in another thread, without checking variables throughout the execution, in order to know when the callback function is called.
I also added sample code.
public class CustomTimerTask extends TimerTask { private ServerGameManager gameManager; public CustomTimerTask(ServerGameManager gameManager){ this.gameManager= gameManager; } @Override public void run() { gameManager.changeTurn(); }}
This is my custom Timer class that will call the gameManager method, but this method does not stop the game loop in order to pass the move to another player.
private void playGame() { while (true) { try { int turnDelay = 1000; int turnSeconds = 30; java.util.Timer timer = new java.util.Timer(); timer.scheduleAtFixedRate(new CustomTimerTask(this), 0, turnDelay); try { // Send player turn color to clients //ToDo change method to return to start whenever the update method is called toPlayerOne.writeObject(turn); toPlayerTwo.writeObject(turn); // Get turn from client. if (playerOne.getColor() == turn) { move = (Move) fromPlayerOne.readObject(); move.setStart(9 - move.getStart().x, 9 - move.getStart().y); move.setEnd(9 - move.getEnd().x, 9 - move.getEnd().y); } else { move = (Move) fromPlayerTwo.readObject(); } Move moveToPlayerOne = new Move(), moveToPlayerTwo = new Move(); // Register move on the board. // If there is no piece at the end (normal move, no attack) if (board.getSquare(move.getEnd().x, move.getEnd().y).getPiece() == null) { Piece piece = board.getSquare(move.getStart().x, move.getStart().y).getPiece(); board.getSquare(move.getStart().x, move.getStart().y).setPiece(null); board.getSquare(move.getEnd().x, move.getEnd().y).setPiece(piece); // Rotate the move 180 degrees before sending. moveToPlayerOne.setStart(new Point(9 - move.getStart().x, 9 - move.getStart().y)); moveToPlayerOne.setEnd(new Point(9 - move.getEnd().x, 9 - move.getEnd().y)); moveToPlayerOne.setMoveColor(move.getMoveColor()); moveToPlayerOne.setStartPiece(null); moveToPlayerOne.setEndPiece(piece); moveToPlayerTwo.setStart(new Point(move.getStart().x, move.getStart().y)); moveToPlayerTwo.setEnd(new Point(move.getEnd().x, move.getEnd().y)); moveToPlayerTwo.setMoveColor(move.getMoveColor()); moveToPlayerTwo.setStartPiece(null); moveToPlayerTwo.setEndPiece(piece); } else { Piece attackingPiece = board.getSquare(move.getStart().x, move.getStart().y).getPiece(); Piece defendingPiece = board.getSquare(move.getEnd().x, move.getEnd().y).getPiece(); BattleOutcome outcome = attackingPiece.getPieceType().attack(defendingPiece.getPieceType()); moveToPlayerOne.setAttackMove(true); moveToPlayerTwo.setAttackMove(true); if (outcome == BattleOutcome.WIN) { board.getSquare(move.getEnd().x, move.getEnd().y).setPiece(board.getSquare(move.getStart().x, move.getStart().y).getPiece()); board.getSquare(move.getStart().x, move.getStart().y).setPiece(null); // Rotate the move 180 degrees before sending. moveToPlayerOne.setStart(new Point(9 - move.getStart().x, 9 - move.getStart().y)); moveToPlayerOne.setEnd(new Point(9 - move.getEnd().x, 9 - move.getEnd().y)); moveToPlayerOne.setMoveColor(move.getMoveColor()); moveToPlayerOne.setStartPiece(null); moveToPlayerOne.setEndPiece(attackingPiece); moveToPlayerOne.setAttackWin(true); moveToPlayerOne.setDefendWin(false); moveToPlayerTwo.setStart(new Point(move.getStart().x, move.getStart().y)); moveToPlayerTwo.setEnd(new Point(move.getEnd().x, move.getEnd().y)); moveToPlayerTwo.setMoveColor(move.getMoveColor()); moveToPlayerTwo.setStartPiece(null); moveToPlayerTwo.setEndPiece(attackingPiece); moveToPlayerTwo.setAttackWin(true); moveToPlayerTwo.setDefendWin(false); } else if (outcome == BattleOutcome.LOSE) { board.getSquare(move.getStart().x, move.getStart().y).setPiece(null); // Rotate the move 180 degrees before sending. moveToPlayerOne.setStart(new Point(9 - move.getStart().x, 9 - move.getStart().y)); moveToPlayerOne.setEnd(new Point(9 - move.getEnd().x, 9 - move.getEnd().y)); moveToPlayerOne.setMoveColor(move.getMoveColor()); moveToPlayerOne.setStartPiece(null); moveToPlayerOne.setEndPiece(defendingPiece); moveToPlayerOne.setAttackWin(false); moveToPlayerOne.setDefendWin(true); moveToPlayerTwo.setStart(new Point(move.getStart().x, move.getStart().y)); moveToPlayerTwo.setEnd(new Point(move.getEnd().x, move.getEnd().y)); moveToPlayerTwo.setMoveColor(move.getMoveColor()); moveToPlayerTwo.setStartPiece(null); moveToPlayerTwo.setEndPiece(defendingPiece); moveToPlayerTwo.setAttackWin(false); moveToPlayerTwo.setDefendWin(true); } else if (outcome == BattleOutcome.DRAW) { board.getSquare(move.getStart().x, move.getStart().y).setPiece(null); board.getSquare(move.getEnd().x, move.getEnd().y).setPiece(null); // Rotate the move 180 degrees before sending. moveToPlayerOne.setStart(new Point(9 - move.getStart().x, 9 - move.getStart().y)); moveToPlayerOne.setEnd(new Point(9 - move.getEnd().x, 9 - move.getEnd().y)); moveToPlayerOne.setMoveColor(move.getMoveColor()); moveToPlayerOne.setStartPiece(null); moveToPlayerOne.setEndPiece(null); moveToPlayerOne.setAttackWin(false); moveToPlayerOne.setDefendWin(false); moveToPlayerTwo.setStart(new Point(move.getStart().x, move.getStart().y)); moveToPlayerTwo.setEnd(new Point(move.getEnd().x, move.getEnd().y)); moveToPlayerTwo.setMoveColor(move.getMoveColor()); moveToPlayerTwo.setStartPiece(null); moveToPlayerTwo.setEndPiece(null); moveToPlayerTwo.setAttackWin(false); moveToPlayerTwo.setDefendWin(false); } } GameStatus winCondition = checkWinCondition(); toPlayerOne.writeObject(moveToPlayerOne); toPlayerTwo.writeObject(moveToPlayerTwo); toPlayerOne.writeObject(winCondition); toPlayerTwo.writeObject(winCondition); // Change turn color. //ToDo use this change colors in a daemon that has a timer, this daemon should be located in the client and notify the server whenever the turn has changed if (turn == PieceColor.RED) turn = PieceColor.BLUE; else turn = PieceColor.RED; // Check win conditions. } catch (IOException | ClassNotFoundException e) { System.out.println(session + "Error occured during network I/O"); return; } } catch (Exception e) { System.out.println("CATCH"); if (turn == PieceColor.RED) turn = PieceColor.BLUE; else turn = PieceColor.RED; } } }
This is a game loop that always runs (I know I must add a condition to stop the game if the game is paused)
The problem is that make the changeTurn() method to stop the game loop during its execution.
The first method that comes to my mind is to use exceptions, but this will not work, since they are two separate threads, so the exception stops at CustomTimerTask.