Removed Generics, pray nothing breaks.

This commit is contained in:
2025-12-12 15:53:24 +01:00
parent 0132981d94
commit fa9c2ce32b
30 changed files with 116 additions and 113 deletions

View File

@@ -214,15 +214,15 @@ public final class Server {
switch (type) { switch (type) {
case TICTACTOE ->{ case TICTACTOE ->{
Player<BitboardTicTacToe>[] players = new Player[2]; Player[] players = new Player[2];
players[(myTurn + 1) % 2] = new OnlinePlayer<>(response.opponent()); players[(myTurn + 1) % 2] = new OnlinePlayer(response.opponent());
players[myTurn] = new ArtificialPlayer<>(new RandomAI<BitboardTicTacToe>(), user); players[myTurn] = new ArtificialPlayer(new RandomAI(), user);
gameController = new TicTacToeBitController(players); gameController = new TicTacToeBitController(players);
} }
case REVERSI -> { case REVERSI -> {
Player<BitboardReversi>[] players = new Player[2]; Player[] players = new Player[2];
players[(myTurn + 1) % 2] = new OnlinePlayer<>(response.opponent()); players[(myTurn + 1) % 2] = new OnlinePlayer(response.opponent());
players[myTurn] = new ArtificialPlayer<>(new RandomAI<BitboardReversi>(), user); players[myTurn] = new ArtificialPlayer(new RandomAI(), user);
gameController = new ReversiBitController(players);} gameController = new ReversiBitController(players);}
default -> new ErrorPopup("Unsupported game type."); default -> new ErrorPopup("Unsupported game type.");

View File

@@ -14,7 +14,7 @@ import org.toop.framework.gameFramework.view.GUIEvents;
import java.util.function.Consumer; import java.util.function.Consumer;
public abstract class BitGameCanvas<T extends TurnBasedGame<T>> implements GameCanvas<T> { public abstract class BitGameCanvas<T extends TurnBasedGame> implements GameCanvas {
protected record Cell(float x, float y, float width, float height) { protected record Cell(float x, float y, float width, float height) {
public boolean isInside(double x, double y) { public boolean isInside(double x, double y) {
return x >= this.x && x <= this.x + width && return x >= this.x && x <= this.x + width &&

View File

@@ -1,8 +1,7 @@
package org.toop.app.canvas; package org.toop.app.canvas;
import javafx.scene.canvas.Canvas; import javafx.scene.canvas.Canvas;
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
public interface GameCanvas<T extends TurnBasedGame<T>> extends GameDrawer<T>{ public interface GameCanvas extends GameDrawer{
Canvas getCanvas(); Canvas getCanvas();
} }

View File

@@ -2,6 +2,6 @@ package org.toop.app.canvas;
import org.toop.framework.gameFramework.model.game.TurnBasedGame; import org.toop.framework.gameFramework.model.game.TurnBasedGame;
public interface GameDrawer<T extends TurnBasedGame<T>> { public interface GameDrawer {
void redraw(T gameCopy); void redraw(TurnBasedGame gameCopy);
} }

View File

@@ -2,12 +2,13 @@ package org.toop.app.canvas;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import org.toop.app.App; import org.toop.app.App;
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
import org.toop.game.games.reversi.BitboardReversi; import org.toop.game.games.reversi.BitboardReversi;
import java.util.Arrays; import java.util.Arrays;
import java.util.function.Consumer; import java.util.function.Consumer;
public class ReversiBitCanvas extends BitGameCanvas<BitboardReversi> { public class ReversiBitCanvas extends BitGameCanvas {
public ReversiBitCanvas() { public ReversiBitCanvas() {
super(Color.GRAY, new Color(0f, 0.4f, 0.2f, 1f), (App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3, 8, 8, 5, true); super(Color.GRAY, new Color(0f, 0.4f, 0.2f, 1f), (App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3, 8, 8, 5, true);
canvas.setOnMouseMoved(event -> { canvas.setOnMouseMoved(event -> {
@@ -33,10 +34,10 @@ public class ReversiBitCanvas extends BitGameCanvas<BitboardReversi> {
} }
@Override @Override
public void redraw(BitboardReversi gameCopy) { public void redraw(TurnBasedGame gameCopy) {
clearAll(); clearAll();
long[] board = gameCopy.getBoard(); long[] board = gameCopy.getBoard();
loopOverBoard(board[0], (i) -> drawDot(Color.WHITE, i)); loopOverBoard(board[0], (i) -> drawDot(Color.WHITE, (int)i));
loopOverBoard(board[1], (i) -> drawDot(Color.BLACK, i)); loopOverBoard(board[1], (i) -> drawDot(Color.BLACK, (int)i));
} }
} }

View File

@@ -2,12 +2,13 @@ package org.toop.app.canvas;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import org.toop.app.App; import org.toop.app.App;
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
import org.toop.game.games.tictactoe.BitboardTicTacToe; import org.toop.game.games.tictactoe.BitboardTicTacToe;
import java.util.Arrays; import java.util.Arrays;
import java.util.function.Consumer; import java.util.function.Consumer;
public class TicTacToeBitCanvas extends BitGameCanvas<BitboardTicTacToe>{ public class TicTacToeBitCanvas extends BitGameCanvas{
public TicTacToeBitCanvas() { public TicTacToeBitCanvas() {
super( super(
Color.GRAY, Color.GRAY,
@@ -22,14 +23,14 @@ public class TicTacToeBitCanvas extends BitGameCanvas<BitboardTicTacToe>{
} }
@Override @Override
public void redraw(BitboardTicTacToe gameCopy) { public void redraw(TurnBasedGame gameCopy) {
clearAll(); clearAll();
drawMoves(gameCopy.getBoard()); drawMoves(gameCopy.getBoard());
} }
private void drawMoves(long[] gameBoard){ private void drawMoves(long[] gameBoard){
loopOverBoard(gameBoard[0], (i) -> drawX(Color.RED, i)); loopOverBoard(gameBoard[0], (i) -> drawX(Color.RED, (int)i));
loopOverBoard(gameBoard[1], (i) -> drawO(Color.BLUE, i)); loopOverBoard(gameBoard[1], (i) -> drawO(Color.BLUE, (Integer) i));
} }

View File

@@ -18,7 +18,7 @@ import org.toop.framework.gameFramework.view.GUIEvents;
import org.toop.framework.networking.events.NetworkEvents; import org.toop.framework.networking.events.NetworkEvents;
import org.toop.game.players.LocalPlayer; import org.toop.game.players.LocalPlayer;
public class GenericGameController<T extends TurnBasedGame<T>> implements GameController { public class GenericGameController implements GameController {
protected final EventFlow eventFlow = new EventFlow(); protected final EventFlow eventFlow = new EventFlow();
// Logger for logging // Logger for logging
@@ -28,13 +28,13 @@ public class GenericGameController<T extends TurnBasedGame<T>> implements GameCo
protected final GameView gameView; protected final GameView gameView;
// Reference to game canvas // Reference to game canvas
protected final GameCanvas<T> canvas; protected final GameCanvas canvas;
protected final TurnBasedGame<T> game; // Reference to game instance protected final TurnBasedGame game; // Reference to game instance
private final ThreadBehaviour gameThreadBehaviour; private final ThreadBehaviour gameThreadBehaviour;
// TODO: Change gameType to automatically happen with either dependency injection or something else. // TODO: Change gameType to automatically happen with either dependency injection or something else.
public GenericGameController(GameCanvas<T> canvas, T game, ThreadBehaviour gameThreadBehaviour, String gameType) { public GenericGameController(GameCanvas canvas, TurnBasedGame game, ThreadBehaviour gameThreadBehaviour, String gameType) {
logger.info("Creating: " + this.getClass()); logger.info("Creating: " + this.getClass());
this.canvas = canvas; this.canvas = canvas;
@@ -55,7 +55,9 @@ public class GenericGameController<T extends TurnBasedGame<T>> implements GameCo
// Listen to updates // Listen to updates
eventFlow eventFlow
.listen(GUIEvents.GameEnded.class, this::onGameFinish, false) .listen(GUIEvents.GameEnded.class, this::onGameFinish, false)
.listen(GUIEvents.PlayerAttemptedMove.class, event -> {if (getCurrentPlayer() instanceof LocalPlayer<T> lp){lp.setMove(event.move());}}, false); .listen(GUIEvents.PlayerAttemptedMove.class, event -> {
if (getCurrentPlayer() instanceof LocalPlayer lp){lp.setMove(event.move());}
}, false);
} }
public void start(){ public void start(){
@@ -70,7 +72,7 @@ public class GenericGameController<T extends TurnBasedGame<T>> implements GameCo
gameThreadBehaviour.stop(); gameThreadBehaviour.stop();
} }
public Player<T> getCurrentPlayer(){ public Player getCurrentPlayer(){
return game.getPlayer(getCurrentPlayerIndex()); return game.getPlayer(getCurrentPlayerIndex());
} }
@@ -97,7 +99,7 @@ public class GenericGameController<T extends TurnBasedGame<T>> implements GameCo
stop(); stop();
} }
public Player<T> getPlayer(int player){ public Player getPlayer(int player){
if (player < 0 || player >= 2){ // TODO: Make game turn player count if (player < 0 || player >= 2){ // TODO: Make game turn player count
logger.error("Invalid player index"); logger.error("Invalid player index");
throw new IllegalArgumentException("player out of range"); throw new IllegalArgumentException("player out of range");

View File

@@ -8,13 +8,13 @@ import org.toop.game.gameThreads.OnlineThreadBehaviour;
import org.toop.game.games.reversi.BitboardReversi; import org.toop.game.games.reversi.BitboardReversi;
import org.toop.game.players.OnlinePlayer; import org.toop.game.players.OnlinePlayer;
public class ReversiBitController extends GenericGameController<BitboardReversi> { public class ReversiBitController extends GenericGameController {
public ReversiBitController(Player<BitboardReversi>[] players) { public ReversiBitController(Player[] players) {
BitboardReversi game = new BitboardReversi(players); BitboardReversi game = new BitboardReversi(players);
ThreadBehaviour thread = new LocalThreadBehaviour<>(game); ThreadBehaviour thread = new LocalThreadBehaviour(game);
for (Player<BitboardReversi> player : players) { for (Player player : players) {
if (player instanceof OnlinePlayer<BitboardReversi>){ if (player instanceof OnlinePlayer){
thread = new OnlineThreadBehaviour<>(game); thread = new OnlineThreadBehaviour(game);
} }
} }
super(new ReversiBitCanvas(), game, thread, "Reversi"); super(new ReversiBitCanvas(), game, thread, "Reversi");

View File

@@ -9,13 +9,13 @@ import org.toop.game.gameThreads.OnlineThreadBehaviour;
import org.toop.game.games.tictactoe.BitboardTicTacToe; import org.toop.game.games.tictactoe.BitboardTicTacToe;
import org.toop.game.players.OnlinePlayer; import org.toop.game.players.OnlinePlayer;
public class TicTacToeBitController extends GenericGameController<BitboardTicTacToe> { public class TicTacToeBitController extends GenericGameController {
public TicTacToeBitController(Player<BitboardTicTacToe>[] players) { public TicTacToeBitController(Player[] players) {
BitboardTicTacToe game = new BitboardTicTacToe(players); BitboardTicTacToe game = new BitboardTicTacToe(players);
ThreadBehaviour thread = new LocalThreadBehaviour<>(game); ThreadBehaviour thread = new LocalThreadBehaviour(game);
for (Player<BitboardTicTacToe> player : players) { for (Player player : players) {
if (player instanceof OnlinePlayer<BitboardTicTacToe>){ if (player instanceof OnlinePlayer){
thread = new OnlineThreadBehaviour<>(game); thread = new OnlineThreadBehaviour(game);
} }
} }
super(new TicTacToeBitCanvas(), game, thread , "TicTacToe"); super(new TicTacToeBitCanvas(), game, thread , "TicTacToe");

View File

@@ -58,14 +58,14 @@ public class LocalMultiplayerView extends ViewWidget {
switch (information.type) { switch (information.type) {
case TICTACTOE: case TICTACTOE:
if (information.players[0].isHuman) { if (information.players[0].isHuman) {
players[0] = new LocalPlayer<>(information.players[0].name); players[0] = new LocalPlayer(information.players[0].name);
} else { } else {
players[0] = new ArtificialPlayer<>(new RandomAI<BitboardTicTacToe>(), "Random AI"); players[0] = new ArtificialPlayer(new RandomAI(), "Random AI");
} }
if (information.players[1].isHuman) { if (information.players[1].isHuman) {
players[1] = new LocalPlayer<>(information.players[1].name); players[1] = new LocalPlayer(information.players[1].name);
} else { } else {
players[1] = new ArtificialPlayer<>(new MiniMaxAI<BitboardTicTacToe>(9), "MiniMax AI"); players[1] = new ArtificialPlayer(new MiniMaxAI(9), "MiniMax AI");
} }
if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstTTT()) { if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstTTT()) {
new ShowEnableTutorialWidget( new ShowEnableTutorialWidget(
@@ -86,14 +86,14 @@ public class LocalMultiplayerView extends ViewWidget {
break; break;
case REVERSI: case REVERSI:
if (information.players[0].isHuman) { if (information.players[0].isHuman) {
players[0] = new LocalPlayer<>(information.players[0].name); players[0] = new LocalPlayer(information.players[0].name);
} else { } else {
players[0] = new ArtificialPlayer<>(new RandomAI<BitboardReversi>(), "Random AI"); players[0] = new ArtificialPlayer(new RandomAI(), "Random AI");
} }
if (information.players[1].isHuman) { if (information.players[1].isHuman) {
players[1] = new LocalPlayer<>(information.players[1].name); players[1] = new LocalPlayer(information.players[1].name);
} else { } else {
players[1] = new ArtificialPlayer<>(new MiniMaxAI<BitboardReversi>(6), "MiniMax"); players[1] = new ArtificialPlayer(new MiniMaxAI(6), "MiniMax");
} }
if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstReversi()) { if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstReversi()) {
new ShowEnableTutorialWidget( new ShowEnableTutorialWidget(

View File

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

View File

@@ -1,6 +1,6 @@
package org.toop.framework.gameFramework.model.game; package org.toop.framework.gameFramework.model.game;
public interface TurnBasedGame<T extends TurnBasedGame<T>> extends Playable, DeepCopyable<T>, PlayerProvider<T>, BoardProvider { public interface TurnBasedGame extends Playable, PlayerProvider, BoardProvider, DeepCopyable<TurnBasedGame> {
int getCurrentTurn(); int getCurrentTurn();
int getPlayerCount(); int getPlayerCount();
int getWinner(); int getWinner();

View File

@@ -16,14 +16,14 @@ import java.util.function.Consumer;
* a running flag, a game reference, and a logger. * a running flag, a game reference, and a logger.
* Subclasses implement the actual game-loop logic. * Subclasses implement the actual game-loop logic.
*/ */
public abstract class AbstractThreadBehaviour<T extends TurnBasedGame<T>> implements ThreadBehaviour { public abstract class AbstractThreadBehaviour implements ThreadBehaviour {
private LongPairConsumer onSendMove; private LongPairConsumer onSendMove;
private Runnable onUpdateUI; private Runnable onUpdateUI;
/** Indicates whether the game loop or event processing is active. */ /** Indicates whether the game loop or event processing is active. */
protected final AtomicBoolean isRunning = new AtomicBoolean(); protected final AtomicBoolean isRunning = new AtomicBoolean();
/** The game instance controlled by this behaviour. */ /** The game instance controlled by this behaviour. */
protected final T game; protected final TurnBasedGame game;
/** Logger for the subclass to report errors or debug info. */ /** Logger for the subclass to report errors or debug info. */
protected final Logger logger = LogManager.getLogger(this.getClass()); protected final Logger logger = LogManager.getLogger(this.getClass());
@@ -33,7 +33,7 @@ public abstract class AbstractThreadBehaviour<T extends TurnBasedGame<T>> implem
* *
* @param game the turn-based game to control * @param game the turn-based game to control
*/ */
public AbstractThreadBehaviour(T game) { public AbstractThreadBehaviour(TurnBasedGame game) {
this.game = game; this.game = game;
} }

View File

@@ -3,5 +3,5 @@ package org.toop.framework.gameFramework.model.player;
import org.toop.framework.gameFramework.model.game.DeepCopyable; import org.toop.framework.gameFramework.model.game.DeepCopyable;
import org.toop.framework.gameFramework.model.game.TurnBasedGame; import org.toop.framework.gameFramework.model.game.TurnBasedGame;
public interface AI<T extends TurnBasedGame<T>> extends MoveProvider<T>, DeepCopyable<AI<T>> { public interface AI extends MoveProvider, DeepCopyable<AI> {
} }

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} * @param <T> the specific type of game this AI can play, extending {@link GameR}
*/ */
public abstract class AbstractAI<T extends TurnBasedGame<T>> implements AI<T> { public abstract class AbstractAI implements AI {
// Concrete AI implementations should override findBestMove(T game, int depth) // Concrete AI implementations should override findBestMove(T game, int depth)
} }

View File

@@ -15,7 +15,7 @@ import org.toop.framework.gameFramework.model.game.TurnBasedGame;
* specific move logic. * specific move logic.
* </p> * </p>
*/ */
public abstract class AbstractPlayer<T extends TurnBasedGame<T>> implements Player<T> { public abstract class AbstractPlayer implements Player {
private final Logger logger = LogManager.getLogger(this.getClass()); private final Logger logger = LogManager.getLogger(this.getClass());
private final String name; private final String name;
@@ -24,7 +24,7 @@ public abstract class AbstractPlayer<T extends TurnBasedGame<T>> implements Play
this.name = name; this.name = name;
} }
protected AbstractPlayer(AbstractPlayer<T> other) { protected AbstractPlayer(AbstractPlayer other) {
this.name = other.name; this.name = other.name;
} }
/** /**
@@ -39,7 +39,7 @@ public abstract class AbstractPlayer<T extends TurnBasedGame<T>> implements Play
* @return an integer representing the chosen move * @return an integer representing the chosen move
* @throws UnsupportedOperationException if the method is not overridden * @throws UnsupportedOperationException if the method is not overridden
*/ */
public long getMove(T gameCopy) { public long getMove(TurnBasedGame gameCopy) {
logger.error("Method getMove not implemented."); logger.error("Method getMove not implemented.");
throw new UnsupportedOperationException("Not supported yet."); throw new UnsupportedOperationException("Not supported yet.");
} }

View File

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

View File

@@ -3,5 +3,5 @@ package org.toop.framework.gameFramework.model.player;
import org.toop.framework.gameFramework.model.game.DeepCopyable; import org.toop.framework.gameFramework.model.game.DeepCopyable;
import org.toop.framework.gameFramework.model.game.TurnBasedGame; import org.toop.framework.gameFramework.model.game.TurnBasedGame;
public interface Player<T extends TurnBasedGame<T>> extends NameProvider, MoveProvider<T>, DeepCopyable<Player<T>> { public interface Player extends NameProvider, MoveProvider, DeepCopyable<Player> {
} }

View File

@@ -7,17 +7,17 @@ import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
// There is AI performance to be gained by getting rid of non-primitives and thus speeding up deepCopy // There is AI performance to be gained by getting rid of non-primitives and thus speeding up deepCopy
public abstract class BitboardGame<T extends BitboardGame<T>> implements TurnBasedGame<T> { public abstract class BitboardGame implements TurnBasedGame {
private final int columnSize; private final int columnSize;
private final int rowSize; private final int rowSize;
private Player<T>[] players; private Player[] players;
// long is 64 bits. Every game has a limit of 64 cells maximum. // long is 64 bits. Every game has a limit of 64 cells maximum.
private final long[] playerBitboard; private final long[] playerBitboard;
private int currentTurn = 0; private int currentTurn = 0;
public BitboardGame(int columnSize, int rowSize, int playerCount, Player<T>[] players) { public BitboardGame(int columnSize, int rowSize, int playerCount, Player[] players) {
this.columnSize = columnSize; this.columnSize = columnSize;
this.rowSize = rowSize; this.rowSize = rowSize;
this.players = players; this.players = players;
@@ -26,14 +26,14 @@ public abstract class BitboardGame<T extends BitboardGame<T>> implements TurnBas
Arrays.fill(playerBitboard, 0L); Arrays.fill(playerBitboard, 0L);
} }
public BitboardGame(BitboardGame<T> other) { public BitboardGame(BitboardGame other) {
this.columnSize = other.columnSize; this.columnSize = other.columnSize;
this.rowSize = other.rowSize; this.rowSize = other.rowSize;
this.playerBitboard = other.playerBitboard.clone(); this.playerBitboard = other.playerBitboard.clone();
this.currentTurn = other.currentTurn; this.currentTurn = other.currentTurn;
this.players = Arrays.stream(other.players) this.players = Arrays.stream(other.players)
.map(Player<T>::deepCopy) .map(Player::deepCopy)
.toArray(Player[]::new); .toArray(Player[]::new);
} }
@@ -61,7 +61,7 @@ public abstract class BitboardGame<T extends BitboardGame<T>> implements TurnBas
return getCurrentPlayerIndex(); return getCurrentPlayerIndex();
} }
public Player<T> getPlayer(int index) {return players[index];} public Player getPlayer(int index) {return players[index];}
public int getCurrentPlayerIndex() { public int getCurrentPlayerIndex() {
return currentTurn % playerBitboard.length; return currentTurn % playerBitboard.length;
@@ -71,7 +71,7 @@ public abstract class BitboardGame<T extends BitboardGame<T>> implements TurnBas
return (currentTurn + 1) % playerBitboard.length; return (currentTurn + 1) % playerBitboard.length;
} }
public Player<T> getCurrentPlayer(){ public Player getCurrentPlayer(){
return players[getCurrentPlayerIndex()]; return players[getCurrentPlayerIndex()];
} }

View File

@@ -16,7 +16,7 @@ import java.util.function.Consumer;
* Runs a separate thread that executes game turns at a fixed frequency (default 60 updates/sec), * 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. * applying player moves, updating the game state, and dispatching UI events.
*/ */
public class LocalFixedRateThreadBehaviour<T extends TurnBasedGame<T>> extends AbstractThreadBehaviour<T> implements Runnable { public class LocalFixedRateThreadBehaviour extends AbstractThreadBehaviour implements Runnable {
/** /**
@@ -24,7 +24,7 @@ public class LocalFixedRateThreadBehaviour<T extends TurnBasedGame<T>> extends A
* *
* @param game the game instance * @param game the game instance
*/ */
public LocalFixedRateThreadBehaviour(T game) { public LocalFixedRateThreadBehaviour(TurnBasedGame game) {
super(game); super(game);
} }
@@ -59,7 +59,7 @@ public class LocalFixedRateThreadBehaviour<T extends TurnBasedGame<T>> extends A
if (now >= nextUpdate) { if (now >= nextUpdate) {
nextUpdate += UPDATE_INTERVAL; nextUpdate += UPDATE_INTERVAL;
Player<T> currentPlayer = game.getPlayer(game.getCurrentTurn()); Player currentPlayer = game.getPlayer(game.getCurrentTurn());
long move = currentPlayer.getMove(game.deepCopy()); long move = currentPlayer.getMove(game.deepCopy());
PlayResult result = game.play(move); PlayResult result = game.play(move);

View File

@@ -16,14 +16,14 @@ import java.util.function.Consumer;
* Repeatedly gets the current player's move, applies it to the game, * 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. * updates the UI, and stops when the game ends or {@link #stop()} is called.
*/ */
public class LocalThreadBehaviour<T extends TurnBasedGame<T>> extends AbstractThreadBehaviour<T> implements Runnable { public class LocalThreadBehaviour extends AbstractThreadBehaviour implements Runnable {
/** /**
* Creates a new behaviour for a local turn-based game. * Creates a new behaviour for a local turn-based game.
* *
* @param game the game instance * @param game the game instance
*/ */
public LocalThreadBehaviour(T game) { public LocalThreadBehaviour(TurnBasedGame game) {
super(game); super(game);
} }
@@ -48,7 +48,7 @@ public class LocalThreadBehaviour<T extends TurnBasedGame<T>> extends AbstractTh
@Override @Override
public void run() { public void run() {
while (isRunning.get()) { while (isRunning.get()) {
Player<T> currentPlayer = game.getPlayer(game.getCurrentTurn()); Player currentPlayer = game.getPlayer(game.getCurrentTurn());
long move = currentPlayer.getMove(game.deepCopy()); long move = currentPlayer.getMove(game.deepCopy());
PlayResult result = game.play(move); PlayResult result = game.play(move);

View File

@@ -14,17 +14,17 @@ import org.toop.game.players.OnlinePlayer;
* Reacts to server events, sending moves and updating the game state * Reacts to server events, sending moves and updating the game state
* for the local player while receiving moves from other players. * for the local player while receiving moves from other players.
*/ */
public class OnlineThreadBehaviour<T extends TurnBasedGame<T>> extends AbstractThreadBehaviour<T> implements SupportsOnlinePlay { public class OnlineThreadBehaviour extends AbstractThreadBehaviour implements SupportsOnlinePlay {
/** /**
* Creates behaviour and sets the first local player * Creates behaviour and sets the first local player
* (non-online player) from the given array. * (non-online player) from the given array.
*/ */
public OnlineThreadBehaviour(T game) { public OnlineThreadBehaviour(TurnBasedGame game) {
super(game); super(game);
} }
/** Finds the first non-online player in the array. */ /** Finds the first non-online player in the array. */
private int getFirstNotOnlinePlayer(Player<T>[] players) { private int getFirstNotOnlinePlayer(Player[] players) {
for (int i = 0; i < players.length; i++) { for (int i = 0; i < players.length; i++) {
if (!(players[i] instanceof OnlinePlayer)) { if (!(players[i] instanceof OnlinePlayer)) {
return i; return i;

View File

@@ -10,14 +10,14 @@ import org.toop.framework.networking.events.NetworkEvents;
* This is identical to {@link OnlineThreadBehaviour}, but inserts a * This is identical to {@link OnlineThreadBehaviour}, but inserts a
* short sleep before delegating to the base implementation. * short sleep before delegating to the base implementation.
*/ */
public class OnlineWithSleepThreadBehaviour<T extends TurnBasedGame<T>> extends OnlineThreadBehaviour<T> { public class OnlineWithSleepThreadBehaviour extends OnlineThreadBehaviour {
/** /**
* Creates the behaviour and forwards the players to the base class. * Creates the behaviour and forwards the players to the base class.
* *
* @param game the online-capable turn-based game * @param game the online-capable turn-based game
*/ */
public OnlineWithSleepThreadBehaviour(T game) { public OnlineWithSleepThreadBehaviour(TurnBasedGame game) {
super(game); super(game);
} }

View File

@@ -5,14 +5,14 @@ import org.toop.framework.gameFramework.model.game.PlayResult;
import org.toop.framework.gameFramework.model.player.Player; import org.toop.framework.gameFramework.model.player.Player;
import org.toop.game.BitboardGame; import org.toop.game.BitboardGame;
public class BitboardReversi extends BitboardGame<BitboardReversi> { public class BitboardReversi extends BitboardGame {
public record Score(int black, int white) {} public record Score(int black, int white) {}
private final long notAFile = 0xfefefefefefefefeL; private final long notAFile = 0xfefefefefefefefeL;
private final long notHFile = 0x7f7f7f7f7f7f7f7fL; private final long notHFile = 0x7f7f7f7f7f7f7f7fL;
public BitboardReversi(Player<BitboardReversi>[] players) { public BitboardReversi(Player[] players) {
super(8, 8, 2, players); super(8, 8, 2, players);
// Black (player 0) // Black (player 0)

View File

@@ -5,7 +5,7 @@ import org.toop.framework.gameFramework.model.game.PlayResult;
import org.toop.framework.gameFramework.model.player.Player; import org.toop.framework.gameFramework.model.player.Player;
import org.toop.game.BitboardGame; import org.toop.game.BitboardGame;
public class BitboardTicTacToe extends BitboardGame<BitboardTicTacToe> { public class BitboardTicTacToe extends BitboardGame {
private final long[] winningLines = { private final long[] winningLines = {
0b111000000L, // top row 0b111000000L, // top row
0b000111000L, // middle row 0b000111000L, // middle row
@@ -17,7 +17,7 @@ public class BitboardTicTacToe extends BitboardGame<BitboardTicTacToe> {
0b001010100L // anti-diagonal 0b001010100L // anti-diagonal
}; };
public BitboardTicTacToe(Player<BitboardTicTacToe>[] players) { public BitboardTicTacToe(Player[] players) {
super(3, 3, 2, players); super(3, 3, 2, players);
} }
public BitboardTicTacToe(BitboardTicTacToe other) { public BitboardTicTacToe(BitboardTicTacToe other) {

View File

@@ -12,22 +12,22 @@ import org.toop.framework.gameFramework.model.game.TurnBasedGame;
* *
* @param <T> the specific type of game this AI player can play * @param <T> the specific type of game this AI player can play
*/ */
public class ArtificialPlayer<T extends TurnBasedGame<T>> extends AbstractPlayer<T> { public class ArtificialPlayer extends AbstractPlayer {
/** The AI instance used to calculate moves. */ /** The AI instance used to calculate moves. */
private final AI<T> ai; private final AI ai;
/** /**
* Constructs a new ArtificialPlayer using the specified AI. * Constructs a new ArtificialPlayer using the specified AI.
* *
* @param ai the AI instance that determines moves for this player * @param ai the AI instance that determines moves for this player
*/ */
public ArtificialPlayer(AI<T> ai, String name) { public ArtificialPlayer(AI ai, String name) {
super(name); super(name);
this.ai = ai; this.ai = ai;
} }
public ArtificialPlayer(ArtificialPlayer<T> other) { public ArtificialPlayer(ArtificialPlayer other) {
super(other); super(other);
this.ai = other.ai.deepCopy(); this.ai = other.ai.deepCopy();
} }
@@ -44,12 +44,12 @@ public class ArtificialPlayer<T extends TurnBasedGame<T>> extends AbstractPlayer
* @return the integer representing the chosen move * @return the integer representing the chosen move
* @throws ClassCastException if {@code gameCopy} is not of type {@code T} * @throws ClassCastException if {@code gameCopy} is not of type {@code T}
*/ */
public long getMove(T gameCopy) { public long getMove(TurnBasedGame gameCopy) {
return ai.getMove(gameCopy); return ai.getMove(gameCopy);
} }
@Override @Override
public ArtificialPlayer<T> deepCopy() { public ArtificialPlayer deepCopy() {
return new ArtificialPlayer<T>(this); return new ArtificialPlayer(this);
} }
} }

View File

@@ -7,7 +7,7 @@ import org.toop.framework.gameFramework.model.player.Player;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
public class LocalPlayer<T extends TurnBasedGame<T>> extends AbstractPlayer<T> { public class LocalPlayer extends AbstractPlayer {
// Future can be used with event system, IF unsubscribeAfterSuccess works... // Future can be used with event system, IF unsubscribeAfterSuccess works...
// private CompletableFuture<Integer> LastMove = new CompletableFuture<>(); // private CompletableFuture<Integer> LastMove = new CompletableFuture<>();
@@ -17,12 +17,12 @@ public class LocalPlayer<T extends TurnBasedGame<T>> extends AbstractPlayer<T> {
super(name); super(name);
} }
public LocalPlayer(LocalPlayer<T> other) { public LocalPlayer(LocalPlayer other) {
super(other); super(other);
} }
@Override @Override
public long getMove(T gameCopy) { public long getMove(TurnBasedGame gameCopy) {
return getValidMove(gameCopy); return getValidMove(gameCopy);
} }
@@ -36,7 +36,7 @@ public class LocalPlayer<T extends TurnBasedGame<T>> extends AbstractPlayer<T> {
return false; return false;
} }
private long getMove2(T gameCopy) { private long getMove2(TurnBasedGame gameCopy) {
LastMove = new CompletableFuture<>(); LastMove = new CompletableFuture<>();
long move = 0; long move = 0;
try { try {
@@ -49,7 +49,7 @@ public class LocalPlayer<T extends TurnBasedGame<T>> extends AbstractPlayer<T> {
return move; return move;
} }
protected long getValidMove(T gameCopy){ protected long getValidMove(TurnBasedGame gameCopy){
// Get this player's valid moves // Get this player's valid moves
long validMoves = gameCopy.getLegalMoves(); long validMoves = gameCopy.getLegalMoves();
// Make sure provided move is valid // Make sure provided move is valid
@@ -64,8 +64,8 @@ public class LocalPlayer<T extends TurnBasedGame<T>> extends AbstractPlayer<T> {
} }
@Override @Override
public LocalPlayer<T> deepCopy() { public LocalPlayer deepCopy() {
return new LocalPlayer<T>(this.getName()); return new LocalPlayer(this.getName());
} }
/*public void register() { /*public void register() {

View File

@@ -9,7 +9,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
public class MiniMaxAI<T extends TurnBasedGame<T>> extends AbstractAI<T> { public class MiniMaxAI extends AbstractAI {
private final int maxDepth; private final int maxDepth;
private final Random random = new Random(); private final Random random = new Random();
@@ -18,17 +18,17 @@ public class MiniMaxAI<T extends TurnBasedGame<T>> extends AbstractAI<T> {
this.maxDepth = depth; this.maxDepth = depth;
} }
public MiniMaxAI(MiniMaxAI<T> other) { public MiniMaxAI(MiniMaxAI other) {
this.maxDepth = other.maxDepth; this.maxDepth = other.maxDepth;
} }
@Override @Override
public MiniMaxAI<T> deepCopy() { public MiniMaxAI deepCopy() {
return new MiniMaxAI<>(this); return new MiniMaxAI(this);
} }
@Override @Override
public long getMove(T game) { public long getMove(TurnBasedGame game) {
long legalMoves = game.getLegalMoves(); long legalMoves = game.getLegalMoves();
if (legalMoves == 0) return 0; if (legalMoves == 0) return 0;
@@ -39,7 +39,7 @@ public class MiniMaxAI<T extends TurnBasedGame<T>> extends AbstractAI<T> {
long movesLoop = legalMoves; long movesLoop = legalMoves;
while (movesLoop != 0) { while (movesLoop != 0) {
long move = 1L << Long.numberOfTrailingZeros(movesLoop); long move = 1L << Long.numberOfTrailingZeros(movesLoop);
T copy = game.deepCopy(); TurnBasedGame copy = game.deepCopy();
PlayResult result = copy.play(move); PlayResult result = copy.play(move);
int score; int score;
@@ -75,7 +75,7 @@ public class MiniMaxAI<T extends TurnBasedGame<T>> extends AbstractAI<T> {
* @param beta Beta value * @param beta Beta value
* @return score of the position * @return score of the position
*/ */
private int getMoveScore(T game, int depth, boolean maximizing, int aiPlayer, int alpha, int beta) { private int getMoveScore(TurnBasedGame game, int depth, boolean maximizing, int aiPlayer, int alpha, int beta) {
long legalMoves = game.getLegalMoves(); long legalMoves = game.getLegalMoves();
// Terminal state // Terminal state
@@ -95,7 +95,7 @@ public class MiniMaxAI<T extends TurnBasedGame<T>> extends AbstractAI<T> {
while (movesLoop != 0) { while (movesLoop != 0) {
long move = 1L << Long.numberOfTrailingZeros(movesLoop); long move = 1L << Long.numberOfTrailingZeros(movesLoop);
T copy = game.deepCopy(); TurnBasedGame copy = game.deepCopy();
PlayResult result = copy.play(move); PlayResult result = copy.play(move);
int score; int score;
@@ -130,7 +130,7 @@ public class MiniMaxAI<T extends TurnBasedGame<T>> extends AbstractAI<T> {
* @param aiPlayer AI's player index * @param aiPlayer AI's player index
* @return heuristic score * @return heuristic score
*/ */
private int evaluateBoard(T game, int aiPlayer) { private int evaluateBoard(TurnBasedGame game, int aiPlayer) {
long[] board = game.getBoard(); long[] board = game.getBoard();
int aiCount = 0; int aiCount = 0;
int opponentCount = 0; int opponentCount = 0;

View File

@@ -12,7 +12,7 @@ import org.toop.framework.gameFramework.model.player.Player;
* Currently, this class is a placeholder and does not implement move logic. * Currently, this class is a placeholder and does not implement move logic.
* </p> * </p>
*/ */
public class OnlinePlayer<T extends TurnBasedGame<T>> extends AbstractPlayer<T> { public class OnlinePlayer extends AbstractPlayer {
/** /**
* Constructs a new OnlinePlayer. * Constructs a new OnlinePlayer.
@@ -25,12 +25,12 @@ public class OnlinePlayer<T extends TurnBasedGame<T>> extends AbstractPlayer<T>
super(name); super(name);
} }
public OnlinePlayer(OnlinePlayer<T> other) { public OnlinePlayer(OnlinePlayer other) {
super(other); super(other);
} }
@Override @Override
public Player<T> deepCopy() { public Player deepCopy() {
return new OnlinePlayer<>(this); return new OnlinePlayer(this);
} }
} }

View File

@@ -6,19 +6,19 @@ import org.toop.framework.gameFramework.model.player.AbstractAI;
import java.util.Random; import java.util.Random;
public class RandomAI<T extends TurnBasedGame<T>> extends AbstractAI<T> { public class RandomAI extends AbstractAI {
public RandomAI() { public RandomAI() {
super(); super();
} }
@Override @Override
public RandomAI<T> deepCopy() { public RandomAI deepCopy() {
return new RandomAI<T>(); return new RandomAI();
} }
@Override @Override
public long getMove(T game) { public long getMove(TurnBasedGame game) {
long legalMoves = game.getLegalMoves(); long legalMoves = game.getLegalMoves();
int move = new Random().nextInt(Long.bitCount(legalMoves)); int move = new Random().nextInt(Long.bitCount(legalMoves));
return nthBitIndex(legalMoves, move); return nthBitIndex(legalMoves, move);