Fixed local and online play for both games

This commit is contained in:
2025-12-04 20:50:58 +01:00
parent be57e25a48
commit 86e740a34a
6 changed files with 42 additions and 42 deletions

View File

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

View File

@@ -1,10 +1,9 @@
package org.toop.app.gameControllers; package org.toop.app.gameControllers;
import org.toop.app.canvas.GameCanvas;
import org.toop.app.canvas.TicTacToeBitCanvas; 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.game.threadBehaviour.ThreadBehaviour;
import org.toop.framework.gameFramework.model.player.Player; import org.toop.framework.gameFramework.model.player.Player;
import org.toop.game.gameThreads.LocalFixedRateThreadBehaviour;
import org.toop.game.gameThreads.LocalThreadBehaviour; import org.toop.game.gameThreads.LocalThreadBehaviour;
import org.toop.game.gameThreads.OnlineThreadBehaviour; import org.toop.game.gameThreads.OnlineThreadBehaviour;
import org.toop.game.gameThreads.OnlineWithSleepThreadBehaviour; import org.toop.game.gameThreads.OnlineWithSleepThreadBehaviour;
@@ -17,7 +16,7 @@ public class TicTacToeBitController extends GenericGameController<BitboardTicTac
ThreadBehaviour thread = new LocalThreadBehaviour<>(game); ThreadBehaviour thread = new LocalThreadBehaviour<>(game);
for (Player<BitboardTicTacToe> player : players) { for (Player<BitboardTicTacToe> player : players) {
if (player instanceof OnlinePlayer<BitboardTicTacToe>){ if (player instanceof OnlinePlayer<BitboardTicTacToe>){
thread = new OnlineWithSleepThreadBehaviour<>(game); thread = new OnlineThreadBehaviour<>(game);
} }
} }
super(new TicTacToeBitCanvas(), game, thread , "TicTacToe"); super(new TicTacToeBitCanvas(), game, thread , "TicTacToe");

View File

@@ -5,6 +5,8 @@ import org.toop.app.GameInformation;
import org.toop.app.canvas.ReversiBitCanvas; import org.toop.app.canvas.ReversiBitCanvas;
import org.toop.app.canvas.TicTacToeBitCanvas; import org.toop.app.canvas.TicTacToeBitCanvas;
import org.toop.app.gameControllers.GenericGameController; import org.toop.app.gameControllers.GenericGameController;
import org.toop.app.gameControllers.ReversiBitController;
import org.toop.app.gameControllers.TicTacToeBitController;
import org.toop.framework.gameFramework.controller.GameController; 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.game.gameThreads.LocalThreadBehaviour; import org.toop.game.gameThreads.LocalThreadBehaviour;
@@ -70,20 +72,17 @@ public class LocalMultiplayerView extends ViewWidget {
if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstTTT()) { if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstTTT()) {
new ShowEnableTutorialWidget( new ShowEnableTutorialWidget(
() -> new TicTacToeTutorialWidget(() -> { () -> new TicTacToeTutorialWidget(() -> {
BitboardTicTacToe game = new BitboardTicTacToe(players); // TODO: ThreadBehaviour might need to be created by game idk gameController = new TicTacToeBitController(players);
gameController = new GenericGameController<BitboardTicTacToe>(new TicTacToeBitCanvas(), game, new LocalThreadBehaviour<BitboardTicTacToe>(game), "TicTacToe");
gameController.start(); gameController.start();
}), }),
() -> Platform.runLater(() -> { () -> Platform.runLater(() -> {
BitboardTicTacToe game = new BitboardTicTacToe(players); // TODO: ThreadBehaviour might need to be created by game idk gameController = new TicTacToeBitController(players);
gameController = new GenericGameController<BitboardTicTacToe>(new TicTacToeBitCanvas(), game, new LocalThreadBehaviour<BitboardTicTacToe>(game), "TicTacToe");
gameController.start(); gameController.start();
}), }),
() -> AppSettings.getSettings().setFirstTTT(false) () -> AppSettings.getSettings().setFirstTTT(false)
); );
} else { } else {
BitboardTicTacToe game = new BitboardTicTacToe(players); // TODO: ThreadBehaviour might need to be created by game idk gameController = new TicTacToeBitController(players);
gameController = new GenericGameController<BitboardTicTacToe>(new TicTacToeBitCanvas(), game, new LocalThreadBehaviour<BitboardTicTacToe>(game), "TicTacToe");
gameController.start(); gameController.start();
} }
break; break;
@@ -101,20 +100,17 @@ public class LocalMultiplayerView extends ViewWidget {
if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstReversi()) { if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstReversi()) {
new ShowEnableTutorialWidget( new ShowEnableTutorialWidget(
() -> new ReversiTutorialWidget(() -> { () -> new ReversiTutorialWidget(() -> {
BitboardReversi game = new BitboardReversi(players); gameController = new ReversiBitController(players);
gameController = new GenericGameController<>(new ReversiBitCanvas(), game, new LocalThreadBehaviour<>(game), "Reversi");
gameController.start(); gameController.start();
}), }),
() -> Platform.runLater(() -> { () -> Platform.runLater(() -> {
BitboardReversi game = new BitboardReversi(players); gameController = new ReversiBitController(players);
gameController = new GenericGameController<>(new ReversiBitCanvas(), game, new LocalThreadBehaviour<>(game), "Reversi");
gameController.start(); gameController.start();
}), }),
() -> AppSettings.getSettings().setFirstReversi(false) () -> AppSettings.getSettings().setFirstReversi(false)
); );
} else { } else {
BitboardReversi game = new BitboardReversi(players); gameController = new ReversiBitController(players);
gameController = new GenericGameController<>(new ReversiBitCanvas(), game, new LocalThreadBehaviour<>(game), "Reversi");
gameController.start(); gameController.start();
} }
break; break;

View File

@@ -14,7 +14,7 @@ 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 AtomicInteger currentTurn = new AtomicInteger(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<T>[] players) {
this.columnSize = columnSize; this.columnSize = columnSize;
@@ -91,12 +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() {
System.out.println(currentTurn.get() % playerBitboard.length); System.out.println(currentTurn % playerBitboard.length);
return currentTurn.get() % playerBitboard.length; return currentTurn % playerBitboard.length;
} }
public int getNextPlayer() { public int getNextPlayer() {
return (currentTurn.get() + 1) % playerBitboard.length; return (currentTurn + 1) % playerBitboard.length;
} }
public Player<T> getCurrentPlayer(){ public Player<T> getCurrentPlayer(){
@@ -105,6 +105,6 @@ public abstract class BitboardGame<T extends BitboardGame<T>> implements TurnBas
public void nextTurn() { public void nextTurn() {
System.out.println("Incrementing turn"); System.out.println("Incrementing turn");
currentTurn.incrementAndGet(); currentTurn++;
} }
} }

View File

@@ -16,18 +16,14 @@ import org.toop.framework.gameFramework.model.player.Player;
*/ */
public class LocalFixedRateThreadBehaviour<T extends TurnBasedGame<T>> extends AbstractThreadBehaviour<T> implements Runnable { public class LocalFixedRateThreadBehaviour<T extends TurnBasedGame<T>> extends AbstractThreadBehaviour<T> implements Runnable {
/** All players participating in the game. */
private final Player<T>[] players;
/** /**
* Creates a fixed-rate behaviour for a local turn-based game. * Creates a fixed-rate behaviour for a local turn-based game.
* *
* @param game the game instance * @param game the game instance
* @param players the list of players in turn order
*/ */
public LocalFixedRateThreadBehaviour(T game, Player<T>[] players) { public LocalFixedRateThreadBehaviour(T game) {
super(game); super(game);
this.players = players;
} }
/** Starts the game loop thread if not already running. */ /** Starts the game loop thread if not already running. */
@@ -52,7 +48,7 @@ public class LocalFixedRateThreadBehaviour<T extends TurnBasedGame<T>> extends A
*/ */
@Override @Override
public void run() { public void run() {
final int UPS = 60; final int UPS = 1;
final long UPDATE_INTERVAL = 1_000_000_000L / UPS; final long UPDATE_INTERVAL = 1_000_000_000L / UPS;
long nextUpdate = System.nanoTime(); long nextUpdate = System.nanoTime();

View File

@@ -20,6 +20,9 @@ public class BitboardTicTacToe extends BitboardGame<BitboardTicTacToe> {
public BitboardTicTacToe(Player<BitboardTicTacToe>[] players) { public BitboardTicTacToe(Player<BitboardTicTacToe>[] players) {
super(3, 3, 2, players); super(3, 3, 2, players);
} }
public BitboardTicTacToe(BitboardTicTacToe other) {
super(other);
}
@Override @Override
public int[] getLegalMoves(){ public int[] getLegalMoves(){
@@ -28,7 +31,7 @@ public class BitboardTicTacToe extends BitboardGame<BitboardTicTacToe> {
@Override @Override
public PlayResult play(int move) { public PlayResult play(int move) {
return new PlayResult(play2(translateMove(move)), getCurrentPlayerIndex()); return play2(translateMove(move));
} }
public long getLegalMoves2() { public long getLegalMoves2() {
@@ -39,24 +42,34 @@ public class BitboardTicTacToe extends BitboardGame<BitboardTicTacToe> {
return (~taken) & 0x1ffL; return (~taken) & 0x1ffL;
} }
public GameState play2(long move) { public PlayResult play2(long move) {
// Player loses if move is invalid
if ((move & getLegalMoves2()) == 0 || Long.bitCount(move) != 1){
return new PlayResult(GameState.WIN, getNextPlayer());
}
// Move is legal, make move
long playerBitboard = getPlayerBitboard(getCurrentPlayerIndex()); long playerBitboard = getPlayerBitboard(getCurrentPlayerIndex());
playerBitboard |= move; playerBitboard |= move;
setPlayerBitboard(getCurrentPlayerIndex(), playerBitboard); setPlayerBitboard(getCurrentPlayerIndex(), playerBitboard);
// Check if current player won
if (checkWin(playerBitboard)) {
return new PlayResult(GameState.WIN, getCurrentPlayerIndex());
}
// Proceed to next turn
nextTurn(); nextTurn();
if (checkWin(playerBitboard)) {
return GameState.WIN;
}
// Check for early draw
if (getLegalMoves2() == 0L || checkEarlyDraw()) { if (getLegalMoves2() == 0L || checkEarlyDraw()) {
return GameState.DRAW; return new PlayResult(GameState.DRAW, -1);
} }
// Nothing weird happened, continue on as normal
return new PlayResult(GameState.NORMAL, -1);
return GameState.NORMAL;
} }
private boolean checkWin(long board) { private boolean checkWin(long board) {
@@ -94,9 +107,8 @@ public class BitboardTicTacToe extends BitboardGame<BitboardTicTacToe> {
return translateBoard(); return translateBoard();
} }
// TODO: Implement
@Override @Override
public BitboardTicTacToe deepCopy() { public BitboardTicTacToe deepCopy() {
return this; return new BitboardTicTacToe(this);
} }
} }