From 2936cc0b7227fba8e728bb0ae86c80787b28a3b9 Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 27 Nov 2025 16:58:47 +0100 Subject: [PATCH] Revert "readd previous game thread code" This reverts commit d24feef73e0ba05357776d24e2a607d8be4aa849. --- app/src/main/java/org/toop/app/Server.java | 12 +- .../java/org/toop/app/game/Connect4Game.java | 266 -------------- .../java/org/toop/app/game/ReversiGame.java | 341 ------------------ .../java/org/toop/app/game/TicTacToeGame.java | 250 ------------- .../app/widget/view/LocalMultiplayerView.java | 19 +- 5 files changed, 16 insertions(+), 872 deletions(-) delete mode 100644 app/src/main/java/org/toop/app/game/Connect4Game.java delete mode 100644 app/src/main/java/org/toop/app/game/ReversiGame.java delete mode 100644 app/src/main/java/org/toop/app/game/TicTacToeGame.java diff --git a/app/src/main/java/org/toop/app/Server.java b/app/src/main/java/org/toop/app/Server.java index 00f91cc..9df2e2d 100644 --- a/app/src/main/java/org/toop/app/Server.java +++ b/app/src/main/java/org/toop/app/Server.java @@ -1,8 +1,8 @@ package org.toop.app; -import org.toop.app.game.Connect4Game; -import org.toop.app.game.ReversiGame; -import org.toop.app.game.TicTacToeGame; +import org.toop.app.game.Connect4GameThread; +import org.toop.app.game.ReversiGameThread; +import org.toop.app.game.TicTacToeGameThread; import org.toop.app.widget.WidgetContainer; import org.toop.app.widget.popup.ChallengePopup; import org.toop.app.widget.popup.ErrorPopup; @@ -131,11 +131,11 @@ public final class Server { switch (type) { case TICTACTOE -> - new TicTacToeGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable); + new TicTacToeGameThread(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable); case REVERSI -> - new ReversiGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable); + new ReversiGameThread(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable); case CONNECT4 -> - new Connect4Game(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable); + new Connect4GameThread(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable); default -> new ErrorPopup("Unsupported game type."); } } diff --git a/app/src/main/java/org/toop/app/game/Connect4Game.java b/app/src/main/java/org/toop/app/game/Connect4Game.java deleted file mode 100644 index 9fe006d..0000000 --- a/app/src/main/java/org/toop/app/game/Connect4Game.java +++ /dev/null @@ -1,266 +0,0 @@ -package org.toop.app.game; - -import javafx.geometry.Pos; -import javafx.scene.paint.Color; -import org.toop.app.App; -import org.toop.app.GameInformation; -import org.toop.app.canvas.Connect4Canvas; -import org.toop.app.widget.WidgetContainer; -import org.toop.app.widget.view.GameView; -import org.toop.framework.eventbus.EventFlow; -import org.toop.framework.networking.events.NetworkEvents; -import org.toop.game.Connect4.Connect4; -import org.toop.game.Connect4.Connect4AI; -import org.toop.game.enumerators.GameState; -import org.toop.game.records.Move; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; - -public class Connect4Game { - private final GameInformation information; - - private final int myTurn; - private Runnable onGameOver; - private final BlockingQueue moveQueue; - - private final Connect4 game; - private final Connect4AI ai; - private final int columnSize = 7; - private final int rowSize = 6; - - private final GameView primary; - private final Connect4Canvas canvas; - - private final AtomicBoolean isRunning; - - public Connect4Game(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer onMessage, Runnable onGameOver) { - this.information = information; - this.myTurn = myTurn; - this.onGameOver = onGameOver; - moveQueue = new LinkedBlockingQueue(); - - - game = new Connect4(); - ai = new Connect4AI(); - - isRunning = new AtomicBoolean(true); - - if (onForfeit == null || onExit == null) { - primary = new GameView(null, () -> { - isRunning.set(false); - WidgetContainer.getCurrentView().transitionPrevious(); - }, null); - } else { - primary = new GameView(onForfeit, () -> { - isRunning.set(false); - onExit.run(); - }, onMessage); - } - - canvas = new Connect4Canvas(Color.GRAY, - (App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3, - (cell) -> { - if (onForfeit == null || onExit == null) { - if (information.players[game.getCurrentTurn()].isHuman) { - final char value = game.getCurrentTurn() == 0? 'X' : 'O'; - - try { - moveQueue.put(new Move(cell%columnSize, value)); - } catch (InterruptedException _) {} - } - } else { - if (information.players[0].isHuman) { - final char value = myTurn == 0? 'X' : 'O'; - - try { - moveQueue.put(new Move(cell%columnSize, value)); - } catch (InterruptedException _) {} - } - } - }); - - primary.add(Pos.CENTER, canvas.getCanvas()); - WidgetContainer.getCurrentView().transitionNext(primary); - - if (onForfeit == null || onExit == null) { - new Thread(this::localGameThread).start(); - setGameLabels(information.players[0].isHuman); - } else { - new EventFlow() - .listen(NetworkEvents.GameMoveResponse.class, this::onMoveResponse) - .listen(NetworkEvents.YourTurnResponse.class, this::onYourTurnResponse); - - setGameLabels(myTurn == 0); - } - - updateCanvas(); - } - - public Connect4Game(GameInformation information) { - this(information, 0, null, null, null, null); - } - private void localGameThread() { - while (isRunning.get()) { - final int currentTurn = game.getCurrentTurn(); - final String currentValue = currentTurn == 0? "RED" : "BLUE"; - final int nextTurn = (currentTurn + 1) % information.type.getPlayerCount(); - - primary.nextPlayer(information.players[currentTurn].isHuman, - information.players[currentTurn].name, - currentValue, - information.players[nextTurn].name); - - Move move = null; - - if (information.players[currentTurn].isHuman) { - try { - final Move wants = moveQueue.take(); - final Move[] legalMoves = game.getLegalMoves(); - - for (final Move legalMove : legalMoves) { - if (legalMove.position() == wants.position() && - legalMove.value() == wants.value()) { - move = wants; - break; - } - } - } catch (InterruptedException _) {} - } else { - final long start = System.currentTimeMillis(); - - move = ai.findBestMove(game, information.players[currentTurn].computerDifficulty); - - if (information.players[currentTurn].computerThinkTime > 0) { - final long elapsedTime = System.currentTimeMillis() - start; - final long sleepTime = Math.abs(information.players[currentTurn].computerThinkTime * 1000L - elapsedTime); - - try { - Thread.sleep((long)(sleepTime * Math.random())); - } catch (InterruptedException _) {} - } - } - - if (move == null) { - continue; - } - - final GameState state = game.play(move); - updateCanvas(); -/* - if (move.value() == 'X') { - canvas.drawX(Color.INDIANRED, move.position()); - } else if (move.value() == 'O') { - canvas.drawO(Color.ROYALBLUE, move.position()); - } -*/ - if (state != GameState.NORMAL) { - if (state == GameState.WIN) { - primary.gameOver(true, information.players[currentTurn].name); - } else if (state == GameState.DRAW) { - primary.gameOver(false, ""); - } - - isRunning.set(false); - } - } - } - - private void onMoveResponse(NetworkEvents.GameMoveResponse response) { - if (!isRunning.get()) { - return; - } - - char playerChar; - - if (response.player().equalsIgnoreCase(information.players[0].name)) { - playerChar = myTurn == 0? 'X' : 'O'; - } else { - playerChar = myTurn == 0? 'O' : 'X'; - } - - final Move move = new Move(Integer.parseInt(response.move()), playerChar); - final GameState state = game.play(move); - - if (state != GameState.NORMAL) { - if (state == GameState.WIN) { - if (response.player().equalsIgnoreCase(information.players[0].name)) { - primary.gameOver(true, information.players[0].name); - gameOver(); - } else { - primary.gameOver(false, information.players[1].name); - gameOver(); - } - } else if (state == GameState.DRAW) { - primary.gameOver(false, ""); - gameOver(); - } - } - - if (move.value() == 'X') { - canvas.drawDot(Color.INDIANRED, move.position()); - } else if (move.value() == 'O') { - canvas.drawDot(Color.ROYALBLUE, move.position()); - } - - updateCanvas(); - setGameLabels(game.getCurrentTurn() == myTurn); - } - - private void gameOver() { - if (onGameOver == null){ - return; - } - isRunning.set(false); - onGameOver.run(); - } - - private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) { - - if (!isRunning.get()) { - return; - } - - moveQueue.clear(); - - int position = -1; - - if (information.players[0].isHuman) { - try { - position = moveQueue.take().position(); - } catch (InterruptedException _) {} - } else { - final Move move = ai.findBestMove(game, information.players[0].computerDifficulty); - - assert move != null; - position = move.position(); - } - - new EventFlow().addPostEvent(new NetworkEvents.SendMove(response.clientId(), (short)position)) - .postEvent(); - } - - private void updateCanvas() { - canvas.clearAll(); - - for (int i = 0; i < game.getBoard().length; i++) { - if (game.getBoard()[i] == 'X') { - canvas.drawDot(Color.RED, i); - } else if (game.getBoard()[i] == 'O') { - canvas.drawDot(Color.BLUE, i); - } - } - } - - private void setGameLabels(boolean isMe) { - final int currentTurn = game.getCurrentTurn(); - final String currentValue = currentTurn == 0? "RED" : "BLUE"; - - primary.nextPlayer(isMe, - information.players[isMe? 0 : 1].name, - currentValue, - information.players[isMe? 1 : 0].name); - } -} \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/game/ReversiGame.java b/app/src/main/java/org/toop/app/game/ReversiGame.java deleted file mode 100644 index fb0e69e..0000000 --- a/app/src/main/java/org/toop/app/game/ReversiGame.java +++ /dev/null @@ -1,341 +0,0 @@ -package org.toop.app.game; - -import javafx.animation.SequentialTransition; -import org.toop.app.App; -import org.toop.app.GameInformation; -import org.toop.app.canvas.ReversiCanvas; -import org.toop.app.widget.WidgetContainer; -import org.toop.app.widget.view.GameView; -import org.toop.framework.eventbus.EventFlow; -import org.toop.framework.networking.events.NetworkEvents; -import org.toop.game.enumerators.GameState; -import org.toop.game.records.Move; -import org.toop.game.reversi.Reversi; -import org.toop.game.reversi.ReversiAI; - -import javafx.geometry.Pos; -import javafx.scene.paint.Color; - -import java.awt.*; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; - -public final class ReversiGame { - private final GameInformation information; - - private final int myTurn; - private Runnable onGameOver; - private final BlockingQueue moveQueue; - - private final Reversi game; - private final ReversiAI ai; - - private final GameView primary; - private final ReversiCanvas canvas; - - private final AtomicBoolean isRunning; - private final AtomicBoolean isPaused; - - public ReversiGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer onMessage, Runnable onGameOver) { - this.information = information; - - this.myTurn = myTurn; - this.onGameOver = onGameOver; - moveQueue = new LinkedBlockingQueue(); - - game = new Reversi(); - ai = new ReversiAI(); - - isRunning = new AtomicBoolean(true); - isPaused = new AtomicBoolean(false); - - if (onForfeit == null || onExit == null) { - primary = new GameView(null, () -> { - isRunning.set(false); - WidgetContainer.getCurrentView().transitionPrevious(); - }, null); - } else { - primary = new GameView(onForfeit, () -> { - isRunning.set(false); - onExit.run(); - }, onMessage); - } - - canvas = new ReversiCanvas(Color.BLACK, - (App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3, - (cell) -> { - if (onForfeit == null || onExit == null) { - if (information.players[game.getCurrentTurn()].isHuman) { - final char value = game.getCurrentTurn() == 0 ? 'B' : 'W'; - - try { - moveQueue.put(new Move(cell, value)); - } catch (InterruptedException _) { - } - } - } else { - if (information.players[0].isHuman) { - final char value = myTurn == 0 ? 'B' : 'W'; - - try { - moveQueue.put(new Move(cell, value)); - } catch (InterruptedException _) { - } - } - } - }); - - canvas.setOnCellEntered(this::highlightCells); - - primary.add(Pos.CENTER, canvas.getCanvas()); - WidgetContainer.getCurrentView().transitionNext(primary); - - if (onForfeit == null || onExit == null) { - new Thread(this::localGameThread).start(); - setGameLabels(information.players[0].isHuman); - } else { - new EventFlow() - .listen(NetworkEvents.GameMoveResponse.class, this::onMoveResponse) - .listen(NetworkEvents.YourTurnResponse.class, this::onYourTurnResponse); - - setGameLabels(myTurn == 0); - } - - updateCanvas(false); - } - - public ReversiGame(GameInformation information) { - this(information, 0, null, null, null, null); - } - - private void localGameThread() { - while (isRunning.get()) { - if (isPaused.get()) { - try { - Thread.sleep(200); - } catch (InterruptedException _) { - } - - continue; - } - - final int currentTurn = game.getCurrentTurn(); - final String currentValue = currentTurn == 0 ? "BLACK" : "WHITE"; - final int nextTurn = (currentTurn + 1) % information.type.getPlayerCount(); - - primary.nextPlayer(information.players[currentTurn].isHuman, - information.players[currentTurn].name, - currentValue, - information.players[nextTurn].name); - - Move move = null; - - if (information.players[currentTurn].isHuman) { - try { - final Move wants = moveQueue.take(); - final Move[] legalMoves = game.getLegalMoves(); - - for (final Move legalMove : legalMoves) { - if (legalMove.position() == wants.position() && - legalMove.value() == wants.value()) { - move = wants; - break; - } - } - } catch (InterruptedException _) { - } - } else { - final long start = System.currentTimeMillis(); - - move = ai.findBestMove(game, information.players[currentTurn].computerDifficulty); - - if (information.players[currentTurn].computerThinkTime > 0) { - final long elapsedTime = System.currentTimeMillis() - start; - final long sleepTime = information.players[currentTurn].computerThinkTime * 1000L - elapsedTime; - - try { - Thread.sleep((long) (sleepTime * Math.random())); - } catch (InterruptedException _) { - } - } - } - - if (move == null) { - continue; - } - - canvas.setCurrentlyHighlightedMovesNull(); - final GameState state = game.play(move); - updateCanvas(true); - - if (state != GameState.NORMAL) { - if (state == GameState.TURN_SKIPPED) { - continue; - } - int winningPLayerNumber = getPlayerNumberWithHighestScore(); - if (state == GameState.WIN && winningPLayerNumber > -1) { - primary.gameOver(true, information.players[winningPLayerNumber].name); - } else if (state == GameState.DRAW || winningPLayerNumber == -1) { - primary.gameOver(false, ""); - } - - isRunning.set(false); - } - } - } - - private int getPlayerNumberWithHighestScore() { - Reversi.Score score = game.getScore(); - if (score.player1Score() > score.player2Score()) return 0; - if (score.player1Score() < score.player2Score()) return 1; - return -1; - } - - private void onMoveResponse(NetworkEvents.GameMoveResponse response) { - if (!isRunning.get()) { - return; - } - - char playerChar; - - if (response.player().equalsIgnoreCase(information.players[0].name)) { - playerChar = myTurn == 0 ? 'B' : 'W'; - } else { - playerChar = myTurn == 0 ? 'W' : 'B'; - } - - final Move move = new Move(Integer.parseInt(response.move()), playerChar); - final GameState state = game.play(move); - - if (state != GameState.NORMAL) { - if (state == GameState.WIN) { - if (response.player().equalsIgnoreCase(information.players[0].name)) { - primary.gameOver(true, information.players[0].name); - gameOver(); - } else { - primary.gameOver(false, information.players[1].name); - gameOver(); - } - } else if (state == GameState.DRAW) { - primary.gameOver(false, ""); - game.play(move); - } - } - - updateCanvas(false); - setGameLabels(game.getCurrentTurn() == myTurn); - } - - private void gameOver() { - if (onGameOver == null) { - return; - } - isRunning.set(false); - onGameOver.run(); - } - - private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) { - if (!isRunning.get()) { - return; - } - - moveQueue.clear(); - - int position = -1; - - if (information.players[0].isHuman) { - try { - position = moveQueue.take().position(); - } catch (InterruptedException _) { - } - } else { - final Move move = ai.findBestMove(game, information.players[0].computerDifficulty); - - assert move != null; - position = move.position(); - } - - new EventFlow().addPostEvent(new NetworkEvents.SendMove(response.clientId(), (short) position)) - .postEvent(); - } - - private void updateCanvas(boolean animate) { - // Todo: this is very inefficient. still very fast but if the grid is bigger it might cause issues. improve. - canvas.clearAll(); - - for (int i = 0; i < game.getBoard().length; i++) { - if (game.getBoard()[i] == 'B') { - canvas.drawDot(Color.BLACK, i); - } else if (game.getBoard()[i] == 'W') { - canvas.drawDot(Color.WHITE, i); - } - } - - final Move[] flipped = game.getMostRecentlyFlippedPieces(); - - final SequentialTransition animation = new SequentialTransition(); - isPaused.set(true); - - if (animate && flipped != null) { - for (final Move flip : flipped) { - canvas.clear(flip.position()); - - final Color from = flip.value() == 'W' ? Color.BLACK : Color.WHITE; - final Color to = flip.value() == 'W' ? Color.WHITE : Color.BLACK; - - canvas.drawDot(from, flip.position()); - - animation.getChildren().addFirst(canvas.flipDot(from, to, flip.position())); - } - } - - animation.setOnFinished(_ -> { - isPaused.set(false); - - if (information.players[game.getCurrentTurn()].isHuman) { - final Move[] legalMoves = game.getLegalMoves(); - - for (final Move legalMove : legalMoves) { - canvas.drawLegalPosition(legalMove.position(), game.getCurrentPlayer()); - } - } - }); - - animation.play(); - } - - private void setGameLabels(boolean isMe) { - final int currentTurn = game.getCurrentTurn(); - final String currentValue = currentTurn == 0 ? "BLACK" : "WHITE"; - - primary.nextPlayer(isMe, - information.players[isMe ? 0 : 1].name, - currentValue, - information.players[isMe ? 1 : 0].name); - } - - private void highlightCells(int cellEntered) { - if (information.players[game.getCurrentTurn()].isHuman) { - Move[] legalMoves = game.getLegalMoves(); - boolean isLegalMove = false; - for (Move move : legalMoves) { - if (move.position() == cellEntered) { - isLegalMove = true; - break; - } - } - - if (cellEntered >= 0) { - Move[] moves = null; - if (isLegalMove) { - moves = game.getFlipsForPotentialMove( - new Point(cellEntered % game.getColumnSize(), cellEntered / game.getRowSize()), - game.getCurrentPlayer()); - } - canvas.drawHighlightDots(moves); - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/game/TicTacToeGame.java b/app/src/main/java/org/toop/app/game/TicTacToeGame.java deleted file mode 100644 index f87b98f..0000000 --- a/app/src/main/java/org/toop/app/game/TicTacToeGame.java +++ /dev/null @@ -1,250 +0,0 @@ -package org.toop.app.game; - -import org.toop.app.App; -import org.toop.app.GameInformation; -import org.toop.app.canvas.TicTacToeCanvas; -import org.toop.app.widget.WidgetContainer; -import org.toop.app.widget.view.GameView; -import org.toop.framework.eventbus.EventFlow; -import org.toop.framework.networking.events.NetworkEvents; -import org.toop.game.enumerators.GameState; -import org.toop.game.records.Move; -import org.toop.game.tictactoe.TicTacToe; -import org.toop.game.tictactoe.TicTacToeAI; - -import javafx.geometry.Pos; -import javafx.scene.paint.Color; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; - -public final class TicTacToeGame { - private final GameInformation information; - - private final int myTurn; - private Runnable onGameOver; - private final BlockingQueue moveQueue; - - private final TicTacToe game; - private final TicTacToeAI ai; - - private final GameView primary; - private final TicTacToeCanvas canvas; - - private final AtomicBoolean isRunning; - - public TicTacToeGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer onMessage, Runnable onGameOver) { - this.information = information; - - this.myTurn = myTurn; - this.onGameOver = onGameOver; - moveQueue = new LinkedBlockingQueue(); - - game = new TicTacToe(); - ai = new TicTacToeAI(); - - isRunning = new AtomicBoolean(true); - - if (onForfeit == null || onExit == null) { - primary = new GameView(null, () -> { - isRunning.set(false); - WidgetContainer.getCurrentView().transitionPrevious(); - }, null); - } else { - primary = new GameView(onForfeit, () -> { - isRunning.set(false); - onExit.run(); - }, onMessage); - } - - canvas = new TicTacToeCanvas(Color.GRAY, - (App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3, - (cell) -> { - if (onForfeit == null || onExit == null) { - if (information.players[game.getCurrentTurn()].isHuman) { - final char value = game.getCurrentTurn() == 0? 'X' : 'O'; - - try { - moveQueue.put(new Move(cell, value)); - } catch (InterruptedException _) {} - } - } else { - if (information.players[0].isHuman) { - final char value = myTurn == 0? 'X' : 'O'; - - try { - moveQueue.put(new Move(cell, value)); - } catch (InterruptedException _) {} - } - } - }); - - primary.add(Pos.CENTER, canvas.getCanvas()); - WidgetContainer.getCurrentView().transitionNext(primary); - - if (onForfeit == null || onExit == null) { - new Thread(this::localGameThread).start(); - } else { - new EventFlow() - .listen(NetworkEvents.GameMoveResponse.class, this::onMoveResponse) - .listen(NetworkEvents.YourTurnResponse.class, this::onYourTurnResponse); - - setGameLabels(myTurn == 0); - } - } - - public TicTacToeGame(GameInformation information) { - this(information, 0, null, null, null, null); - } - - private void localGameThread() { - while (isRunning.get()) { - final int currentTurn = game.getCurrentTurn(); - final String currentValue = currentTurn == 0? "X" : "O"; - final int nextTurn = (currentTurn + 1) % information.type.getPlayerCount(); - - primary.nextPlayer(information.players[currentTurn].isHuman, - information.players[currentTurn].name, - currentValue, - information.players[nextTurn].name); - - Move move = null; - - if (information.players[currentTurn].isHuman) { - try { - final Move wants = moveQueue.take(); - final Move[] legalMoves = game.getLegalMoves(); - - for (final Move legalMove : legalMoves) { - if (legalMove.position() == wants.position() && - legalMove.value() == wants.value()) { - move = wants; - break; - } - } - } catch (InterruptedException _) {} - } else { - final long start = System.currentTimeMillis(); - - move = ai.findBestMove(game, information.players[currentTurn].computerDifficulty); - - if (information.players[currentTurn].computerThinkTime > 0) { - final long elapsedTime = System.currentTimeMillis() - start; - final long sleepTime = information.players[currentTurn].computerThinkTime * 1000L - elapsedTime; - - try { - Thread.sleep((long)(sleepTime * Math.random())); - } catch (InterruptedException _) {} - } - } - - if (move == null) { - continue; - } - - final GameState state = game.play(move); - - if (move.value() == 'X') { - canvas.drawX(Color.INDIANRED, move.position()); - } else if (move.value() == 'O') { - canvas.drawO(Color.ROYALBLUE, move.position()); - } - - if (state != GameState.NORMAL) { - if (state == GameState.WIN) { - primary.gameOver(true, information.players[currentTurn].name); - } else if (state == GameState.DRAW) { - primary.gameOver(false, ""); - } - - isRunning.set(false); - } - } - } - - private void onMoveResponse(NetworkEvents.GameMoveResponse response) { - if (!isRunning.get()) { - return; - } - - char playerChar; - - if (response.player().equalsIgnoreCase(information.players[0].name)) { - playerChar = myTurn == 0? 'X' : 'O'; - } else { - playerChar = myTurn == 0? 'O' : 'X'; - } - - final Move move = new Move(Integer.parseInt(response.move()), playerChar); - final GameState state = game.play(move); - - if (state != GameState.NORMAL) { - if (state == GameState.WIN) { - if (response.player().equalsIgnoreCase(information.players[0].name)) { - primary.gameOver(true, information.players[0].name); - gameOver(); - } else { - primary.gameOver(false, information.players[1].name); - gameOver(); - } - } else if (state == GameState.DRAW) { - if(game.getLegalMoves().length == 0) { //only return draw in online multiplayer if the game is actually over. - primary.gameOver(false, ""); - gameOver(); - } - } - } - - if (move.value() == 'X') { - canvas.drawX(Color.RED, move.position()); - } else if (move.value() == 'O') { - canvas.drawO(Color.BLUE, move.position()); - } - - setGameLabels(game.getCurrentTurn() == myTurn); - } - - private void gameOver() { - if (onGameOver == null){ - return; - } - isRunning.set(false); - onGameOver.run(); - } - - private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) { - if (!isRunning.get()) { - return; - } - - moveQueue.clear(); - - int position = -1; - - if (information.players[0].isHuman) { - try { - position = moveQueue.take().position(); - } catch (InterruptedException _) {} - } else { - final Move move; - move = ai.findBestMove(game, information.players[0].computerDifficulty); - assert move != null; - position = move.position(); - } - - new EventFlow().addPostEvent(new NetworkEvents.SendMove(response.clientId(), (short)position)) - .postEvent(); - } - - private void setGameLabels(boolean isMe) { - final int currentTurn = game.getCurrentTurn(); - final String currentValue = currentTurn == 0? "X" : "O"; - - primary.nextPlayer(isMe, - information.players[isMe? 0 : 1].name, - currentValue, - information.players[isMe? 1 : 0].name); - } -} \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/widget/view/LocalMultiplayerView.java b/app/src/main/java/org/toop/app/widget/view/LocalMultiplayerView.java index 614e9d4..6ff3fe7 100644 --- a/app/src/main/java/org/toop/app/widget/view/LocalMultiplayerView.java +++ b/app/src/main/java/org/toop/app/widget/view/LocalMultiplayerView.java @@ -1,18 +1,19 @@ package org.toop.app.widget.view; -import javafx.geometry.Pos; -import javafx.scene.control.ScrollPane; -import javafx.scene.layout.VBox; import org.toop.app.GameInformation; -import org.toop.app.game.Connect4Game; -import org.toop.app.game.ReversiGame; -import org.toop.app.game.TicTacToeGame; +import org.toop.app.game.Connect4GameThread; +import org.toop.app.game.ReversiGameThread; +import org.toop.app.game.TicTacToeGameThread; import org.toop.app.widget.Primitive; import org.toop.app.widget.complex.PlayerInfoWidget; import org.toop.app.widget.complex.ViewWidget; import org.toop.app.widget.popup.ErrorPopup; import org.toop.local.AppContext; +import javafx.geometry.Pos; +import javafx.scene.control.ScrollPane; +import javafx.scene.layout.VBox; + public class LocalMultiplayerView extends ViewWidget { private final GameInformation information; @@ -31,9 +32,9 @@ public class LocalMultiplayerView extends ViewWidget { } switch (information.type) { - case TICTACTOE -> new TicTacToeGame(information); - case REVERSI -> new ReversiGame(information); - case CONNECT4 -> new Connect4Game(information); + case TICTACTOE -> new TicTacToeGameThread(information); + case REVERSI -> new ReversiGameThread(information); + case CONNECT4 -> new Connect4GameThread(information); // case BATTLESHIP -> new BattleshipGame(information); } });