made more classes deepClonable.

This commit is contained in:
2025-12-04 21:23:26 +01:00
parent 6607918635
commit 76f836b1c1
13 changed files with 66 additions and 15 deletions

View File

@@ -23,7 +23,7 @@ public class ReversiController extends AbstractGameController<ReversiR> {
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);

View File

@@ -1,5 +1,5 @@
package org.toop.framework.gameFramework.model.game;
public interface DeepCopyable<T extends TurnBasedGame<T>> {
public interface DeepCopyable<T> {
T deepCopy();
}

View File

@@ -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<T extends TurnBasedGame<T>> extends MoveProvider<T>, DeepCopyable<AI<T>> {
}

View File

@@ -12,6 +12,6 @@ import org.toop.framework.gameFramework.model.game.TurnBasedGame;
*
* @param <T> the specific type of game this AI can play, extending {@link GameR}
*/
public abstract class AbstractAI<T extends TurnBasedGame<T>> implements MoveProvider<T> {
public abstract class AbstractAI<T extends TurnBasedGame<T>> implements AI<T> {
// Concrete AI implementations should override findBestMove(T game, int depth)
}

View File

@@ -16,15 +16,17 @@ import org.toop.framework.gameFramework.model.game.TurnBasedGame;
* </p>
*/
public abstract class AbstractPlayer<T extends TurnBasedGame<T>> implements Player<T> {
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<T> other) {
this.name = other.name;
}
/**
* Determines the next move based on the provided game state.
* <p>

View File

@@ -2,6 +2,6 @@ package org.toop.framework.gameFramework.model.player;
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
public interface MoveProvider<T extends TurnBasedGame> {
public interface MoveProvider<T extends TurnBasedGame<T>> {
int getMove(T game);
}

View File

@@ -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<T extends TurnBasedGame<T>> extends NameProvider, MoveProvider<T> {
public interface Player<T extends TurnBasedGame<T>> extends NameProvider, MoveProvider<T>, DeepCopyable<Player<T>> {
}

View File

@@ -60,7 +60,9 @@ public abstract class BitboardGame<T extends BitboardGame<T>> 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<T>::deepCopy)
.toArray(Player[]::new);
}
public int getColumnSize() {

View File

@@ -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<BitboardReversi> {
public final class ReversiAIR extends AbstractAI<BitboardReversi>{
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<BitboardReversi> {
int inty = new Random().nextInt(0, moves.length);
return moves[inty];
}
public ReversiAIR deepCopy() {
return new ReversiAIR();
}
}

View File

@@ -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<BitboardTicTacToe> {
return score;
}
@Override
public AI<BitboardTicTacToe> deepCopy() {
return new TicTacToeAIR();
}
}

View File

@@ -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<T extends TurnBasedGame<T>> extends AbstractPlayer<T> {
/** The AI instance used to calculate moves. */
private final MoveProvider<T> ai;
private final AI<T> ai;
/**
* Constructs a new ArtificialPlayer using the specified AI.
*
* @param ai the AI instance that determines moves for this player
*/
public ArtificialPlayer(MoveProvider<T> ai, String name) {
public ArtificialPlayer(AI<T> ai, String name) {
super(name);
this.ai = ai;
}
public ArtificialPlayer(ArtificialPlayer<T> other) {
super(other);
this.ai = other.ai.deepCopy();
}
/**
* Determines the next move for this player using its AI.
* <p>
@@ -44,4 +47,9 @@ public class ArtificialPlayer<T extends TurnBasedGame<T>> extends AbstractPlayer
public int getMove(T gameCopy) {
return ai.getMove(gameCopy);
}
@Override
public ArtificialPlayer<T> deepCopy() {
return new ArtificialPlayer<T>(this);
}
}

View File

@@ -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<T extends TurnBasedGame<T>> extends AbstractPlayer<T> {
super(name);
}
public LocalPlayer(LocalPlayer<T> other) {
super(other);
}
@Override
public int getMove(T gameCopy) {
return getValidMove(gameCopy);
@@ -57,6 +62,11 @@ public class LocalPlayer<T extends TurnBasedGame<T>> extends AbstractPlayer<T> {
return move;
}
@Override
public LocalPlayer<T> deepCopy() {
return new LocalPlayer<T>(this.getName());
}
/*public void register() {
// Listening to PlayerAttemptedMove
new EventFlow().listen(GUIEvents.PlayerAttemptedMove.class, event -> {

View File

@@ -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<T extends TurnBasedGame<T>> extends AbstractPlayer<T>
public OnlinePlayer(String name) {
super(name);
}
public OnlinePlayer(OnlinePlayer<T> other) {
super(other);
}
@Override
public Player<T> deepCopy() {
return new OnlinePlayer<>(this);
}
}