From 172b26ed51a669357efd5f7e772abe5a6a82a92c Mon Sep 17 00:00:00 2001 From: ramollia <@> Date: Tue, 7 Oct 2025 04:46:45 +0200 Subject: [PATCH] ... --- app/src/main/java/org/toop/Main.java | 2 +- .../java/org/toop/app/GameInformation.java | 3 +- .../toop/app/layer/layers/ConnectedLayer.java | 109 +++++++- .../app/layer/layers/MultiplayerLayer.java | 32 +-- .../layer/layers/game/GameFinishedPopup.java | 3 +- .../app/layer/layers/game/TicTacToeLayer.java | 260 ++++++++---------- .../main/java/org/toop/local/AppContext.java | 2 +- .../localization/localization_en.properties | 4 + 8 files changed, 243 insertions(+), 172 deletions(-) diff --git a/app/src/main/java/org/toop/Main.java b/app/src/main/java/org/toop/Main.java index a94799b..05a34a4 100644 --- a/app/src/main/java/org/toop/Main.java +++ b/app/src/main/java/org/toop/Main.java @@ -18,4 +18,4 @@ public final class Main { new Thread(NetworkingClientManager::new).start(); new Thread(SoundManager::new).start(); } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/GameInformation.java b/app/src/main/java/org/toop/app/GameInformation.java index e61a60b..fd7c56e 100644 --- a/app/src/main/java/org/toop/app/GameInformation.java +++ b/app/src/main/java/org/toop/app/GameInformation.java @@ -1,5 +1,6 @@ package org.toop.app; -public record GameInformation(String[] playerName, boolean[] isPlayerHuman, int[] computerDifficulty, int[] computerThinkTime, +public record GameInformation(String[] playerName, boolean[] isPlayerHuman, + int[] computerDifficulty, int[] computerThinkTime, boolean isConnectionLocal, String serverIP, String serverPort) { } diff --git a/app/src/main/java/org/toop/app/layer/layers/ConnectedLayer.java b/app/src/main/java/org/toop/app/layer/layers/ConnectedLayer.java index 01ae2f3..8873f4c 100644 --- a/app/src/main/java/org/toop/app/layer/layers/ConnectedLayer.java +++ b/app/src/main/java/org/toop/app/layer/layers/ConnectedLayer.java @@ -1,40 +1,114 @@ package org.toop.app.layer.layers; import javafx.application.Platform; +import org.toop.app.App; +import org.toop.app.GameInformation; import org.toop.app.layer.Container; import org.toop.app.layer.Layer; import org.toop.app.layer.NodeBuilder; +import org.toop.app.layer.Popup; +import org.toop.app.layer.containers.HorizontalContainer; import org.toop.app.layer.containers.VerticalContainer; +import org.toop.app.layer.layers.game.TicTacToeLayer; import org.toop.framework.eventbus.EventFlow; import org.toop.framework.networking.events.NetworkEvents; import javafx.geometry.Pos; import javafx.scene.control.Label; import javafx.scene.control.ListView; +import org.toop.local.AppContext; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicInteger; public final class ConnectedLayer extends Layer { + private static Timer pollTimer = new Timer(); + + private static class ChallengePopup extends Popup { + private final GameInformation information; + + private final String challenger; + private final String game; + + private final long clientID; + private final int challengeID; + + public ChallengePopup(GameInformation information, String challenger, String game, long clientID, String challengeID) { + super(false, "bg-popup"); + + this.information = information; + + this.challenger = challenger; + this.game = game; + + this.clientID = clientID; + this.challengeID = Integer.parseInt(challengeID.substring(18, challengeID.length() - 2)); + + reload(); + } + + @Override + public void reload() { + popAll(); + + final var challengeText = NodeBuilder.header(AppContext.getString("challengeText")); + final var challengerNameText = NodeBuilder.header(challenger); + + final var gameText = NodeBuilder.text(AppContext.getString("gameIsText")); + final var gameNameText = NodeBuilder.text(game); + + final var acceptButton = NodeBuilder.button(AppContext.getString("accept"), () -> { + pollTimer.cancel(); + + new EventFlow().addPostEvent(new NetworkEvents.SendAcceptChallenge(clientID, challengeID)).postEvent(); + App.activate(new TicTacToeLayer(information, clientID)); + }); + + final var denyButton = NodeBuilder.button(AppContext.getString("deny"), () -> { + App.pop(); + }); + + final Container controlContainer = new HorizontalContainer(30); + controlContainer.addNodes(acceptButton, denyButton); + + final Container mainContainer = new VerticalContainer(30); + mainContainer.addNodes(challengeText, challengerNameText); + mainContainer.addNodes(gameText, gameNameText); + + mainContainer.addContainer(controlContainer, false); + + addContainer(mainContainer, Pos.CENTER, 0, 0, 30, 30); + } + } + + GameInformation information; long clientId; String user; List onlinePlayers = new CopyOnWriteArrayList<>(); - public ConnectedLayer(long clientId, String user) { + public ConnectedLayer(GameInformation information) { super("bg-primary"); - this.clientId = clientId; - this.user = user; + this.information = information; + + new EventFlow() + .addPostEvent(NetworkEvents.StartClient.class, information.serverIP(), Integer.parseInt(information.serverPort())) + .onResponse(NetworkEvents.StartClientResponse.class, e -> { + clientId = e.clientId(); + user = information.playerName()[0].replaceAll("\\s+", ""); + + new EventFlow().addPostEvent(new NetworkEvents.SendLogin(this.clientId, this.user)).postEvent(); + + Thread popThread = new Thread(this::populatePlayerList); + popThread.setDaemon(false); + popThread.start(); + }).postEvent(); - new EventFlow().addPostEvent(new NetworkEvents.SendLogin(this.clientId, this.user)).postEvent(); new EventFlow().listen(this::handleReceivedChallenge); - Thread popThread = new Thread(this::populatePlayerList); - popThread.setDaemon(false); - popThread.start(); - reload(); } @@ -58,19 +132,32 @@ public final class ConnectedLayer extends Layer { } }; - Timer pollTimer = new Timer(); pollTimer.schedule(task, 0L, 5000L); // TODO: Block app exit, fix later } private void sendChallenge(String oppUsername, String gameType) { + final AtomicInteger challengeId = new AtomicInteger(-1); + if (onlinePlayers.contains(oppUsername)) { new EventFlow().addPostEvent(new NetworkEvents.SendChallenge(this.clientId, oppUsername, gameType)) - .postEvent(); + .listen(NetworkEvents.ChallengeResponse.class, e -> { + challengeId.set(Integer.parseInt(e.challengeId().substring(18, e.challengeId().length() - 2))); + }) + .listen(NetworkEvents.GameMatchResponse.class, e -> { + if (e.clientId() == this.clientId) { + pollTimer.cancel(); + App.activate(new TicTacToeLayer(information, this.clientId)); + } + }, false).postEvent(); + // ^ + // | + // | + // | } } private void handleReceivedChallenge(NetworkEvents.ChallengeResponse response) { - // TODO: Popup? Idk what this actually sends back. + App.push(new ChallengePopup(information, response.challengerName(), response.gameType(), clientId, response.challengeId())); } @Override diff --git a/app/src/main/java/org/toop/app/layer/layers/MultiplayerLayer.java b/app/src/main/java/org/toop/app/layer/layers/MultiplayerLayer.java index 099d495..f148377 100644 --- a/app/src/main/java/org/toop/app/layer/layers/MultiplayerLayer.java +++ b/app/src/main/java/org/toop/app/layer/layers/MultiplayerLayer.java @@ -1,7 +1,5 @@ package org.toop.app.layer.layers; -import javafx.application.Platform; -import javafx.geometry.Pos; import org.toop.app.App; import org.toop.app.GameInformation; import org.toop.app.layer.Container; @@ -10,10 +8,10 @@ import org.toop.app.layer.NodeBuilder; import org.toop.app.layer.containers.HorizontalContainer; import org.toop.app.layer.containers.VerticalContainer; import org.toop.app.layer.layers.game.TicTacToeLayer; -import org.toop.framework.eventbus.EventFlow; -import org.toop.framework.networking.events.NetworkEvents; import org.toop.local.AppContext; +import javafx.geometry.Pos; + import java.time.LocalDateTime; public final class MultiplayerLayer extends Layer { @@ -59,7 +57,7 @@ public final class MultiplayerLayer extends Layer { player1Container.addNodes(playerNameText, playerNameInput); } else { - player1Name = "Pism Bot #" + LocalDateTime.now().getSecond(); + player1Name = "Pism Bot V" + LocalDateTime.now().getSecond(); final var computerNameText = NodeBuilder.text(player1Name); final var computerNameSeparator = NodeBuilder.separator(); @@ -94,7 +92,7 @@ public final class MultiplayerLayer extends Layer { player2Container.addNodes(playerNameText, playerNameInput); } else { - player2Name = "Pism Bot #" + LocalDateTime.now().getSecond(); + player2Name = "Pism Bot V" + LocalDateTime.now().getSecond(); final var computerNameText = NodeBuilder.text(player2Name); final var computerNameSeparator = NodeBuilder.separator(); @@ -137,21 +135,17 @@ public final class MultiplayerLayer extends Layer { }); final var playButton = NodeBuilder.button(isConnectionLocal ? AppContext.getString("start") : AppContext.getString("connect"), () -> { + final var information = new GameInformation( + new String[]{player1Name, player2Name}, + new boolean[]{isPlayer1Human, isPlayer2Human}, + new int[]{computer1Difficulty, computer2Difficulty}, + new int[]{computer1ThinkTime, computer2ThinkTime}, + isConnectionLocal, serverIP, serverPort); + if (isConnectionLocal) { - App.activate(new TicTacToeLayer(new GameInformation( - new String[]{player1Name, player2Name}, - new boolean[]{isPlayer1Human, isPlayer2Human}, - new int[]{computer1Difficulty, computer2Difficulty}, - new int[]{computer1ThinkTime, computer2ThinkTime}, - isConnectionLocal, serverIP, serverPort))); + App.activate(new TicTacToeLayer(information)); } else { - new EventFlow() - .addPostEvent(NetworkEvents.StartClient.class, serverIP, Integer.parseInt(serverPort)) - .onResponse(NetworkEvents.StartClientResponse.class, - e -> Platform.runLater( - () -> App.activate(new ConnectedLayer(e.clientId(), player1Name)) - )) - .postEvent(); + App.activate(new ConnectedLayer(information)); } }); diff --git a/app/src/main/java/org/toop/app/layer/layers/game/GameFinishedPopup.java b/app/src/main/java/org/toop/app/layer/layers/game/GameFinishedPopup.java index b17f758..9d90699 100644 --- a/app/src/main/java/org/toop/app/layer/layers/game/GameFinishedPopup.java +++ b/app/src/main/java/org/toop/app/layer/layers/game/GameFinishedPopup.java @@ -1,6 +1,5 @@ package org.toop.app.layer.layers.game; -import javafx.geometry.Pos; import org.toop.app.App; import org.toop.app.layer.Container; import org.toop.app.layer.NodeBuilder; @@ -9,6 +8,8 @@ import org.toop.app.layer.containers.VerticalContainer; import org.toop.app.layer.layers.MainLayer; import org.toop.local.AppContext; +import javafx.geometry.Pos; + public class GameFinishedPopup extends Popup { private final boolean isDraw; private final String winner; diff --git a/app/src/main/java/org/toop/app/layer/layers/game/TicTacToeLayer.java b/app/src/main/java/org/toop/app/layer/layers/game/TicTacToeLayer.java index 554ffd6..0dafa37 100644 --- a/app/src/main/java/org/toop/app/layer/layers/game/TicTacToeLayer.java +++ b/app/src/main/java/org/toop/app/layer/layers/game/TicTacToeLayer.java @@ -20,15 +20,15 @@ import org.toop.local.AppContext; import javafx.geometry.Pos; import javafx.scene.paint.Color; -import java.time.Duration; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; public final class TicTacToeLayer extends Layer { private TicTacToeCanvas canvas; - private TicTacToe ticTacToe; + private AtomicReference ticTacToe; private TicTacToeAI ticTacToeAI; private GameInformation information; @@ -42,45 +42,34 @@ public final class TicTacToeLayer extends Layer { private char currentPlayerMove = Game.EMPTY; private String player2Name = ""; + final AtomicBoolean firstPlayerIsMe = new AtomicBoolean(true); + public TicTacToeLayer(GameInformation information) { super("bg-primary"); canvas = new TicTacToeCanvas(Color.LIME, (App.getHeight() / 100) * 75, (App.getHeight() / 100) * 75, (cell) -> { try { if (information.isConnectionLocal()) { - if (ticTacToe.getCurrentTurn() == 0) { + if (ticTacToe.get().getCurrentTurn() == 0) { playerMoveQueue.put(new Game.Move(cell, 'X')); } else { playerMoveQueue.put(new Game.Move(cell, 'O')); } } else { - if (information.isPlayerHuman()[0] && currentPlayerMove != Game.EMPTY) { - playerMoveQueue.put(new Game.Move(cell, currentPlayerMove)); - } + if (information.isPlayerHuman()[0] && currentPlayerMove != Game.EMPTY) { + playerMoveQueue.put(new Game.Move(cell, firstPlayerIsMe.get()? 'X' : 'O')); + } } - } catch (InterruptedException e) { - return; - } + } catch (InterruptedException _) {} }); - ticTacToe = new TicTacToe(); + ticTacToe = new AtomicReference<>(new TicTacToe()); ticTacToeAI = new TicTacToeAI(); this.information = information; if (information.isConnectionLocal()) { new Thread(this::localGameThread).start(); - } else { - new EventFlow() - .addPostEvent(NetworkEvents.StartClient.class, - information.serverIP(), - Integer.parseInt(information.serverPort())) - .onResponse(NetworkEvents.StartClientResponse.class, event -> { - Thread a = new Thread(() -> serverGameThread(event)); - a.setDaemon(false); - a.start(); - }) - .postEvent(); } currentPlayerNameText = NodeBuilder.header(""); @@ -89,14 +78,24 @@ public final class TicTacToeLayer extends Layer { reload(); } + public TicTacToeLayer(GameInformation information, long clientID) { + this(information); + + Thread a = new Thread(this::serverGameThread); + a.setDaemon(false); + a.start(); + + reload(); + } + @Override public void reload() { popAll(); canvas.resize((App.getHeight() / 100) * 75, (App.getHeight() / 100) * 75); - for (int i = 0; i < ticTacToe.board.length; i++) { - final char value = ticTacToe.board[i]; + for (int i = 0; i < ticTacToe.get().board.length; i++) { + final char value = ticTacToe.get().board[i]; if (value == 'X') { canvas.drawX(Color.RED, i); @@ -128,30 +127,28 @@ public final class TicTacToeLayer extends Layer { boolean running = true; while (running) { - final int currentPlayer = ticTacToe.getCurrentTurn(); + final int currentPlayer = ticTacToe.get().getCurrentTurn(); currentPlayerNameText.setText(information.playerName()[currentPlayer]); - currentPlayerMoveText.setText(ticTacToe.getCurrentTurn() == 0? "X" : "O"); + currentPlayerMoveText.setText(ticTacToe.get().getCurrentTurn() == 0? "X" : "O"); Game.Move move = null; if (information.isPlayerHuman()[currentPlayer]) { try { final Game.Move wants = playerMoveQueue.take(); - final Game.Move[] legalMoves = ticTacToe.getLegalMoves(); + final Game.Move[] legalMoves = ticTacToe.get().getLegalMoves(); for (final Game.Move legalMove : legalMoves) { if (legalMove.position() == wants.position() && legalMove.value() == wants.value()) { move = wants; } } - } catch (InterruptedException exception) { - return; - } + } catch (InterruptedException _) {} } else { final long start = System.currentTimeMillis(); - move = ticTacToeAI.findBestMove(ticTacToe, compurterDifficultyToDepth(10, + move = ticTacToeAI.findBestMove(ticTacToe.get(), compurterDifficultyToDepth(10, information.computerDifficulty()[currentPlayer])); if (information.computerThinkTime()[currentPlayer] > 0) { @@ -168,7 +165,7 @@ public final class TicTacToeLayer extends Layer { continue; } - final Game.State state = ticTacToe.play(move); + final Game.State state = ticTacToe.get().play(move); if (move.value() == 'X') { canvas.drawX(Color.RED, move.position()); @@ -178,7 +175,7 @@ public final class TicTacToeLayer extends Layer { if (state != Game.State.NORMAL) { if (state == Game.State.WIN) { - App.push(new GameFinishedPopup(false, information.playerName()[ticTacToe.getCurrentTurn()])); + App.push(new GameFinishedPopup(false, information.playerName()[ticTacToe.get().getCurrentTurn()])); } else if (state == Game.State.DRAW) { App.push(new GameFinishedPopup(true, "")); } @@ -188,125 +185,112 @@ public final class TicTacToeLayer extends Layer { } } - class OnlineGameState { - public long clientId = -1; - public long receivedMove = -1; - public boolean firstPlayerIsMe = true; + private void serverGameThread() { + new EventFlow() + .listen(this::handleServerGameStart) // <----------- + .listen(this::yourTurnResponse) + .listen(this::onMoveResponse) + .listen(this::handleReceivedMessage); } - AtomicBoolean firstPlayerIsMe = new AtomicBoolean(true); - AtomicBoolean gameHasStarted = new AtomicBoolean(false); - private void serverGameThread(NetworkEvents.StartClientResponse event) { - boolean running = true; - final long clientId = event.clientId(); - final OnlineGameState onlineGameState = new OnlineGameState(); - onlineGameState.clientId = clientId; - //new EventFlow() - // .listen(NetworkEvents.GameMoveResponse.class,respEvent -> onMoveResponse(onlineGameState, respEvent)); + private void handleServerGameStart(NetworkEvents.GameMatchResponse resp) { + // Meneer Bas de Jong. Dit functie wordt niet aangeroepen als je de challenger bent. + // Ik heb veel dingen geprobeert. FUCKING veel dingen. Hij doet het niet. + // Ik heb zelfs in jou code gekeken en unsubscribeAfterSuccess op false gezet. (zie ConnectedLayer). + // Alle andere functies worden wel gecalt. Behalve dit. - new EventFlow() - .listen(this::yourTurnResponse) - .listen(this::handleChallengeResponse) - .listen(this::handleServerGameStart) - .listen(this::handleReceivedMessage) - .listen(this::onMoveResponse); + // Ben jij gehandicapt of ik? Want het moet 1 van de 2 zijn. Ik ben dit al 2 uur aan het debuggen. + // Ik ga nu slapen (04:46). - while (running) { - try { - Thread.sleep(250); - } catch (InterruptedException exception) {} - boolean hasStarted = gameHasStarted.get(); - if (hasStarted) { - onlineGameState.firstPlayerIsMe = firstPlayerIsMe.get(); - if (onlineGameState.firstPlayerIsMe) { - currentPlayerMove = 'X'; - } - else { - currentPlayerMove = 'O'; - } - if(!information.isPlayerHuman()[0]){ - boolean myTurn = (onlineGameState.firstPlayerIsMe && ticTacToe.getCurrentTurn() % 2 == 0) - || (!onlineGameState.firstPlayerIsMe && ticTacToe.getCurrentTurn() % 2 == 1); - if (myTurn) { - Game.Move move; - move = ticTacToeAI.findBestMove(ticTacToe, compurterDifficultyToDepth(10, 10)); - new EventFlow().addPostEvent(new NetworkEvents.SendMove(clientId, (short) move.position())) - .postEvent(); - } - } - else { - try { - final Game.Move wants = playerMoveQueue.take(); - final Game.Move[] legalMoves = ticTacToe.getLegalMoves(); - for (final Game.Move legalMove : legalMoves) { - if (legalMove.position() == wants.position() && legalMove.value() == wants.value()) { - new EventFlow().addPostEvent(new NetworkEvents.SendMove(clientId, (short) wants.position())) - .postEvent(); - break; - } - } - } catch (InterruptedException exception) { - System.out.println(exception.getMessage()); - return; - } - } - } +// ⠀⠀⠀⠀⠀⠀⣀⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +// ⠀⠀⠀⢀⣴⣿⣿⠿⣟⢷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +// ⠀⠀⠀⢸⣏⡏⠀⠀⠀⢣⢻⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +// ⠀⠀⠀⢸⣟⠧⠤⠤⠔⠋⠀⢿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +// ⠀⠀⠀⠀⣿⡆⠀⠀⠀⠀⠀⠸⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +// ⠀⠀⠀⠀⠘⣿⡀⢀⣶⠤⠒⠀⢻⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +// ⠀⠀⠀⠀⠀⢹⣧⠀⠀⠀⠀⠀⠈⢿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +// ⠀⠀⠀⠀⠀⠀⣿⡆⠀⠀⠀⠀⠀⠈⢿⣆⣠⣤⣤⣤⣤⣴⣦⣄⡀⠀⠀⠀⠀⠀⠀⠀ +// ⠀⠀⠀⠀⢀⣾⢿⢿⠀⠀⠀⢀⣀⣀⠘⣿⠋⠁⠀⠙⢇⠀⠀⠙⢿⣦⡀⠀⠀⠀⠀⠀ +// ⠀⠀⠀⢀⣾⢇⡞⠘⣧⠀⢖⡭⠞⢛⡄⠘⣆⠀⠀⠀⠈⢧⠀⠀⠀⠙⢿⣄⠀⠀⠀⠀ +// ⠀⠀⣠⣿⣛⣥⠤⠤⢿⡄⠀⠀⠈⠉⠀⠀⠹⡄⠀⠀⠀⠈⢧⠀⠀⠀⠈⠻⣦⠀⠀⠀ +// ⠀⣼⡟⡱⠛⠙⠀⠀⠘⢷⡀⠀⠀⠀⠀⠀⠀⠹⡀⠀⠀⠀⠈⣧⠀⠀⠀⠀⠹⣧⡀⠀ +// ⢸⡏⢠⠃⠀⠀⠀⠀⠀⠀⢳⡀⠀⠀⠀⠀⠀⠀⢳⡀⠀⠀⠀⠘⣧⠀⠀⠀⠀⠸⣷⡀ +// ⠸⣧⠘⡇⠀⠀⠀⠀⠀⠀⠀⢳⡀⠀⠀⠀⠀⠀⠀⢣⠀⠀⠀⠀⢹⡇⠀⠀⠀⠀⣿⠇ +// ⠀⣿⡄⢳⠀⠀⠀⠀⠀⠀⠀⠈⣷⠀⠀⠀⠀⠀⠀⠈⠆⠀⠀⠀⠀⠀⠀⠀⠀⣼⡟⠀ +// ⠀⢹⡇⠘⣇⠀⠀⠀⠀⠀⠀⠰⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⣼⡟⠀⠀ +// ⠀⢸⡇⠀⢹⡆⠀⠀⠀⠀⠀⠀⠙⠁⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⢳⣼⠟⠀⠀⠀ +// ⠀⠸⣧⣀⠀⢳⡀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⢃⠀⢀⣴⡿⠁⠀⠀⠀⠀ +// ⠀⠀⠈⠙⢷⣄⢳⡀⠀⠀⠀⠀⠀⠀⢳⡀⠀⠀⠀⠀⠀⣠⡿⠟⠛⠉⠀⠀⠀⠀⠀⠀ +// ⠀⠀⠀⠀⠈⠻⢿⣷⣦⣄⣀⣀⣠⣤⠾⠷⣦⣤⣤⡶⠟⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +// ⠀⠀⠀⠀⠀⠀⠀⠈⠉⠛⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ + + player2Name = resp.opponent(); + System.out.println(player2Name); + + currentPlayerMoveText.setText("X"); + + if(!resp.playerToMove().equalsIgnoreCase(resp.opponent())) { + currentPlayerNameText.setText(information.playerName()[0]); + firstPlayerIsMe.set(true); + + System.out.printf("I am starting: My client id is %d\n", resp.clientId()); + } else { + currentPlayerNameText.setText(player2Name); + firstPlayerIsMe.set(false); + + System.out.printf("I am NOT starting: My client id is %d\n", resp.clientId()); } } - private void drawSymbol(Game.Move move) { - if (move.value() == 'X') { - canvas.drawX(Color.RED, move.position()); - } else if (move.value() == 'O') { - canvas.drawO(Color.BLUE, move.position()); - } - } - - private void handleServerGameStart(NetworkEvents.GameMatchResponse resp) { - if(resp.playerToMove().equals(resp.opponent())){ - firstPlayerIsMe.set(false); - } - else{ - firstPlayerIsMe.set(true); - } - gameHasStarted.set(true); - } - private void onMoveResponse(NetworkEvents.GameMoveResponse resp) { - char playerChar; - if (resp.player().equals(information.playerName()[0]) && firstPlayerIsMe.get() - || !resp.player().equals(information.playerName()[0]) && !firstPlayerIsMe.get()) { - playerChar = 'X'; - } - else { - playerChar = 'O'; - } - Game.Move move =new Game.Move(Integer.parseInt(resp.move()),playerChar); - Game.State state = ticTacToe.play(move); - if (state != Game.State.NORMAL) { //todo differentiate between future draw guaranteed and is currently a draw - gameHasStarted.set(false); - } - drawSymbol(move); + char playerChar; + + if (!resp.player().equalsIgnoreCase(player2Name)) { + playerChar = firstPlayerIsMe.get()? 'X' : 'O'; + } else { + playerChar = firstPlayerIsMe.get()? 'O' : 'X'; + } + + final Game.Move move = new Game.Move(Integer.parseInt(resp.move()), playerChar); + final Game.State state = ticTacToe.get().play(move); + + if (state != Game.State.NORMAL) { //todo differentiate between future draw guaranteed and is currently a draw + if (state == Game.State.WIN) { + App.push(new GameFinishedPopup(false, information.playerName()[ticTacToe.get().getCurrentTurn()])); + } else if (state == Game.State.DRAW) { + App.push(new GameFinishedPopup(true, "")); + } + } + + if (move.value() == 'X') { + canvas.drawX(Color.RED, move.position()); + } else if (move.value() == 'O') { + canvas.drawO(Color.BLUE, move.position()); + } + + currentPlayerNameText.setText(ticTacToe.get().getCurrentTurn() == (firstPlayerIsMe.get()? 0 : 1)? information.playerName()[0] : player2Name); + currentPlayerMoveText.setText(ticTacToe.get().getCurrentTurn() == 0? "X" : "O"); } - private void handleChallengeResponse(NetworkEvents.ChallengeResponse resp) { - new EventFlow().addPostEvent(new NetworkEvents.SendAcceptChallenge(resp.clientId(),Integer.parseInt(resp.challengeId()))) - .postEvent(); - } + private void yourTurnResponse(NetworkEvents.YourTurnResponse response) { + int position = -1; - private void yourTurnResponse(NetworkEvents.YourTurnResponse response) { + if (information.isPlayerHuman()[0]) { + try { + position = playerMoveQueue.take().position(); + } catch (InterruptedException _) {} + } else { + final Game.Move move = ticTacToeAI.findBestMove(ticTacToe.get(), compurterDifficultyToDepth(10, + information.computerDifficulty()[0])); - //new EventFlow().addPostEvent(new NetworkEvents.SendCommand(response.clientId(),"CHALLENGE banaan tic-tac-toe")).postEvent(); - //new EventFlow().addPostEvent(new NetworkEvents.SendMove(response.clientId(),(short)2)) - // .postEvent(); - } - private void handleReceivedMessage(NetworkEvents.ReceivedMessage msg) { - System.out.println("Received Message: " + msg.message()); //todo add chat window - } + position = move.position(); + } - private void serverGameThreadResponseHandler(OnlineGameState ogs, NetworkEvents.ChallengeResponse msg) { - if (msg.clientId() != ogs.clientId) return; - IO.println("Client ID: " + ogs.clientId + " Received Message: " + msg); + new EventFlow().addPostEvent(new NetworkEvents.SendMove(response.clientId(), (short)position)) + .postEvent(); } + private void handleReceivedMessage(NetworkEvents.ReceivedMessage msg) { + System.out.println("Received Message: " + msg.message()); //todo add chat window + } } \ No newline at end of file diff --git a/app/src/main/java/org/toop/local/AppContext.java b/app/src/main/java/org/toop/local/AppContext.java index 10009b0..4a50029 100644 --- a/app/src/main/java/org/toop/local/AppContext.java +++ b/app/src/main/java/org/toop/local/AppContext.java @@ -25,4 +25,4 @@ public class AppContext { assert localization != null; return localization.getString(key, locale); } -} +} \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_en.properties b/app/src/main/resources/assets/localization/localization_en.properties index 9d024a5..387d741 100644 --- a/app/src/main/resources/assets/localization/localization_en.properties +++ b/app/src/main/resources/assets/localization/localization_en.properties @@ -1,7 +1,9 @@ +accept=Accept ai=Artificial Intelligence appTitle=ISY Games Selector back=Back backToMainMenu=Back to main menu +challengeText=You were challenged by computer=Computer computerDifficulty=Computer Difficulty computerThinkTime=Computer Think Time @@ -11,10 +13,12 @@ connectionType=Connection Type credits=Credits dark=Dark dark-hc=Dark (High Contrast) +deny=Deny developers=Developers drawText=The game ended in a draw effectsVolume=Effects Volume fullscreen=Fullscreen +gameIsText=To a game of goodGameText=Good game. Well played. human=Human language=Language