From 35f7a4fd1331d48ec367d4082ec898045007536f Mon Sep 17 00:00:00 2001 From: Bas de Jong Date: Fri, 9 Jan 2026 19:27:47 +0100 Subject: [PATCH] Revert "Merge remote-tracking branch 'refs/remotes/origin/main' into Development" This reverts commit e2132b549d92c6d7cf98720660d88db8210cc408, reversing changes made to 9aefcb9b7bdf599735d5bbe5a4ffb8da07fd0e58. --- .../java/org/toop/app/canvas/GameDrawer.java | 7 - .../controller/UpdatesGameUI.java | 10 -- .../model/game/BoardProvider.java | 5 - .../gameFramework/model/game/Playable.java | 24 --- .../model/game/PlayerProvider.java | 7 - .../model/game/SupportsOnlinePlay.java | 20 --- .../game/threadBehaviour/Controllable.java | 7 - .../model/player/MoveProvider.java | 7 - .../model/player/NameProvider.java | 5 - .../NetworkingClientEventListener.java | 152 ---------------- .../clients/TournamentNetworkingClient.java | 20 --- .../NetworkingInitializationException.java | 4 - .../handlers/NetworkingGameClientHandler.java | 8 - .../exceptions/ClientNotFoundException.java | 25 --- .../exceptions/CouldNotConnectException.java | 21 --- .../interfaces/NetworkingClient.java | 13 -- .../interfaces/NetworkingClientManager.java | 17 -- .../networking/types/NetworkingConnector.java | 5 - .../networking/types/ServerCommand.java | 3 - .../networking/types/ServerMessage.java | 3 - .../main/java/org/toop/game/BitboardGame.java | 86 --------- game/src/main/java/org/toop/game/Move.java | 3 - .../LocalFixedRateThreadBehaviour.java | 88 --------- .../gameThreads/LocalThreadBehaviour.java | 76 -------- .../gameThreads/OnlineThreadBehaviour.java | 84 --------- .../OnlineWithSleepThreadBehaviour.java | 40 ----- .../game/games/reversi/BitboardReversi.java | 170 ------------------ .../games/tictactoe/BitboardTicTacToe.java | 103 ----------- .../toop/game/players/ArtificialPlayer.java | 55 ------ .../org/toop/game/players/LocalPlayer.java | 86 --------- .../java/org/toop/game/players/MiniMaxAI.java | 165 ----------------- .../org/toop/game/players/OnlinePlayer.java | 36 ---- .../java/org/toop/game/players/RandomAI.java | 38 ---- 33 files changed, 1393 deletions(-) delete mode 100644 app/src/main/java/org/toop/app/canvas/GameDrawer.java delete mode 100644 framework/src/main/java/org/toop/framework/gameFramework/controller/UpdatesGameUI.java delete mode 100644 framework/src/main/java/org/toop/framework/gameFramework/model/game/BoardProvider.java delete mode 100644 framework/src/main/java/org/toop/framework/gameFramework/model/game/Playable.java delete mode 100644 framework/src/main/java/org/toop/framework/gameFramework/model/game/PlayerProvider.java delete mode 100644 framework/src/main/java/org/toop/framework/gameFramework/model/game/SupportsOnlinePlay.java delete mode 100644 framework/src/main/java/org/toop/framework/gameFramework/model/game/threadBehaviour/Controllable.java delete mode 100644 framework/src/main/java/org/toop/framework/gameFramework/model/player/MoveProvider.java delete mode 100644 framework/src/main/java/org/toop/framework/gameFramework/model/player/NameProvider.java delete mode 100644 framework/src/main/java/org/toop/framework/networking/NetworkingClientEventListener.java delete mode 100644 framework/src/main/java/org/toop/framework/networking/exceptions/ClientNotFoundException.java delete mode 100644 framework/src/main/java/org/toop/framework/networking/exceptions/CouldNotConnectException.java delete mode 100644 framework/src/main/java/org/toop/framework/networking/interfaces/NetworkingClient.java delete mode 100644 framework/src/main/java/org/toop/framework/networking/interfaces/NetworkingClientManager.java delete mode 100644 framework/src/main/java/org/toop/framework/networking/types/NetworkingConnector.java delete mode 100644 framework/src/main/java/org/toop/framework/networking/types/ServerCommand.java delete mode 100644 framework/src/main/java/org/toop/framework/networking/types/ServerMessage.java delete mode 100644 game/src/main/java/org/toop/game/BitboardGame.java delete mode 100644 game/src/main/java/org/toop/game/Move.java delete mode 100644 game/src/main/java/org/toop/game/gameThreads/LocalFixedRateThreadBehaviour.java delete mode 100644 game/src/main/java/org/toop/game/gameThreads/LocalThreadBehaviour.java delete mode 100644 game/src/main/java/org/toop/game/gameThreads/OnlineThreadBehaviour.java delete mode 100644 game/src/main/java/org/toop/game/gameThreads/OnlineWithSleepThreadBehaviour.java delete mode 100644 game/src/main/java/org/toop/game/games/reversi/BitboardReversi.java delete mode 100644 game/src/main/java/org/toop/game/games/tictactoe/BitboardTicTacToe.java delete mode 100644 game/src/main/java/org/toop/game/players/ArtificialPlayer.java delete mode 100644 game/src/main/java/org/toop/game/players/LocalPlayer.java delete mode 100644 game/src/main/java/org/toop/game/players/MiniMaxAI.java delete mode 100644 game/src/main/java/org/toop/game/players/OnlinePlayer.java delete mode 100644 game/src/main/java/org/toop/game/players/RandomAI.java diff --git a/app/src/main/java/org/toop/app/canvas/GameDrawer.java b/app/src/main/java/org/toop/app/canvas/GameDrawer.java deleted file mode 100644 index 261334c..0000000 --- a/app/src/main/java/org/toop/app/canvas/GameDrawer.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.toop.app.canvas; - -import org.toop.framework.gameFramework.model.game.TurnBasedGame; - -public interface GameDrawer> { - void redraw(T gameCopy); -} diff --git a/framework/src/main/java/org/toop/framework/gameFramework/controller/UpdatesGameUI.java b/framework/src/main/java/org/toop/framework/gameFramework/controller/UpdatesGameUI.java deleted file mode 100644 index ce32bb7..0000000 --- a/framework/src/main/java/org/toop/framework/gameFramework/controller/UpdatesGameUI.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.toop.framework.gameFramework.controller; - -/** - * Interface for classes that can trigger a UI update. - */ -public interface UpdatesGameUI { - - /** Called to refresh or update the game UI. */ - void updateUI(); -} diff --git a/framework/src/main/java/org/toop/framework/gameFramework/model/game/BoardProvider.java b/framework/src/main/java/org/toop/framework/gameFramework/model/game/BoardProvider.java deleted file mode 100644 index fb70cf8..0000000 --- a/framework/src/main/java/org/toop/framework/gameFramework/model/game/BoardProvider.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.toop.framework.gameFramework.model.game; - -public interface BoardProvider { - long[] getBoard(); -} diff --git a/framework/src/main/java/org/toop/framework/gameFramework/model/game/Playable.java b/framework/src/main/java/org/toop/framework/gameFramework/model/game/Playable.java deleted file mode 100644 index 21956b0..0000000 --- a/framework/src/main/java/org/toop/framework/gameFramework/model/game/Playable.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.toop.framework.gameFramework.model.game; - -import org.toop.framework.gameFramework.GameState; - -/** - * Interface for turn-based games that can be played and queried for legal moves. - */ -public interface Playable { - - /** - * Returns the moves that are currently valid in the game. - * - * @return an array of integers representing legal moves - */ - long getLegalMoves(); - - /** - * Plays the given move and returns the resulting game state. - * - * @param move the move to apply - * @return the {@link GameState} and additional info after the move - */ - PlayResult play(long move); -} diff --git a/framework/src/main/java/org/toop/framework/gameFramework/model/game/PlayerProvider.java b/framework/src/main/java/org/toop/framework/gameFramework/model/game/PlayerProvider.java deleted file mode 100644 index 8db47a3..0000000 --- a/framework/src/main/java/org/toop/framework/gameFramework/model/game/PlayerProvider.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.toop.framework.gameFramework.model.game; - -import org.toop.framework.gameFramework.model.player.Player; - -public interface PlayerProvider> { - Player getPlayer(int index); -} diff --git a/framework/src/main/java/org/toop/framework/gameFramework/model/game/SupportsOnlinePlay.java b/framework/src/main/java/org/toop/framework/gameFramework/model/game/SupportsOnlinePlay.java deleted file mode 100644 index 1cc1641..0000000 --- a/framework/src/main/java/org/toop/framework/gameFramework/model/game/SupportsOnlinePlay.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.toop.framework.gameFramework.model.game; - -import org.toop.framework.networking.events.NetworkEvents; - -/** - * Interface for games that support online multiplayer play. - *

- * Methods are called in response to network events from the server. - */ -public interface SupportsOnlinePlay { - - /** Called when it is this player's turn to make a move. */ - void onYourTurn(long clientId); - - /** Called when a move from another player is received. */ - void onMoveReceived(long move); - - /** Called when the game has finished, with the final result. */ - void gameFinished(String condition); -} diff --git a/framework/src/main/java/org/toop/framework/gameFramework/model/game/threadBehaviour/Controllable.java b/framework/src/main/java/org/toop/framework/gameFramework/model/game/threadBehaviour/Controllable.java deleted file mode 100644 index cefbbd4..0000000 --- a/framework/src/main/java/org/toop/framework/gameFramework/model/game/threadBehaviour/Controllable.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.toop.framework.gameFramework.model.game.threadBehaviour; - -public interface Controllable { - void start(); - - void stop(); -} diff --git a/framework/src/main/java/org/toop/framework/gameFramework/model/player/MoveProvider.java b/framework/src/main/java/org/toop/framework/gameFramework/model/player/MoveProvider.java deleted file mode 100644 index b9ab448..0000000 --- a/framework/src/main/java/org/toop/framework/gameFramework/model/player/MoveProvider.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.toop.framework.gameFramework.model.player; - -import org.toop.framework.gameFramework.model.game.TurnBasedGame; - -public interface MoveProvider> { - long getMove(T game); -} diff --git a/framework/src/main/java/org/toop/framework/gameFramework/model/player/NameProvider.java b/framework/src/main/java/org/toop/framework/gameFramework/model/player/NameProvider.java deleted file mode 100644 index 850f0f2..0000000 --- a/framework/src/main/java/org/toop/framework/gameFramework/model/player/NameProvider.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.toop.framework.gameFramework.model.player; - -public interface NameProvider { - String getName(); -} diff --git a/framework/src/main/java/org/toop/framework/networking/NetworkingClientEventListener.java b/framework/src/main/java/org/toop/framework/networking/NetworkingClientEventListener.java deleted file mode 100644 index 5a9a08d..0000000 --- a/framework/src/main/java/org/toop/framework/networking/NetworkingClientEventListener.java +++ /dev/null @@ -1,152 +0,0 @@ -package org.toop.framework.networking; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.toop.framework.SnowflakeGenerator; -import org.toop.framework.eventbus.EventFlow; -import org.toop.framework.eventbus.bus.EventBus; -import org.toop.framework.networking.events.NetworkEvents; -import org.toop.framework.networking.exceptions.ClientNotFoundException; -import org.toop.framework.networking.interfaces.NetworkingClientManager; - -public class NetworkingClientEventListener { - private static final Logger logger = LogManager.getLogger(NetworkingClientEventListener.class); - - private final NetworkingClientManager clientManager; - - /** Starts a connection manager, to manage, connections. */ - public NetworkingClientEventListener(EventBus eventBus, NetworkingClientManager clientManager) { - this.clientManager = clientManager; - new EventFlow(eventBus) - .listen(NetworkEvents.StartClient.class, this::handleStartClient, false) - .listen(NetworkEvents.SendCommand.class, this::handleCommand, false) - .listen(NetworkEvents.SendLogin.class, this::handleSendLogin, false) - .listen(NetworkEvents.SendLogout.class, this::handleSendLogout, false) - .listen(NetworkEvents.SendGetPlayerlist.class, this::handleSendGetPlayerlist, false) - .listen(NetworkEvents.SendGetGamelist.class, this::handleSendGetGamelist, false) - .listen(NetworkEvents.SendSubscribe.class, this::handleSendSubscribe, false) - .listen(NetworkEvents.SendMove.class, this::handleSendMove, false) - .listen(NetworkEvents.SendChallenge.class, this::handleSendChallenge, false) - .listen(NetworkEvents.SendAcceptChallenge.class, this::handleSendAcceptChallenge, false) - .listen(NetworkEvents.SendForfeit.class, this::handleSendForfeit, false) - .listen(NetworkEvents.SendMessage.class, this::handleSendMessage, false) - .listen(NetworkEvents.SendHelp.class, this::handleSendHelp, false) - .listen(NetworkEvents.SendHelpForCommand.class, this::handleSendHelpForCommand, false) - .listen(NetworkEvents.CloseClient.class, this::handleCloseClient, false) - .listen(NetworkEvents.Reconnect.class, this::handleReconnect, false) - .listen(NetworkEvents.ChangeAddress.class, this::handleChangeAddress, false) - .listen(NetworkEvents.RequestsAllClients.class, this::handleGetAllConnections, false) - .listen(NetworkEvents.ForceCloseAllClients.class, this::handleShutdownAll, false); - } - - void handleStartClient(NetworkEvents.StartClient event) { - long clientId = SnowflakeGenerator.nextId(); - new EventFlow().addPostEvent(new NetworkEvents.CreatedIdForClient(clientId, event.identifier())).postEvent(); - clientManager.startClient( - clientId, - event.networkingClient(), - event.networkingConnector(), - () -> new EventFlow().addPostEvent(new NetworkEvents.StartClientResponse(clientId, true, event.identifier())).postEvent(), - () -> new EventFlow().addPostEvent(new NetworkEvents.StartClientResponse(clientId, false, event.identifier())).postEvent() - ); - } - - private void sendCommand(long clientId, String command) { - try { - clientManager.sendCommand(clientId, command); - } catch (ClientNotFoundException e) { - logger.error(e); - } - } - - private void handleCommand(NetworkEvents.SendCommand event) { - String args = String.join(" ", event.args()); - sendCommand(event.clientId(), args); - } - - private void handleSendLogin(NetworkEvents.SendLogin event) { - sendCommand(event.clientId(), String.format("LOGIN %s", event.username())); - } - - private void handleSendLogout(NetworkEvents.SendLogout event) { - sendCommand(event.clientId(), "LOGOUT"); - } - - private void handleSendGetPlayerlist(NetworkEvents.SendGetPlayerlist event) { - sendCommand(event.clientId(), "GET PLAYERLIST"); - } - - private void handleSendGetGamelist(NetworkEvents.SendGetGamelist event) { - sendCommand(event.clientId(), "GET GAMELIST"); - } - - private void handleSendSubscribe(NetworkEvents.SendSubscribe event) { - sendCommand(event.clientId(), String.format("SUBSCRIBE %s", event.gameType())); - } - - private void handleSendMove(NetworkEvents.SendMove event) { - sendCommand(event.clientId(), String.format("MOVE %d", event.moveNumber())); - } - - private void handleSendChallenge(NetworkEvents.SendChallenge event) { - sendCommand(event.clientId(), String.format("CHALLENGE %s %s", event.usernameToChallenge(), event.gameType())); - } - - private void handleSendAcceptChallenge(NetworkEvents.SendAcceptChallenge event) { - sendCommand(event.clientId(), String.format("CHALLENGE ACCEPT %d", event.challengeId())); - } - - private void handleSendForfeit(NetworkEvents.SendForfeit event) { - sendCommand(event.clientId(), "FORFEIT"); - } - - private void handleSendMessage(NetworkEvents.SendMessage event) { - sendCommand(event.clientId(), String.format("MESSAGE %s", event.message())); - } - - private void handleSendHelp(NetworkEvents.SendHelp event) { - sendCommand(event.clientId(), "HELP"); - } - - private void handleSendHelpForCommand(NetworkEvents.SendHelpForCommand event) { - sendCommand(event.clientId(), String.format("HELP %s", event.command())); - } - - private void handleReconnect(NetworkEvents.Reconnect event) { - clientManager.startClient( - event.clientId(), - event.networkingClient(), - event.networkingConnector(), - () -> new EventFlow().addPostEvent(new NetworkEvents.ReconnectResponse(true, event.identifier())).postEvent(), - () -> new EventFlow().addPostEvent(new NetworkEvents.ReconnectResponse(false, event.identifier())).postEvent() - ); - } - - private void handleChangeAddress(NetworkEvents.ChangeAddress event) { - clientManager.startClient( - event.clientId(), - event.networkingClient(), - event.networkingConnector(), - () -> new EventFlow().addPostEvent(new NetworkEvents.ChangeAddressResponse(true, event.identifier())).postEvent(), - () -> new EventFlow().addPostEvent(new NetworkEvents.ChangeAddressResponse(false, event.identifier())).postEvent() - ); - } - - void handleCloseClient(NetworkEvents.CloseClient event) { - try { - this.clientManager.closeClient(event.clientId()); - } catch (ClientNotFoundException e) { - logger.error(e); - } - } - - void handleGetAllConnections(NetworkEvents.RequestsAllClients request) { -// List a = new ArrayList<>(this.networkClients.values()); -// request.future().complete(a); - // TODO - } - - public void handleShutdownAll(NetworkEvents.ForceCloseAllClients request) { - // TODO - } -} diff --git a/framework/src/main/java/org/toop/framework/networking/connection/clients/TournamentNetworkingClient.java b/framework/src/main/java/org/toop/framework/networking/connection/clients/TournamentNetworkingClient.java index 7d8a1d7..afaf48a 100644 --- a/framework/src/main/java/org/toop/framework/networking/connection/clients/TournamentNetworkingClient.java +++ b/framework/src/main/java/org/toop/framework/networking/connection/clients/TournamentNetworkingClient.java @@ -1,8 +1,4 @@ -<<<<<<<< HEAD:framework/src/main/java/org/toop/framework/networking/connection/clients/TournamentNetworkingClient.java package org.toop.framework.networking.connection.clients; -======== -package org.toop.framework.networking.clients; ->>>>>>>> refs/remotes/origin/main:framework/src/main/java/org/toop/framework/networking/clients/TournamentNetworkingClient.java import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; @@ -16,16 +12,10 @@ import io.netty.util.CharsetUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.toop.framework.eventbus.bus.EventBus; -<<<<<<<< HEAD:framework/src/main/java/org/toop/framework/networking/connection/clients/TournamentNetworkingClient.java import org.toop.framework.networking.connection.events.NetworkEvents; import org.toop.framework.networking.connection.exceptions.CouldNotConnectException; import org.toop.framework.networking.connection.handlers.NetworkingGameClientHandler; import org.toop.framework.networking.connection.interfaces.NetworkingClient; -======== -import org.toop.framework.networking.exceptions.CouldNotConnectException; -import org.toop.framework.networking.handlers.NetworkingGameClientHandler; -import org.toop.framework.networking.interfaces.NetworkingClient; ->>>>>>>> refs/remotes/origin/main:framework/src/main/java/org/toop/framework/networking/clients/TournamentNetworkingClient.java import java.net.InetSocketAddress; @@ -34,10 +24,7 @@ public class TournamentNetworkingClient implements NetworkingClient { private final EventBus eventBus; private Channel channel; -<<<<<<<< HEAD:framework/src/main/java/org/toop/framework/networking/connection/clients/TournamentNetworkingClient.java private long clientId; -======== ->>>>>>>> refs/remotes/origin/main:framework/src/main/java/org/toop/framework/networking/clients/TournamentNetworkingClient.java public TournamentNetworkingClient(EventBus eventBus) { this.eventBus = eventBus; @@ -50,10 +37,7 @@ public class TournamentNetworkingClient implements NetworkingClient { @Override public void connect(long clientId, String host, int port) throws CouldNotConnectException { -<<<<<<<< HEAD:framework/src/main/java/org/toop/framework/networking/connection/clients/TournamentNetworkingClient.java this.clientId = clientId; -======== ->>>>>>>> refs/remotes/origin/main:framework/src/main/java/org/toop/framework/networking/clients/TournamentNetworkingClient.java try { Bootstrap bootstrap = new Bootstrap(); EventLoopGroup workerGroup = new MultiThreadIoEventLoopGroup(NioIoHandler.newFactory()); @@ -73,7 +57,6 @@ public class TournamentNetworkingClient implements NetworkingClient { pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); pipeline.addLast(handler); } - }); ChannelFuture channelFuture = bootstrap.connect(host, port).sync(); this.channel = channelFuture.channel(); @@ -95,10 +78,7 @@ public class TournamentNetworkingClient implements NetworkingClient { logger.info("Connection {} sent message: '{}' ", this.channel.remoteAddress(), literalMsg); } else { logger.warn("Cannot send message: '{}', connection inactive. ", literalMsg); -<<<<<<<< HEAD:framework/src/main/java/org/toop/framework/networking/connection/clients/TournamentNetworkingClient.java eventBus.post(new NetworkEvents.ClosedConnection(clientId)); -======== ->>>>>>>> refs/remotes/origin/main:framework/src/main/java/org/toop/framework/networking/clients/TournamentNetworkingClient.java } } diff --git a/framework/src/main/java/org/toop/framework/networking/connection/exceptions/NetworkingInitializationException.java b/framework/src/main/java/org/toop/framework/networking/connection/exceptions/NetworkingInitializationException.java index 9a88c6d..3b2582f 100644 --- a/framework/src/main/java/org/toop/framework/networking/connection/exceptions/NetworkingInitializationException.java +++ b/framework/src/main/java/org/toop/framework/networking/connection/exceptions/NetworkingInitializationException.java @@ -1,8 +1,4 @@ -<<<<<<<< HEAD:framework/src/main/java/org/toop/framework/networking/connection/exceptions/NetworkingInitializationException.java package org.toop.framework.networking.connection.exceptions; -======== -package org.toop.framework.networking.exceptions; ->>>>>>>> refs/remotes/origin/main:framework/src/main/java/org/toop/framework/networking/exceptions/NetworkingInitializationException.java public class NetworkingInitializationException extends RuntimeException { public NetworkingInitializationException(String message, Throwable cause) { diff --git a/framework/src/main/java/org/toop/framework/networking/connection/handlers/NetworkingGameClientHandler.java b/framework/src/main/java/org/toop/framework/networking/connection/handlers/NetworkingGameClientHandler.java index f3728f0..a313d97 100644 --- a/framework/src/main/java/org/toop/framework/networking/connection/handlers/NetworkingGameClientHandler.java +++ b/framework/src/main/java/org/toop/framework/networking/connection/handlers/NetworkingGameClientHandler.java @@ -1,8 +1,4 @@ -<<<<<<<< HEAD:framework/src/main/java/org/toop/framework/networking/connection/handlers/NetworkingGameClientHandler.java package org.toop.framework.networking.connection.handlers; -======== -package org.toop.framework.networking.handlers; ->>>>>>>> refs/remotes/origin/main:framework/src/main/java/org/toop/framework/networking/handlers/NetworkingGameClientHandler.java import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; @@ -13,11 +9,7 @@ import java.util.regex.Pattern; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.toop.framework.eventbus.bus.EventBus; -<<<<<<<< HEAD:framework/src/main/java/org/toop/framework/networking/connection/handlers/NetworkingGameClientHandler.java import org.toop.framework.networking.connection.events.NetworkEvents; -======== -import org.toop.framework.networking.events.NetworkEvents; ->>>>>>>> refs/remotes/origin/main:framework/src/main/java/org/toop/framework/networking/handlers/NetworkingGameClientHandler.java public class NetworkingGameClientHandler extends ChannelInboundHandlerAdapter { private static final Logger logger = LogManager.getLogger(NetworkingGameClientHandler.class); diff --git a/framework/src/main/java/org/toop/framework/networking/exceptions/ClientNotFoundException.java b/framework/src/main/java/org/toop/framework/networking/exceptions/ClientNotFoundException.java deleted file mode 100644 index 2506b26..0000000 --- a/framework/src/main/java/org/toop/framework/networking/exceptions/ClientNotFoundException.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.toop.framework.networking.exceptions; - -/** - * Thrown when an operation is attempted on a networking client - * that does not exist or has already been closed. - */ -public class ClientNotFoundException extends RuntimeException { - - private final long clientId; - - public ClientNotFoundException(long clientId) { - super("Networking client with ID " + clientId + " was not found."); - this.clientId = clientId; - } - - public ClientNotFoundException(long clientId, Throwable cause) { - super("Networking client with ID " + clientId + " was not found.", cause); - this.clientId = clientId; - } - - public long getClientId() { - return clientId; - } - -} \ No newline at end of file diff --git a/framework/src/main/java/org/toop/framework/networking/exceptions/CouldNotConnectException.java b/framework/src/main/java/org/toop/framework/networking/exceptions/CouldNotConnectException.java deleted file mode 100644 index 839fb0b..0000000 --- a/framework/src/main/java/org/toop/framework/networking/exceptions/CouldNotConnectException.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.toop.framework.networking.exceptions; - -public class CouldNotConnectException extends RuntimeException { - - private final long clientId; - - public CouldNotConnectException(long clientId) { - super("Networking client with ID " + clientId + " could not connect."); - this.clientId = clientId; - } - - public CouldNotConnectException(long clientId, Throwable cause) { - super("Networking client with ID " + clientId + " could not connect.", cause); - this.clientId = clientId; - } - - public long getClientId() { - return clientId; - } - -} \ No newline at end of file diff --git a/framework/src/main/java/org/toop/framework/networking/interfaces/NetworkingClient.java b/framework/src/main/java/org/toop/framework/networking/interfaces/NetworkingClient.java deleted file mode 100644 index 09b215c..0000000 --- a/framework/src/main/java/org/toop/framework/networking/interfaces/NetworkingClient.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.toop.framework.networking.interfaces; - -import org.toop.framework.networking.exceptions.CouldNotConnectException; - -import java.net.InetSocketAddress; - -public interface NetworkingClient { - InetSocketAddress getAddress(); - void connect(long clientId, String host, int port) throws CouldNotConnectException; - boolean isActive(); - void writeAndFlush(String msg); - void closeConnection(); -} diff --git a/framework/src/main/java/org/toop/framework/networking/interfaces/NetworkingClientManager.java b/framework/src/main/java/org/toop/framework/networking/interfaces/NetworkingClientManager.java deleted file mode 100644 index c236080..0000000 --- a/framework/src/main/java/org/toop/framework/networking/interfaces/NetworkingClientManager.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.toop.framework.networking.interfaces; - -import org.toop.framework.networking.exceptions.ClientNotFoundException; -import org.toop.framework.networking.exceptions.CouldNotConnectException; -import org.toop.framework.networking.types.NetworkingConnector; - -public interface NetworkingClientManager { - void startClient( - long id, - NetworkingClient nClient, - NetworkingConnector nConnector, - Runnable onSuccess, - Runnable onFailure - ) throws CouldNotConnectException; - void sendCommand(long id, String command) throws ClientNotFoundException; - void closeClient(long id) throws ClientNotFoundException; -} diff --git a/framework/src/main/java/org/toop/framework/networking/types/NetworkingConnector.java b/framework/src/main/java/org/toop/framework/networking/types/NetworkingConnector.java deleted file mode 100644 index ee6ed44..0000000 --- a/framework/src/main/java/org/toop/framework/networking/types/NetworkingConnector.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.toop.framework.networking.types; - -import java.util.concurrent.TimeUnit; - -public record NetworkingConnector(String host, int port, int reconnectAttempts, long timeout, TimeUnit timeUnit) {} \ No newline at end of file diff --git a/framework/src/main/java/org/toop/framework/networking/types/ServerCommand.java b/framework/src/main/java/org/toop/framework/networking/types/ServerCommand.java deleted file mode 100644 index e11bb61..0000000 --- a/framework/src/main/java/org/toop/framework/networking/types/ServerCommand.java +++ /dev/null @@ -1,3 +0,0 @@ -package org.toop.framework.networking.types; - -public record ServerCommand(long clientId, String command) {} diff --git a/framework/src/main/java/org/toop/framework/networking/types/ServerMessage.java b/framework/src/main/java/org/toop/framework/networking/types/ServerMessage.java deleted file mode 100644 index 606607d..0000000 --- a/framework/src/main/java/org/toop/framework/networking/types/ServerMessage.java +++ /dev/null @@ -1,3 +0,0 @@ -package org.toop.framework.networking.types; - -public record ServerMessage(String message) {} diff --git a/game/src/main/java/org/toop/game/BitboardGame.java b/game/src/main/java/org/toop/game/BitboardGame.java deleted file mode 100644 index 4ebdb95..0000000 --- a/game/src/main/java/org/toop/game/BitboardGame.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.toop.game; - -import org.toop.framework.gameFramework.model.game.TurnBasedGame; -import org.toop.framework.gameFramework.model.player.Player; - -import java.util.Arrays; -import java.util.concurrent.atomic.AtomicInteger; - -// There is AI performance to be gained by getting rid of non-primitives and thus speeding up deepCopy -public abstract class BitboardGame> implements TurnBasedGame { - private final int columnSize; - private final int rowSize; - - private Player[] players; - - // long is 64 bits. Every game has a limit of 64 cells maximum. - private final long[] playerBitboard; - private int currentTurn = 0; - - public BitboardGame(int columnSize, int rowSize, int playerCount, Player[] players) { - this.columnSize = columnSize; - this.rowSize = rowSize; - this.players = players; - this.playerBitboard = new long[playerCount]; - - Arrays.fill(playerBitboard, 0L); - } - - public BitboardGame(BitboardGame other) { - this.columnSize = other.columnSize; - this.rowSize = other.rowSize; - - this.playerBitboard = other.playerBitboard.clone(); - this.currentTurn = other.currentTurn; - this.players = Arrays.stream(other.players) - .map(Player::deepCopy) - .toArray(Player[]::new); - } - - public int getColumnSize() { - return this.columnSize; - } - - public int getRowSize() { - return this.rowSize; - } - - public long getPlayerBitboard(int player) { - return this.playerBitboard[player]; - } - - public void setPlayerBitboard(int player, long bitboard) { - this.playerBitboard[player] = bitboard; - } - - public int getPlayerCount() { - return playerBitboard.length; - } - - public int getCurrentTurn() { - return getCurrentPlayerIndex(); - } - - public Player getPlayer(int index) {return players[index];} - - public int getCurrentPlayerIndex() { - return currentTurn % playerBitboard.length; - } - - public int getNextPlayer() { - return (currentTurn + 1) % playerBitboard.length; - } - - public Player getCurrentPlayer(){ - return players[getCurrentPlayerIndex()]; - } - - - - @Override - public long[] getBoard() {return this.playerBitboard;} - - public void nextTurn() { - currentTurn++; - } -} \ No newline at end of file diff --git a/game/src/main/java/org/toop/game/Move.java b/game/src/main/java/org/toop/game/Move.java deleted file mode 100644 index 62a2b1a..0000000 --- a/game/src/main/java/org/toop/game/Move.java +++ /dev/null @@ -1,3 +0,0 @@ -package org.toop.game; -// TODO: Remove this, only used in ReversiCanvas. Needs to not -public record Move(int position, char value) {} diff --git a/game/src/main/java/org/toop/game/gameThreads/LocalFixedRateThreadBehaviour.java b/game/src/main/java/org/toop/game/gameThreads/LocalFixedRateThreadBehaviour.java deleted file mode 100644 index 0a9da7f..0000000 --- a/game/src/main/java/org/toop/game/gameThreads/LocalFixedRateThreadBehaviour.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.toop.game.gameThreads; - -import org.toop.framework.eventbus.EventFlow; -import org.toop.framework.gameFramework.GameState; -import org.toop.framework.gameFramework.model.game.PlayResult; -import org.toop.framework.gameFramework.model.game.threadBehaviour.AbstractThreadBehaviour; -import org.toop.framework.gameFramework.view.GUIEvents; -import org.toop.framework.gameFramework.model.game.TurnBasedGame; -import org.toop.framework.gameFramework.model.player.Player; - -import java.util.function.Consumer; - -/** - * Handles local turn-based game logic at a fixed update rate. - *

- * Runs a separate thread that executes game turns at a fixed frequency (default 60 updates/sec), - * applying player moves, updating the game state, and dispatching UI events. - */ -public class LocalFixedRateThreadBehaviour> extends AbstractThreadBehaviour implements Runnable { - - - /** - * Creates a fixed-rate behaviour for a local turn-based game. - * - * @param game the game instance - */ - public LocalFixedRateThreadBehaviour(T game) { - super(game); - } - - /** Starts the game loop thread if not already running. */ - @Override - public void start() { - if (isRunning.compareAndSet(false, true)) { - new Thread(this).start(); - } - } - - /** Stops the game loop after the current iteration. */ - @Override - public void stop() { - isRunning.set(false); - } - - /** - * Main loop running at a fixed rate. - *

- * Fetches the current player's move, applies it to the game, - * updates the UI, and handles game-ending states. - */ - @Override - public void run() { - final int UPS = 1; - final long UPDATE_INTERVAL = 1_000_000_000L / UPS; - long nextUpdate = System.nanoTime(); - - while (isRunning.get()) { - long now = System.nanoTime(); - if (now >= nextUpdate) { - nextUpdate += UPDATE_INTERVAL; - - Player currentPlayer = game.getPlayer(game.getCurrentTurn()); - long move = currentPlayer.getMove(game.deepCopy()); - PlayResult result = game.play(move); - - updateUI(); - - GameState state = result.state(); - switch (state) { - case WIN, DRAW -> { - isRunning.set(false); - new EventFlow().addPostEvent(GUIEvents.GameEnded.class, state == GameState.WIN, result.player()).postEvent(); - } - case NORMAL, TURN_SKIPPED -> { /* continue */ } - default -> { - logger.error("Unexpected state {}", state); - isRunning.set(false); - throw new RuntimeException("Unknown state: " + state); - } - } - } else { - try { - Thread.sleep(10); - } catch (InterruptedException ignored) {} - } - } - } -} diff --git a/game/src/main/java/org/toop/game/gameThreads/LocalThreadBehaviour.java b/game/src/main/java/org/toop/game/gameThreads/LocalThreadBehaviour.java deleted file mode 100644 index 79c57f9..0000000 --- a/game/src/main/java/org/toop/game/gameThreads/LocalThreadBehaviour.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.toop.game.gameThreads; - -import org.toop.framework.eventbus.EventFlow; -import org.toop.framework.gameFramework.model.game.threadBehaviour.AbstractThreadBehaviour; -import org.toop.framework.gameFramework.view.GUIEvents; -import org.toop.framework.gameFramework.model.game.PlayResult; -import org.toop.framework.gameFramework.GameState; -import org.toop.framework.gameFramework.model.game.TurnBasedGame; -import org.toop.framework.gameFramework.model.player.Player; - -import java.util.function.Consumer; - -/** - * Handles local turn-based game logic in its own thread. - *

- * Repeatedly gets the current player's move, applies it to the game, - * updates the UI, and stops when the game ends or {@link #stop()} is called. - */ -public class LocalThreadBehaviour> extends AbstractThreadBehaviour implements Runnable { - - /** - * Creates a new behaviour for a local turn-based game. - * - * @param game the game instance - */ - public LocalThreadBehaviour(T game) { - super(game); - } - - /** Starts the game loop in a new thread. */ - @Override - public void start() { - if (isRunning.compareAndSet(false, true)) { - new Thread(this).start(); - } - } - - /** Stops the game loop after the current iteration. */ - @Override - public void stop() { - isRunning.set(false); - } - - /** - * Main game loop: gets the current player's move, applies it, - * updates the UI, and handles end-of-game states. - */ - @Override - public void run() { - while (isRunning.get()) { - Player currentPlayer = game.getPlayer(game.getCurrentTurn()); - long move = currentPlayer.getMove(game.deepCopy()); - PlayResult result = game.play(move); - - updateUI(); - - GameState state = result.state(); - switch (state) { - case WIN, DRAW -> { - isRunning.set(false); - new EventFlow().addPostEvent( - GUIEvents.GameEnded.class, - state == GameState.WIN, - result.player() - ).postEvent(); - } - case NORMAL, TURN_SKIPPED -> { /* continue normally */ } - default -> { - logger.error("Unexpected state {}", state); - isRunning.set(false); - throw new RuntimeException("Unknown state: " + state); - } - } - } - } -} diff --git a/game/src/main/java/org/toop/game/gameThreads/OnlineThreadBehaviour.java b/game/src/main/java/org/toop/game/gameThreads/OnlineThreadBehaviour.java deleted file mode 100644 index ae9aa88..0000000 --- a/game/src/main/java/org/toop/game/gameThreads/OnlineThreadBehaviour.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.toop.game.gameThreads; - -import org.toop.framework.eventbus.EventFlow; -import org.toop.framework.gameFramework.model.game.threadBehaviour.AbstractThreadBehaviour; -import org.toop.framework.gameFramework.view.GUIEvents; -import org.toop.framework.gameFramework.model.game.TurnBasedGame; -import org.toop.framework.gameFramework.model.game.SupportsOnlinePlay; -import org.toop.framework.gameFramework.model.player.Player; -import org.toop.game.players.OnlinePlayer; - -/** - * Handles online multiplayer game logic. - *

- * Reacts to server events, sending moves and updating the game state - * for the local player while receiving moves from other players. - */ -public class OnlineThreadBehaviour> extends AbstractThreadBehaviour implements SupportsOnlinePlay { - /** - * Creates behaviour and sets the first local player - * (non-online player) from the given array. - */ - public OnlineThreadBehaviour(T game) { - super(game); - } - - /** Finds the first non-online player in the array. */ - private int getFirstNotOnlinePlayer(Player[] players) { - for (int i = 0; i < players.length; i++) { - if (!(players[i] instanceof OnlinePlayer)) { - return i; - } - } - throw new RuntimeException("All players are online players"); - } - - /** Starts processing network events for the local player. */ - @Override - public void start() { - isRunning.set(true); - } - - /** Stops processing network events. */ - @Override - public void stop() { - isRunning.set(false); - } - - /** - * Called when the server notifies that it is the local player's turn. - * Sends the generated move back to the server. - */ - @Override - public void onYourTurn(long clientId) { - if (!isRunning.get()) return; - long move = game.getPlayer(game.getCurrentTurn()).getMove(game.deepCopy()); - sendMove(clientId, move); - } - - /** - * Handles a move received from the server for any player. - * Updates the game state and triggers a UI refresh. - */ - public void onMoveReceived(long move) { - if (!isRunning.get()) return; - game.play(move); - - updateUI(); - } - - /** - * Handles the end of the game as notified by the server. - * Updates the UI to show a win or draw result for the local player. - */ - public void gameFinished(String condition) { - switch(condition.toUpperCase()){ - case "WIN", "LOSS" -> new EventFlow().addPostEvent(GUIEvents.GameEnded.class, true, game.getWinner()).postEvent(); - case "DRAW" -> new EventFlow().addPostEvent(GUIEvents.GameEnded.class, false, -1).postEvent(); - default -> { - logger.error("Invalid condition"); - throw new RuntimeException("Unknown condition"); - } - } - } -} diff --git a/game/src/main/java/org/toop/game/gameThreads/OnlineWithSleepThreadBehaviour.java b/game/src/main/java/org/toop/game/gameThreads/OnlineWithSleepThreadBehaviour.java deleted file mode 100644 index a666f8d..0000000 --- a/game/src/main/java/org/toop/game/gameThreads/OnlineWithSleepThreadBehaviour.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.toop.game.gameThreads; - -import org.toop.framework.gameFramework.model.game.TurnBasedGame; -import org.toop.framework.networking.events.NetworkEvents; - -/** - * Online thread behaviour that adds a fixed delay before processing - * the local player's turn. - *

- * This is identical to {@link OnlineThreadBehaviour}, but inserts a - * short sleep before delegating to the base implementation. - */ -public class OnlineWithSleepThreadBehaviour> extends OnlineThreadBehaviour { - - /** - * Creates the behaviour and forwards the players to the base class. - * - * @param game the online-capable turn-based game - */ - public OnlineWithSleepThreadBehaviour(T game) { - super(game); - } - - /** - * Waits briefly before handling the "your turn" event. - * - * @param event the network event indicating it's this client's turn - */ - @Override - public void onYourTurn(long clientId) { - - try { - Thread.sleep(50); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - super.onYourTurn(clientId); - } -} diff --git a/game/src/main/java/org/toop/game/games/reversi/BitboardReversi.java b/game/src/main/java/org/toop/game/games/reversi/BitboardReversi.java deleted file mode 100644 index f380bef..0000000 --- a/game/src/main/java/org/toop/game/games/reversi/BitboardReversi.java +++ /dev/null @@ -1,170 +0,0 @@ -package org.toop.game.games.reversi; - -import org.toop.framework.gameFramework.GameState; -import org.toop.framework.gameFramework.model.game.PlayResult; -import org.toop.framework.gameFramework.model.player.Player; -import org.toop.game.BitboardGame; - -public class BitboardReversi extends BitboardGame { - - public record Score(int black, int white) {} - - private final long notAFile = 0xfefefefefefefefeL; - private final long notHFile = 0x7f7f7f7f7f7f7f7fL; - - public BitboardReversi(Player[] players) { - super(8, 8, 2, players); - - // Black (player 0) - setPlayerBitboard(0, (1L << (3 + 4 * 8)) | (1L << (4 + 3 * 8))); - - // White (player 1) - setPlayerBitboard(1, (1L << (3 + 3 * 8)) | (1L << (4 + 4 * 8))); - } - - public BitboardReversi(BitboardReversi other) { - super(other); - } - - public long getLegalMoves() { - final long player = getPlayerBitboard(getCurrentPlayerIndex()); - final long opponent = getPlayerBitboard(getNextPlayer()); - - long legalMoves = 0L; - - // north & south - legalMoves |= computeMoves(player, opponent, 8, -1L); - legalMoves |= computeMoves(player, opponent, -8, -1L); - - // east & west - legalMoves |= computeMoves(player, opponent, 1, notAFile); - legalMoves |= computeMoves(player, opponent, -1, notHFile); - - // north-east & north-west & south-east & south-west - legalMoves |= computeMoves(player, opponent, 9, notAFile); - legalMoves |= computeMoves(player, opponent, 7, notHFile); - legalMoves |= computeMoves(player, opponent, -7, notAFile); - legalMoves |= computeMoves(player, opponent, -9, notHFile); - - return legalMoves; - } - - public long getFlips(long move) { - final long player = getPlayerBitboard(getCurrentPlayerIndex()); - final long opponent = getPlayerBitboard(getNextPlayer()); - - long flips = 0L; - - // north & south - flips |= computeFlips(move, player, opponent, 8, -1L); - flips |= computeFlips(move, player, opponent, -8, -1L); - - // east & west - flips |= computeFlips(move, player, opponent, 1, notAFile); - flips |= computeFlips(move, player, opponent, -1, notHFile); - - // north-east & north-west & south-east & south-west - flips |= computeFlips(move, player, opponent, 9, notAFile); - flips |= computeFlips(move, player, opponent, 7, notHFile); - flips |= computeFlips(move, player, opponent, -7, notAFile); - flips |= computeFlips(move, player, opponent, -9, notHFile); - - return flips; - } - - @Override - public BitboardReversi deepCopy() {return new BitboardReversi(this);} - - public PlayResult play(long move) { - final long flips = getFlips(move); - - long player = getPlayerBitboard(getCurrentPlayerIndex()); - long opponent = getPlayerBitboard(getNextPlayer()); - - player |= move | flips; - opponent &= ~flips; - - setPlayerBitboard(getCurrentPlayerIndex(), player); - setPlayerBitboard(getNextPlayer(), opponent); - - nextTurn(); - - final long nextLegalMoves = getLegalMoves(); - - if (nextLegalMoves == 0) { - nextTurn(); - - final long skippedLegalMoves = getLegalMoves(); - - if (skippedLegalMoves == 0) { - int winner = getWinner(); - - if (winner == -1) { - return new PlayResult(GameState.DRAW, -1); - } - - return new PlayResult(GameState.WIN, winner); - } - - return new PlayResult(GameState.TURN_SKIPPED, getCurrentPlayerIndex()); - } - - return new PlayResult(GameState.NORMAL, getCurrentPlayerIndex()); - } - - public Score getScore() { - return new Score( - Long.bitCount(getPlayerBitboard(0)), - Long.bitCount(getPlayerBitboard(1)) - ); - } - - public int getWinner(){ - final long black = getPlayerBitboard(0); - final long white = getPlayerBitboard(1); - - final int blackCount = Long.bitCount(black); - final int whiteCount = Long.bitCount(white); - - if (blackCount == whiteCount){ - return -1; - } - else if (blackCount > whiteCount){ - return 0; - } - else{ - return 1; - } - } - - private long computeMoves(long player, long opponent, int shift, long mask) { - long moves = shift(player, shift, mask) & opponent; - long captured = moves; - - while (moves != 0) { - moves = shift(moves, shift, mask) & opponent; - captured |= moves; - } - - long landing = shift(captured, shift, mask); - return landing & ~(player | opponent); - } - - private long computeFlips(long move, long player, long opponent, int shift, long mask) { - long flips = 0L; - long pos = move; - - while (true) { - pos = shift(pos, shift, mask); - if (pos == 0) return 0L; - - if ((pos & opponent) != 0) flips |= pos; - else if ((pos & player) != 0) return flips; - else return 0L; - } - } - - private long shift(long bit, int shift, long mask) { - return shift > 0 ? (bit << shift) & mask : (bit >>> -shift) & mask; - } -} \ No newline at end of file diff --git a/game/src/main/java/org/toop/game/games/tictactoe/BitboardTicTacToe.java b/game/src/main/java/org/toop/game/games/tictactoe/BitboardTicTacToe.java deleted file mode 100644 index 0927431..0000000 --- a/game/src/main/java/org/toop/game/games/tictactoe/BitboardTicTacToe.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.toop.game.games.tictactoe; - -import org.toop.framework.gameFramework.GameState; -import org.toop.framework.gameFramework.model.game.PlayResult; -import org.toop.framework.gameFramework.model.player.Player; -import org.toop.game.BitboardGame; - -public class BitboardTicTacToe extends BitboardGame { - private final long[] winningLines = { - 0b111000000L, // top row - 0b000111000L, // middle row - 0b000000111L, // bottom row - 0b100100100L, // left column - 0b010010010L, // middle column - 0b001001001L, // right column - 0b100010001L, // diagonal - 0b001010100L // anti-diagonal - }; - - public BitboardTicTacToe(Player[] players) { - super(3, 3, 2, players); - } - public BitboardTicTacToe(BitboardTicTacToe other) { - super(other); - } - - public long getLegalMoves() { - final long xBitboard = getPlayerBitboard(0); - final long oBitboard = getPlayerBitboard(1); - - final long taken = (xBitboard | oBitboard); - return (~taken) & 0x1ffL; - } - - public int getWinner(){ - return getCurrentPlayerIndex(); - } - - public PlayResult play(long move) { - // Player loses if move is invalid - if ((move & getLegalMoves()) == 0 || Long.bitCount(move) != 1){ - return new PlayResult(GameState.WIN, getNextPlayer()); - } - - // Move is legal, make move - long playerBitboard = getPlayerBitboard(getCurrentPlayerIndex()); - playerBitboard |= move; - - setPlayerBitboard(getCurrentPlayerIndex(), playerBitboard); - - // Check if current player won - if (checkWin(playerBitboard)) { - return new PlayResult(GameState.WIN, getCurrentPlayerIndex()); - } - - // Proceed to next turn - nextTurn(); - - - // Check for early draw - if (getLegalMoves() == 0L || checkEarlyDraw()) { - return new PlayResult(GameState.DRAW, -1); - } - - // Nothing weird happened, continue on as normal - return new PlayResult(GameState.NORMAL, -1); - } - - private boolean checkWin(long board) { - for (final long line : winningLines) { - if ((board & line) == line) { - return true; - } - } - - return false; - } - - private boolean checkEarlyDraw() { - final long xBitboard = getPlayerBitboard(0); - final long oBitboard = getPlayerBitboard(1); - - final long taken = (xBitboard | oBitboard); - final long empty = (~taken) & 0x1FFL; - - for (final long line : winningLines) { - if (((line & xBitboard) != 0 && (line & oBitboard) != 0)) { - continue; - } - - if ((line & empty) != 0) { - return false; - } - } - - return true; - } - - @Override - public BitboardTicTacToe deepCopy() { - return new BitboardTicTacToe(this); - } -} \ No newline at end of file diff --git a/game/src/main/java/org/toop/game/players/ArtificialPlayer.java b/game/src/main/java/org/toop/game/players/ArtificialPlayer.java deleted file mode 100644 index 418cbed..0000000 --- a/game/src/main/java/org/toop/game/players/ArtificialPlayer.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.toop.game.players; - -import org.toop.framework.gameFramework.model.player.*; -import org.toop.framework.gameFramework.model.game.TurnBasedGame; - -/** - * Represents a player controlled by an AI in a game. - *

- * This player uses an {@link AbstractAI} instance to determine its moves. The generic - * parameter {@code T} specifies the type of {@link GameR} the AI can handle. - *

- * - * @param the specific type of game this AI player can play - */ -public class ArtificialPlayer> extends AbstractPlayer { - - /** The AI instance used to calculate moves. */ - private final AI ai; - - /** - * Constructs a new ArtificialPlayer using the specified AI. - * - * @param ai the AI instance that determines moves for this player - */ - public ArtificialPlayer(AI ai, String name) { - super(name); - this.ai = ai; - } - - public ArtificialPlayer(ArtificialPlayer other) { - super(other); - this.ai = other.ai.deepCopy(); - } - - /** - * Determines the next move for this player using its AI. - *

- * This method overrides {@link AbstractPlayer#getMove(GameR)}. Because the AI is - * typed to {@code T}, a runtime cast is required. It is the caller's - * responsibility to ensure that {@code gameCopy} is of type {@code T}. - *

- * - * @param gameCopy a copy of the current game state - * @return the integer representing the chosen move - * @throws ClassCastException if {@code gameCopy} is not of type {@code T} - */ - public long getMove(T gameCopy) { - return ai.getMove(gameCopy); - } - - @Override - public ArtificialPlayer deepCopy() { - return new ArtificialPlayer(this); - } -} diff --git a/game/src/main/java/org/toop/game/players/LocalPlayer.java b/game/src/main/java/org/toop/game/players/LocalPlayer.java deleted file mode 100644 index 8f3b94d..0000000 --- a/game/src/main/java/org/toop/game/players/LocalPlayer.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.toop.game.players; - -import org.toop.framework.gameFramework.model.game.TurnBasedGame; -import org.toop.framework.gameFramework.model.player.AbstractPlayer; -import org.toop.framework.gameFramework.model.player.Player; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -public class LocalPlayer> extends AbstractPlayer { - // Future can be used with event system, IF unsubscribeAfterSuccess works... - // private CompletableFuture LastMove = new CompletableFuture<>(); - - private CompletableFuture LastMove; - - public LocalPlayer(String name) { - super(name); - } - - public LocalPlayer(LocalPlayer other) { - super(other); - } - - @Override - public long getMove(T gameCopy) { - return getValidMove(gameCopy); - } - - public void setMove(long move) { - LastMove.complete(move); - } - - // TODO: helper function, would like to replace to get rid of this method - public static boolean contains(int[] array, int value){ - for (int i : array) if (i == value) return true; - return false; - } - - private long getMove2(T gameCopy) { - LastMove = new CompletableFuture<>(); - long move = 0; - try { - move = LastMove.get(); - System.out.println(Long.toBinaryString(move)); - } catch (InterruptedException | ExecutionException e) { - // TODO: Add proper logging. - e.printStackTrace(); - } - return move; - } - - protected long getValidMove(T gameCopy){ - // Get this player's valid moves - long validMoves = gameCopy.getLegalMoves(); - // Make sure provided move is valid - // TODO: Limit amount of retries? - // TODO: Stop copying game so many times - long move = getMove2(gameCopy.deepCopy()); - while ((validMoves & move) == 0) { - System.out.println("Not a valid move, try again"); - move = getMove2(gameCopy.deepCopy()); - } - return move; - } - - @Override - public LocalPlayer deepCopy() { - return new LocalPlayer(this.getName()); - } - - /*public void register() { - // Listening to PlayerAttemptedMove - new EventFlow().listen(GUIEvents.PlayerAttemptedMove.class, event -> { - if (!LastMove.isDone()) { - LastMove.complete(event.move()); // complete the future - } - }, true); // auto-unsubscribe - } - - // This blocks until the next move arrives - public int take() throws ExecutionException, InterruptedException { - int move = LastMove.get(); // blocking - LastMove = new CompletableFuture<>(); // reset for next move - return move; - }*/ -} diff --git a/game/src/main/java/org/toop/game/players/MiniMaxAI.java b/game/src/main/java/org/toop/game/players/MiniMaxAI.java deleted file mode 100644 index 440bb50..0000000 --- a/game/src/main/java/org/toop/game/players/MiniMaxAI.java +++ /dev/null @@ -1,165 +0,0 @@ -package org.toop.game.players; - -import org.toop.framework.gameFramework.GameState; -import org.toop.framework.gameFramework.model.game.PlayResult; -import org.toop.framework.gameFramework.model.game.TurnBasedGame; -import org.toop.framework.gameFramework.model.player.AbstractAI; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -public class MiniMaxAI> extends AbstractAI { - - private final int maxDepth; - private final Random random = new Random(); - - public MiniMaxAI(int depth) { - this.maxDepth = depth; - } - - public MiniMaxAI(MiniMaxAI other) { - this.maxDepth = other.maxDepth; - } - - @Override - public MiniMaxAI deepCopy() { - return new MiniMaxAI<>(this); - } - - @Override - public long getMove(T game) { - long legalMoves = game.getLegalMoves(); - if (legalMoves == 0) return 0; - - List bestMoves = new ArrayList<>(); - int bestScore = Integer.MIN_VALUE; - int aiPlayer = game.getCurrentTurn(); - - long movesLoop = legalMoves; - while (movesLoop != 0) { - long move = 1L << Long.numberOfTrailingZeros(movesLoop); - T copy = game.deepCopy(); - PlayResult result = copy.play(move); - - int score; - switch (result.state()) { - case WIN -> score = (result.player() == aiPlayer ? maxDepth : -maxDepth); - case DRAW -> score = 0; - default -> score = getMoveScore(copy, maxDepth - 1, false, aiPlayer, Integer.MIN_VALUE, Integer.MAX_VALUE); - } - - if (score > bestScore) { - bestScore = score; - bestMoves.clear(); - bestMoves.add(move); - } else if (score == bestScore) { - bestMoves.add(move); - } - - movesLoop &= movesLoop - 1; - } - - long chosenMove = bestMoves.get(random.nextInt(bestMoves.size())); - return chosenMove; - } - - /** - * Recursive minimax with alpha-beta pruning and heuristic evaluation. - * - * @param game Current game state - * @param depth Remaining depth - * @param maximizing True if AI is maximizing, false if opponent - * @param aiPlayer AI's player index - * @param alpha Alpha value - * @param beta Beta value - * @return score of the position - */ - private int getMoveScore(T game, int depth, boolean maximizing, int aiPlayer, int alpha, int beta) { - long legalMoves = game.getLegalMoves(); - - // Terminal state - PlayResult lastResult = null; - if (legalMoves == 0) { - lastResult = new PlayResult(GameState.DRAW, -1); - } - - // If the game is over or depth limit reached, evaluate - if (depth <= 0 || legalMoves == 0) { - if (lastResult != null) return 0; - return evaluateBoard(game, aiPlayer); - } - - int bestScore = maximizing ? Integer.MIN_VALUE : Integer.MAX_VALUE; - long movesLoop = legalMoves; - - while (movesLoop != 0) { - long move = 1L << Long.numberOfTrailingZeros(movesLoop); - T copy = game.deepCopy(); - PlayResult result = copy.play(move); - - int score; - switch (result.state()) { - case WIN -> score = (result.player() == aiPlayer ? depth : -depth); - case DRAW -> score = 0; - default -> score = getMoveScore(copy, depth - 1, !maximizing, aiPlayer, alpha, beta); - } - - if (maximizing) { - bestScore = Math.max(bestScore, score); - alpha = Math.max(alpha, bestScore); - } else { - bestScore = Math.min(bestScore, score); - beta = Math.min(beta, bestScore); - } - - // Alpha-beta pruning - if (beta <= alpha) break; - - movesLoop &= movesLoop - 1; - } - - return bestScore; - } - - /** - * Simple heuristic evaluation for Reversi-like games. - * Positive = good for AI, Negative = good for opponent. - * - * @param game Game state - * @param aiPlayer AI's player index - * @return heuristic score - */ - private int evaluateBoard(T game, int aiPlayer) { - long[] board = game.getBoard(); - int aiCount = 0; - int opponentCount = 0; - - // Count pieces for AI vs opponent - for (int i = 0; i < board.length; i++) { - long bits = board[i]; - for (int j = 0; j < 64; j++) { - if ((bits & (1L << j)) != 0) { - // Assume player 0 occupies even indices, player 1 occupies odd - if ((i * 64 + j) % game.getPlayerCount() == aiPlayer) aiCount++; - else opponentCount++; - } - } - } - - // Mobility (number of legal moves) - int mobility = Long.bitCount(game.getLegalMoves()); - - // Corner control (top-left, top-right, bottom-left, bottom-right) - int corners = 0; - long[] cornerMasks = {1L << 0, 1L << 7, 1L << 56, 1L << 63}; - for (long mask : cornerMasks) { - for (long b : board) { - if ((b & mask) != 0) corners += 1; - } - } - - // Weighted sum - return (aiCount - opponentCount) + 2 * mobility + 5 * corners; - } -} diff --git a/game/src/main/java/org/toop/game/players/OnlinePlayer.java b/game/src/main/java/org/toop/game/players/OnlinePlayer.java deleted file mode 100644 index 9f011c0..0000000 --- a/game/src/main/java/org/toop/game/players/OnlinePlayer.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.toop.game.players; - -import org.toop.framework.gameFramework.model.game.TurnBasedGame; -import org.toop.framework.gameFramework.model.player.AbstractPlayer; -import org.toop.framework.gameFramework.model.player.Player; - -/** - * Represents a player controlled remotely or over a network. - *

- * This class extends {@link AbstractPlayer} and can be used to implement game logic - * where moves are provided by an external source (e.g., another user or a server). - * Currently, this class is a placeholder and does not implement move logic. - *

- */ -public class OnlinePlayer> extends AbstractPlayer { - - /** - * Constructs a new OnlinePlayer. - *

- * Currently, no additional initialization is performed. Subclasses or - * future implementations should provide mechanisms to receive moves from - * an external source. - */ - public OnlinePlayer(String name) { - super(name); - } - - public OnlinePlayer(OnlinePlayer other) { - super(other); - } - - @Override - public Player deepCopy() { - return new OnlinePlayer<>(this); - } -} diff --git a/game/src/main/java/org/toop/game/players/RandomAI.java b/game/src/main/java/org/toop/game/players/RandomAI.java deleted file mode 100644 index 2d0fe02..0000000 --- a/game/src/main/java/org/toop/game/players/RandomAI.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.toop.game.players; - -import org.toop.framework.gameFramework.model.game.TurnBasedGame; -import org.toop.framework.gameFramework.model.player.AbstractAI; - -import java.util.Random; - - -public class RandomAI> extends AbstractAI { - - public RandomAI() { - super(); - } - - @Override - public RandomAI deepCopy() { - return new RandomAI(); - } - - @Override - public long getMove(T game) { - long legalMoves = game.getLegalMoves(); - int move = new Random().nextInt(Long.bitCount(legalMoves)); - return nthBitIndex(legalMoves, move); - } - - public static long nthBitIndex(long bb, int n) { - while (bb != 0) { - int tz = Long.numberOfTrailingZeros(bb); - if (n == 0) { - return 1L << tz; - } - bb &= bb - 1; // clear the least significant 1 - n--; - } - return 0L; // not enough 1s - } -}