From 76f836b1c1870462918e27ca3903215e4ba50ebd Mon Sep 17 00:00:00 2001
From: Stef
Date: Thu, 4 Dec 2025 21:23:26 +0100
Subject: [PATCH] made more classes deepClonable.
---
.../app/gameControllers/ReversiController.java | 2 +-
.../gameFramework/model/game/DeepCopyable.java | 2 +-
.../gameFramework/model/player/AI.java | 7 +++++++
.../gameFramework/model/player/AbstractAI.java | 2 +-
.../model/player/AbstractPlayer.java | 8 +++++---
.../model/player/MoveProvider.java | 2 +-
.../gameFramework/model/player/Player.java | 3 ++-
.../main/java/org/toop/game/BitboardGame.java | 4 +++-
.../toop/game/games/reversi/ReversiAIR.java | 7 ++++++-
.../game/games/tictactoe/TicTacToeAIR.java | 6 ++++++
.../toop/game/players/ArtificialPlayer.java | 18 +++++++++++++-----
.../org/toop/game/players/LocalPlayer.java | 10 ++++++++++
.../org/toop/game/players/OnlinePlayer.java | 10 ++++++++++
13 files changed, 66 insertions(+), 15 deletions(-)
create mode 100644 framework/src/main/java/org/toop/framework/gameFramework/model/player/AI.java
diff --git a/app/src/main/java/org/toop/app/gameControllers/ReversiController.java b/app/src/main/java/org/toop/app/gameControllers/ReversiController.java
index 4e18cec..efa8323 100644
--- a/app/src/main/java/org/toop/app/gameControllers/ReversiController.java
+++ b/app/src/main/java/org/toop/app/gameControllers/ReversiController.java
@@ -23,7 +23,7 @@ public class ReversiController extends AbstractGameController {
new ReversiCanvas(Color.GRAY, (App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3,(c) -> {new EventFlow().addPostEvent(GUIEvents.PlayerAttemptedMove.class, c).postEvent();}, (c) -> {new EventFlow().addPostEvent(GUIEvents.PlayerMoveHovered.class, c).postEvent();}),
players,
ReversiR,
- local ? new LocalFixedRateThreadBehaviour<>(ReversiR, players) : new OnlineThreadBehaviour<>(ReversiR), // TODO: Player order matters here, this won't work atm
+ local ? new LocalFixedRateThreadBehaviour<>(ReversiR) : new OnlineThreadBehaviour<>(ReversiR), // TODO: Player order matters here, this won't work atm
"Reversi");
eventFlow.listen(GUIEvents.PlayerAttemptedMove.class, event -> {if (getCurrentPlayer() instanceof LocalPlayer lp){lp.setMove(event.move());}}, false);
eventFlow.listen(GUIEvents.PlayerMoveHovered.class, this::onHoverMove, false);
diff --git a/framework/src/main/java/org/toop/framework/gameFramework/model/game/DeepCopyable.java b/framework/src/main/java/org/toop/framework/gameFramework/model/game/DeepCopyable.java
index cf3bfe4..51cb1e2 100644
--- a/framework/src/main/java/org/toop/framework/gameFramework/model/game/DeepCopyable.java
+++ b/framework/src/main/java/org/toop/framework/gameFramework/model/game/DeepCopyable.java
@@ -1,5 +1,5 @@
package org.toop.framework.gameFramework.model.game;
-public interface DeepCopyable> {
+public interface DeepCopyable {
T deepCopy();
}
diff --git a/framework/src/main/java/org/toop/framework/gameFramework/model/player/AI.java b/framework/src/main/java/org/toop/framework/gameFramework/model/player/AI.java
new file mode 100644
index 0000000..8377166
--- /dev/null
+++ b/framework/src/main/java/org/toop/framework/gameFramework/model/player/AI.java
@@ -0,0 +1,7 @@
+package org.toop.framework.gameFramework.model.player;
+
+import org.toop.framework.gameFramework.model.game.DeepCopyable;
+import org.toop.framework.gameFramework.model.game.TurnBasedGame;
+
+public interface AI> extends MoveProvider, DeepCopyable> {
+}
diff --git a/framework/src/main/java/org/toop/framework/gameFramework/model/player/AbstractAI.java b/framework/src/main/java/org/toop/framework/gameFramework/model/player/AbstractAI.java
index ea22859..328132d 100644
--- a/framework/src/main/java/org/toop/framework/gameFramework/model/player/AbstractAI.java
+++ b/framework/src/main/java/org/toop/framework/gameFramework/model/player/AbstractAI.java
@@ -12,6 +12,6 @@ import org.toop.framework.gameFramework.model.game.TurnBasedGame;
*
* @param the specific type of game this AI can play, extending {@link GameR}
*/
-public abstract class AbstractAI> implements MoveProvider {
+public abstract class AbstractAI> implements AI {
// Concrete AI implementations should override findBestMove(T game, int depth)
}
diff --git a/framework/src/main/java/org/toop/framework/gameFramework/model/player/AbstractPlayer.java b/framework/src/main/java/org/toop/framework/gameFramework/model/player/AbstractPlayer.java
index 077dee3..bca7a01 100644
--- a/framework/src/main/java/org/toop/framework/gameFramework/model/player/AbstractPlayer.java
+++ b/framework/src/main/java/org/toop/framework/gameFramework/model/player/AbstractPlayer.java
@@ -16,15 +16,17 @@ import org.toop.framework.gameFramework.model.game.TurnBasedGame;
*
*/
public abstract class AbstractPlayer> implements Player {
- private int playerIndex = -1;
-
- private Logger logger = LogManager.getLogger(this.getClass());
+ private final Logger logger = LogManager.getLogger(this.getClass());
private final String name;
protected AbstractPlayer(String name) {
this.name = name;
}
+
+ protected AbstractPlayer(AbstractPlayer other) {
+ this.name = other.name;
+ }
/**
* Determines the next move based on the provided game state.
*
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
index 29529e2..5a8555e 100644
--- 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
@@ -2,6 +2,6 @@ package org.toop.framework.gameFramework.model.player;
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
-public interface MoveProvider {
+public interface MoveProvider> {
int getMove(T game);
}
diff --git a/framework/src/main/java/org/toop/framework/gameFramework/model/player/Player.java b/framework/src/main/java/org/toop/framework/gameFramework/model/player/Player.java
index bf49cd7..e2ff1a8 100644
--- a/framework/src/main/java/org/toop/framework/gameFramework/model/player/Player.java
+++ b/framework/src/main/java/org/toop/framework/gameFramework/model/player/Player.java
@@ -1,6 +1,7 @@
package org.toop.framework.gameFramework.model.player;
+import org.toop.framework.gameFramework.model.game.DeepCopyable;
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
-public interface Player> extends NameProvider, MoveProvider {
+public interface Player> extends NameProvider, MoveProvider, DeepCopyable> {
}
diff --git a/game/src/main/java/org/toop/game/BitboardGame.java b/game/src/main/java/org/toop/game/BitboardGame.java
index 70311b9..d0f1be4 100644
--- a/game/src/main/java/org/toop/game/BitboardGame.java
+++ b/game/src/main/java/org/toop/game/BitboardGame.java
@@ -60,7 +60,9 @@ public abstract class BitboardGame> implements TurnBas
this.playerBitboard = Arrays.copyOf(other.playerBitboard, other.playerBitboard.length);
this.currentTurn = other.currentTurn;
- this.players = Arrays.copyOf(other.players, other.players.length); // TODO: Make this a deep copy
+ this.players = Arrays.stream(other.players)
+ .map(Player::deepCopy)
+ .toArray(Player[]::new);
}
public int getColumnSize() {
diff --git a/game/src/main/java/org/toop/game/games/reversi/ReversiAIR.java b/game/src/main/java/org/toop/game/games/reversi/ReversiAIR.java
index 626a367..928f4e8 100644
--- a/game/src/main/java/org/toop/game/games/reversi/ReversiAIR.java
+++ b/game/src/main/java/org/toop/game/games/reversi/ReversiAIR.java
@@ -1,10 +1,11 @@
package org.toop.game.games.reversi;
+import org.toop.framework.gameFramework.model.player.AI;
import org.toop.framework.gameFramework.model.player.AbstractAI;
import java.util.Random;
-public final class ReversiAIR extends AbstractAI {
+public final class ReversiAIR extends AbstractAI{
public int getMove(BitboardReversi game) {
int[] moves = game.getLegalMoves();
if (moves.length == 0) return -1;
@@ -12,4 +13,8 @@ public final class ReversiAIR extends AbstractAI {
int inty = new Random().nextInt(0, moves.length);
return moves[inty];
}
+
+ public ReversiAIR deepCopy() {
+ return new ReversiAIR();
+ }
}
diff --git a/game/src/main/java/org/toop/game/games/tictactoe/TicTacToeAIR.java b/game/src/main/java/org/toop/game/games/tictactoe/TicTacToeAIR.java
index 8a3e105..497a0b8 100644
--- a/game/src/main/java/org/toop/game/games/tictactoe/TicTacToeAIR.java
+++ b/game/src/main/java/org/toop/game/games/tictactoe/TicTacToeAIR.java
@@ -1,5 +1,6 @@
package org.toop.game.games.tictactoe;
+import org.toop.framework.gameFramework.model.player.AI;
import org.toop.framework.gameFramework.model.player.AbstractAI;
import org.toop.framework.gameFramework.model.game.PlayResult;
import org.toop.framework.gameFramework.GameState;
@@ -99,4 +100,9 @@ public final class TicTacToeAIR extends AbstractAI {
return score;
}
+
+ @Override
+ public AI deepCopy() {
+ return new TicTacToeAIR();
+ }
}
diff --git a/game/src/main/java/org/toop/game/players/ArtificialPlayer.java b/game/src/main/java/org/toop/game/players/ArtificialPlayer.java
index 49fff2d..41883a5 100644
--- a/game/src/main/java/org/toop/game/players/ArtificialPlayer.java
+++ b/game/src/main/java/org/toop/game/players/ArtificialPlayer.java
@@ -1,8 +1,6 @@
package org.toop.game.players;
-import org.toop.framework.gameFramework.model.player.AbstractAI;
-import org.toop.framework.gameFramework.model.player.AbstractPlayer;
-import org.toop.framework.gameFramework.model.player.MoveProvider;
+import org.toop.framework.gameFramework.model.player.*;
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
/**
@@ -17,18 +15,23 @@ import org.toop.framework.gameFramework.model.game.TurnBasedGame;
public class ArtificialPlayer> extends AbstractPlayer {
/** The AI instance used to calculate moves. */
- private final MoveProvider ai;
+ 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(MoveProvider ai, String name) {
+ 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.
*
@@ -44,4 +47,9 @@ public class ArtificialPlayer> extends AbstractPlayer
public int 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
index e83b3f4..200ac3a 100644
--- a/game/src/main/java/org/toop/game/players/LocalPlayer.java
+++ b/game/src/main/java/org/toop/game/players/LocalPlayer.java
@@ -2,6 +2,7 @@ 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;
@@ -16,6 +17,10 @@ public class LocalPlayer> extends AbstractPlayer {
super(name);
}
+ public LocalPlayer(LocalPlayer other) {
+ super(other);
+ }
+
@Override
public int getMove(T gameCopy) {
return getValidMove(gameCopy);
@@ -57,6 +62,11 @@ public class LocalPlayer> extends AbstractPlayer {
return move;
}
+ @Override
+ public LocalPlayer deepCopy() {
+ return new LocalPlayer(this.getName());
+ }
+
/*public void register() {
// Listening to PlayerAttemptedMove
new EventFlow().listen(GUIEvents.PlayerAttemptedMove.class, event -> {
diff --git a/game/src/main/java/org/toop/game/players/OnlinePlayer.java b/game/src/main/java/org/toop/game/players/OnlinePlayer.java
index 148e19c..9f011c0 100644
--- a/game/src/main/java/org/toop/game/players/OnlinePlayer.java
+++ b/game/src/main/java/org/toop/game/players/OnlinePlayer.java
@@ -2,6 +2,7 @@ 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.
@@ -23,4 +24,13 @@ public class OnlinePlayer> extends AbstractPlayer
public OnlinePlayer(String name) {
super(name);
}
+
+ public OnlinePlayer(OnlinePlayer other) {
+ super(other);
+ }
+
+ @Override
+ public Player deepCopy() {
+ return new OnlinePlayer<>(this);
+ }
}