diff --git a/game/src/main/java/org/toop/game/GameController.java b/app/src/main/java/org/toop/app/game/GameController.java similarity index 56% rename from game/src/main/java/org/toop/game/GameController.java rename to app/src/main/java/org/toop/app/game/GameController.java index ff24bb2..e27c08e 100644 --- a/game/src/main/java/org/toop/game/GameController.java +++ b/app/src/main/java/org/toop/app/game/GameController.java @@ -1,17 +1,24 @@ -/*package org.toop.game; +package org.toop.app.game; import org.toop.app.canvas.GameCanvas; import org.toop.app.game.TurnBasedGameThread; import org.toop.app.widget.view.GameView; public abstract class GameController implements UpdatesGameUI { - // TODO: Seperate this from game Thread + // Reference to primary view protected final GameView primary = new GameView(null, null, null); - protected final GameCanvas canvas; - protected final TurnBasedGameThread gameThread; - protected GameController(GameCanvas canvas, TurnBasedGameThread gameThread) { - this.gameThread = gameThread; + // Reference to game canvas + protected final GameCanvas canvas; + + // Reference to gameThread + protected TurnBasedGameThread gameThread; + + protected GameController(GameCanvas canvas) { this.canvas = canvas; } -}*/ + + protected void setThread(TurnBasedGameThread gameThread){ + this.gameThread = gameThread; + } +} diff --git a/app/src/main/java/org/toop/app/game/TicTacToeController.java b/app/src/main/java/org/toop/app/game/TicTacToeController.java new file mode 100644 index 0000000..eb97545 --- /dev/null +++ b/app/src/main/java/org/toop/app/game/TicTacToeController.java @@ -0,0 +1,47 @@ +package org.toop.app.game; + +import javafx.geometry.Pos; +import javafx.scene.paint.Color; +import org.toop.app.App; +import org.toop.app.canvas.TicTacToeCanvas; +import org.toop.app.game.Players.LocalPlayer; +import org.toop.app.game.Players.Player; +import org.toop.app.widget.WidgetContainer; +import org.toop.game.tictactoe.TicTacToeR; + +public class TicTacToeController extends GameController { + + public TicTacToeController(Player[] players) { + TicTacToeR ticTacToeR = new TicTacToeR(); + super(new TicTacToeCanvas(Color.GRAY, + (App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3,(c) -> {if (players[ticTacToeR.getCurrentTurn()] instanceof LocalPlayer lp) {lp.enqueueMove(c);}})); + // TODO: Deal with this thread better. Can't give it to super because of "this" refence. + setThread(new TurnBasedGameThread(players, ticTacToeR, this)); + + initUI(); + } + + @Override + public void updateUI() { + canvas.clearAll(); + drawMoves(); + } + + private void initUI(){ + primary.add(Pos.CENTER, canvas.getCanvas()); + WidgetContainer.getCurrentView().transitionNext(primary); + } + + private void drawMoves(){ + int[] board = gameThread.getBoard(); + + // Draw each move + for (int i = 0; i < board.length; i++){ + switch(board[i]){ + case 0 -> canvas.drawChar('X', Color.RED, i); + case 1 -> canvas.drawChar('O', Color.BLUE, i); + default -> {} + } + } + } +} diff --git a/app/src/main/java/org/toop/app/game/TurnBasedGameThread.java b/app/src/main/java/org/toop/app/game/TurnBasedGameThread.java index f2506bd..dfb285f 100644 --- a/app/src/main/java/org/toop/app/game/TurnBasedGameThread.java +++ b/app/src/main/java/org/toop/app/game/TurnBasedGameThread.java @@ -1,97 +1,75 @@ package org.toop.app.game; -import javafx.geometry.Pos; -import javafx.scene.paint.Color; -import org.toop.app.App; -import org.toop.app.canvas.GameCanvas; -import org.toop.app.canvas.TicTacToeCanvas; -import org.toop.app.game.Players.LocalPlayer; import org.toop.app.game.Players.Player; -import org.toop.app.widget.WidgetContainer; -import org.toop.app.widget.view.GameView; + +import org.toop.game.PlayResult; import org.toop.game.TurnBasedGameR; import org.toop.game.enumerators.GameState; -import java.util.Arrays; import java.util.concurrent.atomic.AtomicBoolean; public class TurnBasedGameThread implements Runnable { private final Player[] players; // List of players, can't be changed. private final TurnBasedGameR game; // Reference to game instance - private final AtomicBoolean isRunning = new AtomicBoolean(); - //private final GameController controller; - - protected final GameView primary = new GameView(null, null, null); - protected final GameCanvas canvas; - - public TurnBasedGameThread(Player[] players, TurnBasedGameR game) { - // Set reference to controller - //this.controller = controller; + private final AtomicBoolean isRunning = new AtomicBoolean(true); + private final GameController controller; + public TurnBasedGameThread(Player[] players, TurnBasedGameR game, GameController controller) { // Make sure player list matches expected size if (players.length != game.getPlayerCount()){ throw new IllegalArgumentException("players and game's players must have same length"); } + // Set vars + this.controller = controller; this.players = players; this.game = game; + // Create and run thread Thread thread = new Thread(this::run); thread.start(); + } - // UI SHIZ TO MOVE - canvas = new TicTacToeCanvas(Color.GRAY, - (App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3,(c) -> {if (players[game.getCurrentTurn()] instanceof LocalPlayer lp) {lp.enqueueMove(c);}}); - primary.add(Pos.CENTER, canvas.getCanvas()); - WidgetContainer.getCurrentView().transitionNext(primary); - + public int[] getBoard(){ + return game.getBoard(); } public Player[] getPlayers() { return players; } - // Move to UI shiz - private void drawMove(int move) { - if (game.getCurrentTurn() == 1){ - canvas.drawChar('X', Color.RED, move); - } - else{ - canvas.drawChar('O', Color.RED, move); - } - } - public void run() { - isRunning.set(true); - // Game logic loop while(isRunning.get()) { // Get current player Player currentPlayer = players[game.getCurrentTurn()]; - System.out.println(game.getCurrentTurn() + "'s turn"); + // Get this player's valid moves int[] validMoves = game.getLegalMoves(); - // Get player's move, reask if Move is invalid + // Make sure provided move is valid // TODO: Limit amount of retries? int move = currentPlayer.getMove(game.clone()); while (!contains(validMoves, move)) { move = currentPlayer.getMove(game.clone()); } - // Make move - System.out.println(Arrays.toString(game.getBoard())); - GameState state = game.play(move); - drawMove(move); + // Make move + PlayResult result = game.play(move); + + // Tell controller to update UI + controller.updateUI(); + GameState state = result.state(); if (state != GameState.NORMAL) { if (state == GameState.WIN) { - // Someone won + // Win, do something + System.out.println(result.winner() + " WON"); } else if (state == GameState.DRAW) { - // THere was a draw + // Draw, do something + System.out.println("DRAW"); } - System.out.println(state); isRunning.set(false); } } diff --git a/game/src/main/java/org/toop/game/UpdatesGameUI.java b/app/src/main/java/org/toop/app/game/UpdatesGameUI.java similarity index 67% rename from game/src/main/java/org/toop/game/UpdatesGameUI.java rename to app/src/main/java/org/toop/app/game/UpdatesGameUI.java index 89cd195..503037c 100644 --- a/game/src/main/java/org/toop/game/UpdatesGameUI.java +++ b/app/src/main/java/org/toop/app/game/UpdatesGameUI.java @@ -1,4 +1,4 @@ -package org.toop.game; +package org.toop.app.game; public interface UpdatesGameUI { void updateUI(); diff --git a/app/src/main/java/org/toop/app/widget/view/LocalMultiplayerView.java b/app/src/main/java/org/toop/app/widget/view/LocalMultiplayerView.java index 68cd088..757358a 100644 --- a/app/src/main/java/org/toop/app/widget/view/LocalMultiplayerView.java +++ b/app/src/main/java/org/toop/app/widget/view/LocalMultiplayerView.java @@ -36,7 +36,7 @@ public class LocalMultiplayerView extends ViewWidget { } switch (information.type) { - case TICTACTOE -> new TurnBasedGameThread(new Player[]{new LocalPlayer(), new ArtificialPlayer<>(new TicTacToeAIR())}, new TicTacToeR()); + case TICTACTOE -> new TicTacToeController(new Player[]{new LocalPlayer(), new ArtificialPlayer<>(new TicTacToeAIR())}); case REVERSI -> new ReversiGame(information); case CONNECT4 -> new Connect4Game(information); // case BATTLESHIP -> new BattleshipGame(information); diff --git a/game/src/main/java/org/toop/game/PlayResult.java b/game/src/main/java/org/toop/game/PlayResult.java new file mode 100644 index 0000000..36737bc --- /dev/null +++ b/game/src/main/java/org/toop/game/PlayResult.java @@ -0,0 +1,6 @@ +package org.toop.game; + +import org.toop.game.enumerators.GameState; + +public record PlayResult(GameState state, int winner) { +} diff --git a/game/src/main/java/org/toop/game/TicTacToeController.java b/game/src/main/java/org/toop/game/TicTacToeController.java deleted file mode 100644 index c09e53a..0000000 --- a/game/src/main/java/org/toop/game/TicTacToeController.java +++ /dev/null @@ -1,24 +0,0 @@ -/*package org.toop.game; - -import javafx.geometry.Pos; -import javafx.scene.paint.Color; -import org.toop.app.App; -import org.toop.app.canvas.TicTacToeCanvas; -import org.toop.app.game.Players.LocalPlayer; -import org.toop.app.game.TurnBasedGameThread; -import org.toop.app.widget.WidgetContainer; - -public class TicTacToeController extends GameController { - - public TicTacToeController() { - super(new TicTacToeCanvas(Color.GRAY, - (App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3,(c) -> {if (players[game.getCurrentTurn()] instanceof LocalPlayer lp) {lp.enqueueMove(c);}}), new TurnBasedGameThread()); - primary.add(Pos.CENTER, canvas.getCanvas()); - WidgetContainer.getCurrentView().transitionNext(primary)); - } - - @Override - public void updateUI() { - - } -}*/ diff --git a/game/src/main/java/org/toop/game/TurnBasedGameR.java b/game/src/main/java/org/toop/game/TurnBasedGameR.java index f3b65a8..d5b576a 100644 --- a/game/src/main/java/org/toop/game/TurnBasedGameR.java +++ b/game/src/main/java/org/toop/game/TurnBasedGameR.java @@ -12,6 +12,7 @@ public abstract class TurnBasedGameR extends GameR { protected TurnBasedGameR(TurnBasedGameR other){ super(other); this.playerCount = other.playerCount; + this.turn = other.turn; } public int getPlayerCount(){return this.playerCount;} diff --git a/game/src/main/java/org/toop/game/interfaces/IPlayableR.java b/game/src/main/java/org/toop/game/interfaces/IPlayableR.java index 677617f..6d86231 100644 --- a/game/src/main/java/org/toop/game/interfaces/IPlayableR.java +++ b/game/src/main/java/org/toop/game/interfaces/IPlayableR.java @@ -1,5 +1,6 @@ package org.toop.game.interfaces; +import org.toop.game.PlayResult; import org.toop.game.enumerators.GameState; /** @@ -26,5 +27,5 @@ public interface IPlayableR { * @param move the move to play, represented as an integer * @return the {@link GameState} after the move is played */ - GameState play(int move); + PlayResult play(int move); } diff --git a/game/src/main/java/org/toop/game/tictactoe/TicTacToeAIR.java b/game/src/main/java/org/toop/game/tictactoe/TicTacToeAIR.java index f9b2fb6..1fddcfc 100644 --- a/game/src/main/java/org/toop/game/tictactoe/TicTacToeAIR.java +++ b/game/src/main/java/org/toop/game/tictactoe/TicTacToeAIR.java @@ -1,8 +1,11 @@ package org.toop.game.tictactoe; import org.toop.game.AIR; +import org.toop.game.PlayResult; import org.toop.game.enumerators.GameState; +import java.util.Arrays; + /** * AI implementation for playing Tic-Tac-Toe. *
@@ -30,13 +33,14 @@ public final class TicTacToeAIR extends AIR