Everything is broken

This commit is contained in:
2025-12-04 19:43:03 +01:00
parent 7ea45586ae
commit 0993abeec7
13 changed files with 105 additions and 52 deletions

View File

@@ -2,9 +2,7 @@ package org.toop.app;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import org.toop.app.gameControllers.AbstractGameController; import org.toop.app.gameControllers.*;
import org.toop.app.gameControllers.ReversiController;
import org.toop.app.gameControllers.TicTacToeController;
import org.toop.app.widget.Primitive; import org.toop.app.widget.Primitive;
import org.toop.app.widget.WidgetContainer; import org.toop.app.widget.WidgetContainer;
import org.toop.app.widget.complex.LoadingWidget; import org.toop.app.widget.complex.LoadingWidget;
@@ -13,11 +11,15 @@ import org.toop.app.widget.popup.ErrorPopup;
import org.toop.app.widget.popup.SendChallengePopup; import org.toop.app.widget.popup.SendChallengePopup;
import org.toop.app.widget.view.ServerView; import org.toop.app.widget.view.ServerView;
import org.toop.framework.eventbus.EventFlow; import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.gameFramework.controller.GameController;
import org.toop.framework.gameFramework.model.player.Player; import org.toop.framework.gameFramework.model.player.Player;
import org.toop.framework.networking.clients.TournamentNetworkingClient; import org.toop.framework.networking.clients.TournamentNetworkingClient;
import org.toop.framework.networking.events.NetworkEvents; import org.toop.framework.networking.events.NetworkEvents;
import org.toop.framework.networking.types.NetworkingConnector; import org.toop.framework.networking.types.NetworkingConnector;
import org.toop.game.games.reversi.BitboardReversi;
import org.toop.game.games.tictactoe.BitboardTicTacToe;
import org.toop.game.players.ArtificialPlayer; import org.toop.game.players.ArtificialPlayer;
import org.toop.game.players.LocalPlayer;
import org.toop.game.players.OnlinePlayer; import org.toop.game.players.OnlinePlayer;
import org.toop.game.games.reversi.ReversiAIR; import org.toop.game.games.reversi.ReversiAIR;
import org.toop.game.games.reversi.ReversiR; import org.toop.game.games.reversi.ReversiR;
@@ -42,7 +44,7 @@ public final class Server {
private ServerView primary; private ServerView primary;
private boolean isPolling = true; private boolean isPolling = true;
private AbstractGameController<?> gameController; private GameController gameController;
private final AtomicBoolean isSingleGame = new AtomicBoolean(false); private final AtomicBoolean isSingleGame = new AtomicBoolean(false);
@@ -195,26 +197,31 @@ public final class Server {
information.players[0].computerThinkTime = 1; information.players[0].computerThinkTime = 1;
information.players[1].name = response.opponent(); information.players[1].name = response.opponent();
Player[] players = new Player[2]; /*switch (type){
players[(myTurn + 1) % 2] = new OnlinePlayer<ReversiR>(response.opponent());
switch (type){
case TICTACTOE ->{ case TICTACTOE ->{
players[myTurn] = new ArtificialPlayer<>(new TicTacToeAIR(), user); players[myTurn] = new ArtificialPlayer<>(new TicTacToeAIR(), user);
} }
case REVERSI ->{ case REVERSI ->{
players[myTurn] = new ArtificialPlayer<>(new ReversiAIR(), user); players[myTurn] = new ArtificialPlayer<>(new ReversiAIR(), user);
} }
} }*/
switch (type) { switch (type) {
case TICTACTOE ->{ case TICTACTOE ->{
gameController = new TicTacToeController(players, false); Player<BitboardTicTacToe>[] players = new Player[2];
players[(myTurn + 1) % 2] = new OnlinePlayer<>(response.opponent());
players[myTurn] = new ArtificialPlayer<>(new TicTacToeAIR(), user);
gameController = new TicTacToeBitController(players);
} }
case REVERSI -> case REVERSI -> {
gameController = new ReversiController(players, false); Player<BitboardReversi>[] players = new Player[2];
players[(myTurn + 1) % 2] = new OnlinePlayer<>(response.opponent());
players[myTurn] = new ArtificialPlayer<>(new ReversiAIR(), user);
gameController = new ReversiBitController(players);}
default -> new ErrorPopup("Unsupported game type."); default -> new ErrorPopup("Unsupported game type.");
} }
if (gameController != null){ if (gameController != null){

View File

@@ -0,0 +1,26 @@
package org.toop.app.gameControllers;
import org.toop.app.canvas.GameCanvas;
import org.toop.app.canvas.ReversiBitCanvas;
import org.toop.framework.gameFramework.model.game.SupportsOnlinePlay;
import org.toop.framework.gameFramework.model.game.threadBehaviour.ThreadBehaviour;
import org.toop.framework.gameFramework.model.player.Player;
import org.toop.game.gameThreads.LocalThreadBehaviour;
import org.toop.game.gameThreads.OnlineThreadBehaviour;
import org.toop.game.gameThreads.OnlineWithSleepThreadBehaviour;
import org.toop.game.games.reversi.BitboardReversi;
import org.toop.game.games.tictactoe.BitboardTicTacToe;
import org.toop.game.players.OnlinePlayer;
public class ReversiBitController extends GenericGameController<BitboardReversi> {
public ReversiBitController(Player<BitboardReversi>[] players) {
BitboardReversi game = new BitboardReversi(players);
ThreadBehaviour thread = new LocalThreadBehaviour<>(game);
for (Player<BitboardReversi> player : players) {
if (player instanceof OnlinePlayer<BitboardReversi>){
thread = new OnlineWithSleepThreadBehaviour<>(game);
}
}
super(new ReversiBitCanvas(), game, thread, "Reversi");
}
}

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();}), 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, players,
ReversiR, ReversiR,
local ? new LocalFixedRateThreadBehaviour<>(ReversiR, players) : new OnlineThreadBehaviour<>(ReversiR, players), // TODO: Player order matters here, this won't work atm local ? new LocalFixedRateThreadBehaviour<>(ReversiR, players) : new OnlineThreadBehaviour<>(ReversiR), // TODO: Player order matters here, this won't work atm
"Reversi"); "Reversi");
eventFlow.listen(GUIEvents.PlayerAttemptedMove.class, event -> {if (getCurrentPlayer() instanceof LocalPlayer lp){lp.setMove(event.move());}}, false); eventFlow.listen(GUIEvents.PlayerAttemptedMove.class, event -> {if (getCurrentPlayer() instanceof LocalPlayer lp){lp.setMove(event.move());}}, false);
eventFlow.listen(GUIEvents.PlayerMoveHovered.class, this::onHoverMove, false); eventFlow.listen(GUIEvents.PlayerMoveHovered.class, this::onHoverMove, false);

View File

@@ -0,0 +1,25 @@
package org.toop.app.gameControllers;
import org.toop.app.canvas.GameCanvas;
import org.toop.app.canvas.TicTacToeBitCanvas;
import org.toop.framework.gameFramework.model.game.SupportsOnlinePlay;
import org.toop.framework.gameFramework.model.game.threadBehaviour.ThreadBehaviour;
import org.toop.framework.gameFramework.model.player.Player;
import org.toop.game.gameThreads.LocalThreadBehaviour;
import org.toop.game.gameThreads.OnlineThreadBehaviour;
import org.toop.game.gameThreads.OnlineWithSleepThreadBehaviour;
import org.toop.game.games.tictactoe.BitboardTicTacToe;
import org.toop.game.players.OnlinePlayer;
public class TicTacToeBitController extends GenericGameController<BitboardTicTacToe> {
public TicTacToeBitController(Player<BitboardTicTacToe>[] players) {
BitboardTicTacToe game = new BitboardTicTacToe(players);
ThreadBehaviour thread = new LocalThreadBehaviour<>(game);
for (Player<BitboardTicTacToe> player : players) {
if (player instanceof OnlinePlayer<BitboardTicTacToe>){
thread = new OnlineWithSleepThreadBehaviour<>(game);
}
}
super(new TicTacToeBitCanvas(), game, thread , "TicTacToe");
}
}

View File

@@ -22,7 +22,7 @@ public class TicTacToeController extends AbstractGameController<BitboardTicTacTo
new TicTacToeCanvas(Color.GRAY, (App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3,(c) -> {new EventFlow().addPostEvent(GUIEvents.PlayerAttemptedMove.class, c).postEvent();}), new TicTacToeCanvas(Color.GRAY, (App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3,(c) -> {new EventFlow().addPostEvent(GUIEvents.PlayerAttemptedMove.class, c).postEvent();}),
players, players,
BitboardTicTacToe, BitboardTicTacToe,
local ? new LocalThreadBehaviour(BitboardTicTacToe) : new OnlineThreadBehaviour<>(BitboardTicTacToe, players), // TODO: Player order matters here, this won't work atm local ? new LocalThreadBehaviour(BitboardTicTacToe) : new OnlineThreadBehaviour<>(BitboardTicTacToe), // TODO: Player order matters here, this won't work atm
"TicTacToe"); "TicTacToe");
initUI(); initUI();

View File

@@ -12,7 +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}
*/ */
@Deprecated
public abstract class AbstractAI<T extends TurnBasedGame<T>> implements MoveProvider<T> { public abstract class AbstractAI<T extends TurnBasedGame<T>> implements MoveProvider<T> {
// Concrete AI implementations should override findBestMove(T game, int depth) // Concrete AI implementations should override findBestMove(T game, int depth)
} }

View File

@@ -42,7 +42,7 @@ public class NetworkingGameClientHandler extends ChannelInboundHandlerAdapter {
msg); msg);
new EventFlow() new EventFlow()
.addPostEvent(new NetworkEvents.ServerResponse(this.connectionId)) .addPostEvent(new NetworkEvents.ServerResponse(this.connectionId))
.asyncPostEvent(); .postEvent();
parseServerReturn(rec); parseServerReturn(rec);
return; return;
} }
@@ -117,7 +117,7 @@ public class NetworkingGameClientHandler extends ChannelInboundHandlerAdapter {
.addPostEvent( .addPostEvent(
new NetworkEvents.GameMoveResponse( new NetworkEvents.GameMoveResponse(
this.connectionId, msg[0], msg[1], msg[2])) this.connectionId, msg[0], msg[1], msg[2]))
.asyncPostEvent(); .postEvent();
} }
private void gameWinConditionHandler(String rec) { private void gameWinConditionHandler(String rec) {
@@ -130,7 +130,7 @@ public class NetworkingGameClientHandler extends ChannelInboundHandlerAdapter {
new EventFlow() new EventFlow()
.addPostEvent(new NetworkEvents.GameResultResponse(this.connectionId, condition)) .addPostEvent(new NetworkEvents.GameResultResponse(this.connectionId, condition))
.asyncPostEvent(); .postEvent();
} }
private void gameChallengeHandler(String rec) { private void gameChallengeHandler(String rec) {
@@ -149,13 +149,13 @@ public class NetworkingGameClientHandler extends ChannelInboundHandlerAdapter {
.addPostEvent( .addPostEvent(
new NetworkEvents.ChallengeCancelledResponse( new NetworkEvents.ChallengeCancelledResponse(
this.connectionId, msg[0])) this.connectionId, msg[0]))
.asyncPostEvent(); .postEvent();
else else
new EventFlow() new EventFlow()
.addPostEvent( .addPostEvent(
new NetworkEvents.ChallengeResponse( new NetworkEvents.ChallengeResponse(
this.connectionId, msg[0], msg[1], msg[2])) this.connectionId, msg[0], msg[1], msg[2]))
.asyncPostEvent(); .postEvent();
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
logger.error("Array out of bounds for: {}", rec, e); logger.error("Array out of bounds for: {}", rec, e);
} }
@@ -175,7 +175,7 @@ public class NetworkingGameClientHandler extends ChannelInboundHandlerAdapter {
.addPostEvent( .addPostEvent(
new NetworkEvents.GameMatchResponse( new NetworkEvents.GameMatchResponse(
this.connectionId, msg[0], msg[1], msg[2])) this.connectionId, msg[0], msg[1], msg[2]))
.asyncPostEvent(); .postEvent();
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
logger.error("Array out of bounds for: {}", rec, e); logger.error("Array out of bounds for: {}", rec, e);
} }
@@ -192,7 +192,7 @@ public class NetworkingGameClientHandler extends ChannelInboundHandlerAdapter {
new EventFlow() new EventFlow()
.addPostEvent(new NetworkEvents.YourTurnResponse(this.connectionId, msg)) .addPostEvent(new NetworkEvents.YourTurnResponse(this.connectionId, msg))
.asyncPostEvent(); .postEvent();
} }
private void playerlistHandler(String rec) { private void playerlistHandler(String rec) {
@@ -205,7 +205,7 @@ public class NetworkingGameClientHandler extends ChannelInboundHandlerAdapter {
new EventFlow() new EventFlow()
.addPostEvent(new NetworkEvents.PlayerlistResponse(this.connectionId, players)) .addPostEvent(new NetworkEvents.PlayerlistResponse(this.connectionId, players))
.asyncPostEvent(); .postEvent();
} }
private void gamelistHandler(String rec) { private void gamelistHandler(String rec) {
@@ -218,7 +218,7 @@ public class NetworkingGameClientHandler extends ChannelInboundHandlerAdapter {
new EventFlow() new EventFlow()
.addPostEvent(new NetworkEvents.GamelistResponse(this.connectionId, gameTypes)) .addPostEvent(new NetworkEvents.GamelistResponse(this.connectionId, gameTypes))
.asyncPostEvent(); .postEvent();
} }
private void helpHandler(String rec) { private void helpHandler(String rec) {

View File

@@ -4,6 +4,7 @@ import org.toop.framework.gameFramework.model.game.TurnBasedGame;
import org.toop.framework.gameFramework.model.player.Player; import org.toop.framework.gameFramework.model.player.Player;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class BitboardGame<T extends BitboardGame<T>> implements TurnBasedGame<T> { public abstract class BitboardGame<T extends BitboardGame<T>> implements TurnBasedGame<T> {
private final int columnSize; private final int columnSize;
@@ -13,14 +14,13 @@ public abstract class BitboardGame<T extends BitboardGame<T>> implements TurnBas
// 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; private AtomicInteger currentTurn = new AtomicInteger(0);
public BitboardGame(int columnSize, int rowSize, int playerCount, Player<T>[] players) { public BitboardGame(int columnSize, int rowSize, int playerCount, Player<T>[] players) {
this.columnSize = columnSize; this.columnSize = columnSize;
this.rowSize = rowSize; this.rowSize = rowSize;
this.players = players; this.players = players;
this.playerBitboard = new long[playerCount]; this.playerBitboard = new long[playerCount];
this.currentTurn = 0;
Arrays.fill(playerBitboard, 0L); Arrays.fill(playerBitboard, 0L);
} }
@@ -91,11 +91,12 @@ public abstract class BitboardGame<T extends BitboardGame<T>> implements TurnBas
public Player<T> getPlayer(int index) {return players[index];} public Player<T> getPlayer(int index) {return players[index];}
public int getCurrentPlayerIndex() { public int getCurrentPlayerIndex() {
return currentTurn % playerBitboard.length; System.out.println(currentTurn.get() % playerBitboard.length);
return currentTurn.get() % playerBitboard.length;
} }
public int getNextPlayer() { public int getNextPlayer() {
return (currentTurn + 1) % playerBitboard.length; return (currentTurn.get() + 1) % playerBitboard.length;
} }
public Player<T> getCurrentPlayer(){ public Player<T> getCurrentPlayer(){
@@ -103,6 +104,7 @@ public abstract class BitboardGame<T extends BitboardGame<T>> implements TurnBas
} }
public void nextTurn() { public void nextTurn() {
currentTurn++; System.out.println("Incrementing turn");
currentTurn.incrementAndGet();
} }
} }

View File

@@ -17,19 +17,12 @@ import org.toop.game.players.OnlinePlayer;
* 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<T extends TurnBasedGame<T>> extends AbstractThreadBehaviour<T> implements SupportsOnlinePlay {
/** The local player controlled by this client. */
private final Player<T> mainPlayer;
private final int playerTurn;
/** /**
* 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, Player<T>[] players) { public OnlineThreadBehaviour(T game) {
super(game); super(game);
this.playerTurn = getFirstNotOnlinePlayer(players);
this.mainPlayer = players[this.playerTurn];
} }
/** Finds the first non-online player in the array. */ /** Finds the first non-online player in the array. */
@@ -61,7 +54,7 @@ public class OnlineThreadBehaviour<T extends TurnBasedGame<T>> extends AbstractT
@Override @Override
public void onYourTurn(NetworkEvents.YourTurnResponse event) { public void onYourTurn(NetworkEvents.YourTurnResponse event) {
if (!isRunning.get()) return; if (!isRunning.get()) return;
int move = mainPlayer.getMove(game.deepCopy()); int move = game.getPlayer(game.getCurrentTurn()).getMove(game.deepCopy());
new EventFlow().addPostEvent(NetworkEvents.SendMove.class, event.clientId(), (short) move).postEvent(); new EventFlow().addPostEvent(NetworkEvents.SendMove.class, event.clientId(), (short) move).postEvent();
} }
@@ -83,9 +76,9 @@ public class OnlineThreadBehaviour<T extends TurnBasedGame<T>> extends AbstractT
@Override @Override
public void gameFinished(NetworkEvents.GameResultResponse event) { public void gameFinished(NetworkEvents.GameResultResponse event) {
switch(event.condition().toUpperCase()){ switch(event.condition().toUpperCase()){
case "WIN" -> new EventFlow().addPostEvent(GUIEvents.GameEnded.class, true, playerTurn).postEvent(); case "WIN" -> new EventFlow().addPostEvent(GUIEvents.GameEnded.class, true, game.getCurrentTurn()).postEvent();
case "DRAW" -> new EventFlow().addPostEvent(GUIEvents.GameEnded.class, false, AbstractGame.EMPTY).postEvent(); case "DRAW" -> new EventFlow().addPostEvent(GUIEvents.GameEnded.class, false, AbstractGame.EMPTY).postEvent();
case "LOSS" -> new EventFlow().addPostEvent(GUIEvents.GameEnded.class, true, (playerTurn + 1)%2).postEvent(); case "LOSS" -> new EventFlow().addPostEvent(GUIEvents.GameEnded.class, true, (game.getCurrentTurn() + 1)%2).postEvent();
default -> { default -> {
logger.error("Invalid condition"); logger.error("Invalid condition");
throw new RuntimeException("Unknown condition"); throw new RuntimeException("Unknown condition");

View File

@@ -1,6 +1,7 @@
package org.toop.game.gameThreads; package org.toop.game.gameThreads;
import org.toop.framework.gameFramework.model.game.AbstractGame; import org.toop.framework.gameFramework.model.game.AbstractGame;
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
import org.toop.framework.networking.events.NetworkEvents; import org.toop.framework.networking.events.NetworkEvents;
import org.toop.framework.gameFramework.model.player.AbstractPlayer; import org.toop.framework.gameFramework.model.player.AbstractPlayer;
@@ -11,16 +12,15 @@ import org.toop.framework.gameFramework.model.player.AbstractPlayer;
* 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 extends OnlineThreadBehaviour { public class OnlineWithSleepThreadBehaviour<T extends TurnBasedGame<T>> extends OnlineThreadBehaviour<T> {
/** /**
* 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
* @param players the list of local and remote players
*/ */
public OnlineWithSleepThreadBehaviour(AbstractGame game, AbstractPlayer[] players) { public OnlineWithSleepThreadBehaviour(T game) {
super(game, players); super(game);
} }
/** /**
@@ -32,7 +32,7 @@ public class OnlineWithSleepThreadBehaviour extends OnlineThreadBehaviour {
public void onYourTurn(NetworkEvents.YourTurnResponse event) { public void onYourTurn(NetworkEvents.YourTurnResponse event) {
try { try {
Thread.sleep(1000); Thread.sleep(50);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@@ -65,6 +65,7 @@ public class BitboardReversi extends BitboardGame<BitboardReversi> {
@Override @Override
public int[] getLegalMoves(){ public int[] getLegalMoves(){
System.out.println(Arrays.toString(translateLegalMoves(getLegalMoves2()))); System.out.println(Arrays.toString(translateLegalMoves(getLegalMoves2())));
System.out.println(Long.toBinaryString(getLegalMoves2()));
return translateLegalMoves(getLegalMoves2()); return translateLegalMoves(getLegalMoves2());
} }

View File

@@ -4,8 +4,8 @@ import org.toop.framework.gameFramework.model.player.AbstractAI;
import java.util.Random; import java.util.Random;
public final class ReversiAIR extends AbstractAI<ReversiR> { public final class ReversiAIR extends AbstractAI<BitboardReversi> {
public int getMove(ReversiR game) { public int getMove(BitboardReversi game) {
int[] moves = game.getLegalMoves(); int[] moves = game.getLegalMoves();
if (moves.length == 0) return -1; if (moves.length == 0) return -1;

View File

@@ -13,7 +13,7 @@ import org.toop.framework.gameFramework.GameState;
* opening or when no clear best move is found. * opening or when no clear best move is found.
* </p> * </p>
*/ */
public final class TicTacToeAIR extends AbstractAI<TicTacToeR> { public final class TicTacToeAIR extends AbstractAI<BitboardTicTacToe> {
/** /**
* Determines the best move for the given Tic-Tac-Toe game state. * Determines the best move for the given Tic-Tac-Toe game state.
@@ -27,7 +27,7 @@ public final class TicTacToeAIR extends AbstractAI<TicTacToeR> {
* @param depth the depth of lookahead for evaluating moves (non-negative) * @param depth the depth of lookahead for evaluating moves (non-negative)
* @return the index of the best move, or -1 if no moves are available * @return the index of the best move, or -1 if no moves are available
*/ */
public int getMove(TicTacToeR game) { public int getMove(BitboardTicTacToe game) {
int depth = 9; int depth = 9;
assert game != null; assert game != null;
final int[] legalMoves = game.getLegalMoves(); final int[] legalMoves = game.getLegalMoves();
@@ -71,8 +71,8 @@ public final class TicTacToeAIR extends AbstractAI<TicTacToeR> {
* @param maximizing true if the AI is to maximize score, false if minimizing * @param maximizing true if the AI is to maximize score, false if minimizing
* @return the score of the move * @return the score of the move
*/ */
private int getMoveScore(TicTacToeR game, int depth, int move, boolean maximizing) { private int getMoveScore(BitboardTicTacToe game, int depth, int move, boolean maximizing) {
final TicTacToeR copy = game.deepCopy(); final BitboardTicTacToe copy = game.deepCopy();
final PlayResult result = copy.play(move); final PlayResult result = copy.play(move);
GameState state = result.state(); GameState state = result.state();