diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 655cfae..e0e273b 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -2,7 +2,7 @@
-
+
diff --git a/app/src/main/java/org/toop/Main.java b/app/src/main/java/org/toop/Main.java
index bd330d2..3b4fef3 100644
--- a/app/src/main/java/org/toop/Main.java
+++ b/app/src/main/java/org/toop/Main.java
@@ -4,50 +4,6 @@ import org.toop.app.App;
public final class Main {
static void main(String[] args) {
- App.run(args);
- // testMCTS(10);
+ App.run(args);
}
-
- // Voor onderzoek
- // private static void testMCTS(int games) {
- // var random = new ArtificialPlayer<>(new RandomAI(), "Random AI");
- // var v1 = new ArtificialPlayer<>(new MCTSAI(10), "MCTS V1 AI");
- // var v2 = new ArtificialPlayer<>(new MCTSAI2(10), "MCTS V2 AI");
- // var v2_2 = new ArtificialPlayer<>(new MCTSAI2(100), "MCTS V2_2 AI");
- // var v3 = new ArtificialPlayer<>(new MCTSAI3(10), "MCTS V3 AI");
-
- // testAI(games, new Player[]{ v1, v2 });
- // // testAI(games, new Player[]{ v1, v3 });
-
- // // testAI(games, new Player[]{ random, v3 });
- // // testAI(games, new Player[]{ v2, v3 });
- // testAI(games, new Player[]{ v2, v3 });
- // // testAI(games, new Player[]{ v3, v2 });
- // }
-
- // private static void testAI(int games, Player[] ais) {
- // int wins = 0;
- // int ties = 0;
-
- // for (int i = 0; i < games; i++) {
- // final BitboardReversi match = new BitboardReversi(ais);
-
- // while (!match.isTerminal()) {
- // final int currentAI = match.getCurrentTurn();
- // final long move = ais[currentAI].getMove(match);
-
- // match.play(move);
- // }
-
- // if (match.getWinner() < 0) {
- // ties++;
- // continue;
- // }
-
- // wins += match.getWinner() == 0? 1 : 0;
- // }
-
- // System.out.printf("Out of %d games, %s won %d -- tied %d -- lost %d, games against %s\n", games, ais[0].getName(), wins, ties, games - wins - ties, ais[1].getName());
- // System.out.printf("Average win rate was: %.2f\n\n", wins / (float)games);
- // }
}
diff --git a/app/src/main/java/org/toop/app/Server.java b/app/src/main/java/org/toop/app/Server.java
index f6bcdec..d8c4acf 100644
--- a/app/src/main/java/org/toop/app/Server.java
+++ b/app/src/main/java/org/toop/app/Server.java
@@ -11,6 +11,7 @@ import org.toop.app.widget.popup.ErrorPopup;
import org.toop.app.widget.popup.SendChallengePopup;
import org.toop.app.widget.view.ServerView;
import org.toop.framework.eventbus.EventFlow;
+import org.toop.framework.game.players.ArtificialPlayer;
import org.toop.framework.game.players.OnlinePlayer;
import org.toop.framework.gameFramework.controller.GameController;
import org.toop.framework.eventbus.GlobalEventBus;
@@ -19,9 +20,10 @@ import org.toop.framework.networking.connection.clients.TournamentNetworkingClie
import org.toop.framework.networking.connection.events.NetworkEvents;
import org.toop.framework.networking.connection.types.NetworkingConnector;
import org.toop.framework.networking.server.gateway.NettyGatewayServer;
-import org.toop.framework.game.players.LocalPlayer;
+import org.toop.game.players.ai.mcts.MCTSAI3;
import org.toop.local.AppContext;
+import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
@@ -117,7 +119,8 @@ public final class Server {
return;
}
- primary = new ServerView(user, this::sendChallenge, clientId);
+ primary = new ServerView(user, this::sendChallenge, user, clientId);
+
WidgetContainer.getCurrentView().transitionNextCustom(primary, "disconnect", this::disconnect);
a.unsubscribe("connecting");
@@ -159,7 +162,8 @@ public final class Server {
.listen(NetworkEvents.GameResultResponse.class, this::handleGameResult, false, "game-result")
.listen(NetworkEvents.GameMoveResponse.class, this::handleReceivedMove, false, "game-move")
.listen(NetworkEvents.YourTurnResponse.class, this::handleYourTurn, false, "your-turn")
- .listen(NetworkEvents.ClosedConnection.class, this::closedConnection, false, "closed-connection");
+ .listen(NetworkEvents.ClosedConnection.class, this::closedConnection, false, "closed-connection")
+ .listen(NetworkEvents.TournamentResultResponse.class, this::handleTournamentResult, false, "tournament-result");
connectFlow = a;
}
@@ -205,7 +209,8 @@ public final class Server {
information.players[opponentStartingTurn].name = response.opponent();
Player[] players = new Player[2];
- players[userStartingTurn] = new LocalPlayer(user);
+
+ players[userStartingTurn] = new ArtificialPlayer(new MCTSAI3(1000, 8), user);
players[opponentStartingTurn] = new OnlinePlayer(response.opponent());
switch (type) {
@@ -238,6 +243,13 @@ public final class Server {
gameController.gameFinished(response);
}
+ private void handleTournamentResult(NetworkEvents.TournamentResultResponse response) {
+ IO.println(response.gameType());
+ IO.println(Arrays.toString(response.names()));
+ IO.println(Arrays.toString(response.scoreTypes()));
+ IO.println(Arrays.toString(response.scores().toArray()));
+ }
+
private void handleReceivedMove(NetworkEvents.GameMoveResponse response) {
if (gameController == null) {
return;
@@ -337,7 +349,8 @@ public final class Server {
private void gamesListFromServerHandler(NetworkEvents.GamelistResponse event) {
gameList.clear();
- var gl = List.of(event.gamelist());
+ var gl = new java.util.ArrayList<>(List.of(event.gamelist()));
+ gl.sort(String::compareTo);
gameList.addAll(gl);
primary.updateGameList(gl);
}
diff --git a/app/src/main/java/org/toop/app/canvas/ReversiBitCanvas.java b/app/src/main/java/org/toop/app/canvas/ReversiBitCanvas.java
index 685a985..d210b16 100644
--- a/app/src/main/java/org/toop/app/canvas/ReversiBitCanvas.java
+++ b/app/src/main/java/org/toop/app/canvas/ReversiBitCanvas.java
@@ -2,9 +2,13 @@ package org.toop.app.canvas;
import javafx.scene.paint.Color;
import org.toop.app.App;
+import org.toop.framework.game.games.reversi.BitboardReversi;
+import org.toop.framework.game.players.LocalPlayer;
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
public class ReversiBitCanvas extends BitGameCanvas {
+ private TurnBasedGame gameCopy;
+ private int previousCell;
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);
canvas.setOnMouseMoved(event -> {
@@ -20,6 +24,9 @@ public class ReversiBitCanvas extends BitGameCanvas {
break;
}
}
+ if (hovered != null) {
+ checkHoverDots(hovered, cellId);
+ }
});
}
@@ -31,9 +38,31 @@ public class ReversiBitCanvas extends BitGameCanvas {
@Override
public void redraw(TurnBasedGame gameCopy) {
+ this.gameCopy = gameCopy;
clearAll();
long[] board = gameCopy.getBoard();
loopOverBoard(board[0], (i) -> drawDot(Color.WHITE, i));
loopOverBoard(board[1], (i) -> drawDot(Color.BLACK, i));
}
+
+ public void drawLegalDots(TurnBasedGame gameCopy){
+ long legal = gameCopy.getLegalMoves();
+ loopOverBoard(legal, (i) -> drawInnerDot(gameCopy.getCurrentTurn()==0?new Color(1f,1f,1f,0.65f) :new Color(0f,0f,0f,0.65f), i,false));
+ }
+
+ private void checkHoverDots(BitGameCanvas.Cell hovered, int cellId){
+ if (previousCell == cellId){
+ return;
+ }
+ long backflips = ((BitboardReversi)gameCopy).getFlips(1L << previousCell);
+ loopOverBoard(backflips, (i) -> drawInnerDot(gameCopy.getCurrentTurn()==1?Color.WHITE:Color.BLACK, i,true));
+ previousCell = cellId;
+ if (gameCopy.getPlayer(gameCopy.getCurrentTurn()) instanceof LocalPlayer) {
+ long legal = gameCopy.getLegalMoves();
+ if ((legal & (1L << cellId)) != 0) {
+ long flips = ((BitboardReversi) gameCopy).getFlips(1L << cellId);
+ loopOverBoard(flips, (i) -> drawInnerDot(gameCopy.getCurrentTurn() == 0 ? Color.WHITE : Color.BLACK, i, false));
+ }
+ }
+ }
}
diff --git a/app/src/main/java/org/toop/app/gameControllers/GenericGameController.java b/app/src/main/java/org/toop/app/gameControllers/GenericGameController.java
index 0c68a74..d31c60d 100644
--- a/app/src/main/java/org/toop/app/gameControllers/GenericGameController.java
+++ b/app/src/main/java/org/toop/app/gameControllers/GenericGameController.java
@@ -5,10 +5,12 @@ import javafx.geometry.Pos;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.toop.app.canvas.GameCanvas;
+import org.toop.app.canvas.ReversiBitCanvas;
import org.toop.app.widget.WidgetContainer;
import org.toop.app.widget.view.GameView;
import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.eventbus.GlobalEventBus;
+import org.toop.framework.game.games.reversi.BitboardReversi;
import org.toop.framework.gameFramework.controller.GameController;
import org.toop.framework.gameFramework.model.game.threadBehaviour.SupportsOnlinePlay;
import org.toop.framework.gameFramework.model.game.TurnBasedGame;
@@ -153,6 +155,18 @@ public class GenericGameController implements GameController {
@Override
public void updateUI() {
- canvas.redraw(game.deepCopy());
+ TurnBasedGame gameCopy = game.deepCopy();
+ canvas.redraw(gameCopy);
+ String gameType = game.getClass().getSimpleName().replace("Bitboard","");
+ gameView.nextPlayer(true, getCurrentPlayer().getName(), game.getPlayer(1-getCurrentPlayerIndex()).getName(),gameType);
+ if (gameType.equals("Reversi")) {
+ BitboardReversi reversiGame = (BitboardReversi) game;
+ BitboardReversi.Score reversiScore = reversiGame.getScore();
+ gameView.setPlayer1Score(reversiScore.black());
+ gameView.setPlayer2Score(reversiScore.white());
+ if (getCurrentPlayer() instanceof LocalPlayer) {
+ ((ReversiBitCanvas)canvas).drawLegalDots(gameCopy);
+ }
+ }
}
}
diff --git a/app/src/main/java/org/toop/app/gameControllers/ReversiBitController.java b/app/src/main/java/org/toop/app/gameControllers/ReversiBitController.java
index 1ea8109..8954a62 100644
--- a/app/src/main/java/org/toop/app/gameControllers/ReversiBitController.java
+++ b/app/src/main/java/org/toop/app/gameControllers/ReversiBitController.java
@@ -11,13 +11,19 @@ import org.toop.framework.game.players.OnlinePlayer;
import java.util.Arrays;
public class ReversiBitController extends GenericGameController {
+
+ private BitboardReversi game;
+
public ReversiBitController(Player[] players) {
BitboardReversi game = new BitboardReversi();
game.init(players);
-
ThreadBehaviour thread = Arrays.stream(players).anyMatch(e -> e instanceof OnlinePlayer) ?
new OnlineThreadBehaviour(game) : new LocalThreadBehaviour(game);
super(new ReversiBitCanvas(), game, thread, "Reversi");
}
+
+ public BitboardReversi.Score getScore() {
+ return game.getScore();
+ }
}
diff --git a/app/src/main/java/org/toop/app/widget/popup/GameOverPopup.java b/app/src/main/java/org/toop/app/widget/popup/GameOverPopup.java
index ab1ef3d..9c9f961 100644
--- a/app/src/main/java/org/toop/app/widget/popup/GameOverPopup.java
+++ b/app/src/main/java/org/toop/app/widget/popup/GameOverPopup.java
@@ -4,6 +4,7 @@ import org.toop.app.widget.complex.ConfirmWidget;
import org.toop.app.widget.complex.PopupWidget;
import javafx.geometry.Pos;
+import org.toop.framework.game.games.reversi.BitboardReversi;
public final class GameOverPopup extends PopupWidget {
public GameOverPopup(boolean winOrTie, String winner) {
@@ -15,7 +16,6 @@ public final class GameOverPopup extends PopupWidget {
else{
confirmWidget.setMessage("It was a tie!");
}
-
confirmWidget.addButton("ok", this::hide);
add(Pos.CENTER, confirmWidget);
diff --git a/app/src/main/java/org/toop/app/widget/view/GameView.java b/app/src/main/java/org/toop/app/widget/view/GameView.java
index 441cc0e..38fcd6c 100644
--- a/app/src/main/java/org/toop/app/widget/view/GameView.java
+++ b/app/src/main/java/org/toop/app/widget/view/GameView.java
@@ -6,6 +6,8 @@ import javafx.scene.text.Font;
import org.toop.app.widget.Primitive;
import org.toop.app.widget.complex.ViewWidget;
import org.toop.app.widget.popup.GameOverPopup;
+
+import java.util.Objects;
import java.util.function.Consumer;
import javafx.application.Platform;
import javafx.geometry.Pos;
@@ -24,6 +26,8 @@ public final class GameView extends ViewWidget {
private final Text player2Header;
private Circle player1Icon;
private Circle player2Icon;
+ private final Text player1Score;
+ private final Text player2Score;
private final Button forfeitButton;
private final Button exitButton;
private final TextField chatInput;
@@ -38,6 +42,8 @@ public final class GameView extends ViewWidget {
player2Header = Primitive.header("");
player1Icon = new Circle();
player2Icon = new Circle();
+ player1Score = Primitive.header("");
+ player2Score = Primitive.header("");
if (onForfeit != null) {
forfeitButton = Primitive.button("forfeit", () -> onForfeit.run(), false);
@@ -94,7 +100,7 @@ public final class GameView extends ViewWidget {
}
}
- public void nextPlayer(boolean isMe, String currentPlayer, String currentMove, String nextPlayer, char GameType) {
+ public void nextPlayer(boolean isMe, String currentPlayer, String nextPlayer, String GameType) {
Platform.runLater(() -> {
if (!(hasSet)) {
playerHeader.setText(currentPlayer + " vs. " + nextPlayer);
@@ -112,8 +118,8 @@ public final class GameView extends ViewWidget {
new GameOverPopup(iWon, winner).show(Pos.CENTER);
}
- private void setPlayerHeaders(boolean isMe, String currentPlayer, String nextPlayer, char GameType) {
- if (GameType == 'T') {
+ private void setPlayerHeaders(boolean isMe, String currentPlayer, String nextPlayer, String GameType) {
+ if (Objects.equals(GameType, "TicTacToe")) {
if (isMe) {
player1Header.setText("X: " + currentPlayer);
player2Header.setText("O: " + nextPlayer);
@@ -124,7 +130,7 @@ public final class GameView extends ViewWidget {
}
setPlayerInfoTTT();
}
- else if (GameType == 'R') {
+ else if (Objects.equals(GameType, "Reversi")) {
if (isMe) {
player1Header.setText(currentPlayer);
player2Header.setText(nextPlayer);
@@ -151,14 +157,16 @@ public final class GameView extends ViewWidget {
private void setPlayerInfoReversi() {
var player1box = Primitive.hbox(
player1Icon,
- player1Header
+ player1Header,
+ player1Score
);
player1box.getStyleClass().add("hboxspacing");
var player2box = Primitive.hbox(
player2Icon,
- player2Header
+ player2Header,
+ player2Score
);
player2box.getStyleClass().add("hboxspacing");
@@ -172,8 +180,16 @@ public final class GameView extends ViewWidget {
player1Icon.setRadius(player1Header.fontProperty().map(Font::getSize).getValue());
player2Icon.setRadius(player2Header.fontProperty().map(Font::getSize).getValue());
- player1Icon.setFill(Color.BLACK);
- player2Icon.setFill(Color.WHITE);
+ player1Icon.setFill(Color.WHITE);
+ player2Icon.setFill(Color.BLACK);
add(Pos.TOP_RIGHT, playerInfo);
}
+
+ public void setPlayer1Score(int score) {
+ player1Score.setText("(" + Integer.toString(score) + ")");
+ }
+
+ public void setPlayer2Score(int score) {
+ player2Score.setText("(" + Integer.toString(score) + ")");
+ }
}
\ No newline at end of file
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 9139720..2db2419 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
@@ -4,6 +4,7 @@ import javafx.application.Platform;
import org.toop.app.GameInformation;
import org.toop.app.gameControllers.ReversiBitController;
import org.toop.app.gameControllers.TicTacToeBitController;
+import org.toop.framework.game.players.LocalPlayer;
import org.toop.framework.gameFramework.controller.GameController;
import org.toop.framework.gameFramework.model.player.Player;
import org.toop.framework.game.players.ArtificialPlayer;
@@ -12,11 +13,10 @@ import org.toop.app.widget.complex.PlayerInfoWidget;
import org.toop.app.widget.complex.ViewWidget;
import org.toop.app.widget.popup.ErrorPopup;
import org.toop.app.widget.tutorial.*;
-import org.toop.framework.game.players.LocalPlayer;
-import org.toop.game.players.ai.MCTSAI;
-import org.toop.game.players.ai.MCTSAI2;
-import org.toop.game.players.ai.MCTSAI3;
import org.toop.game.players.ai.MiniMaxAI;
+import org.toop.game.players.ai.mcts.MCTSAI1;
+import org.toop.game.players.ai.mcts.MCTSAI3;
+import org.toop.game.players.ai.mcts.MCTSAI4;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
@@ -54,7 +54,7 @@ public class LocalMultiplayerView extends ViewWidget {
if (information.players[0].isHuman) {
players[0] = new LocalPlayer(information.players[0].name);
} else {
- players[0] = new ArtificialPlayer(new MCTSAI(100), "MCTS AI");
+ players[0] = new ArtificialPlayer(new MCTSAI1(100), "MCTS AI");
}
if (information.players[1].isHuman) {
players[1] = new LocalPlayer(information.players[1].name);
@@ -82,13 +82,13 @@ public class LocalMultiplayerView extends ViewWidget {
if (information.players[0].isHuman) {
players[0] = new LocalPlayer(information.players[0].name);
} else {
- // players[0] = new ArtificialPlayer(new RandomAI(), "Random AI");
- players[0] = new ArtificialPlayer(new MCTSAI3(50), "MCTS V3 AI");
+ // players[0] = new ArtificialPlayer(new RandomAI(), "Random AI");
+ players[0] = new ArtificialPlayer(new MCTSAI1(100), "MCTS V1 AI");
}
if (information.players[1].isHuman) {
players[1] = new LocalPlayer(information.players[1].name);
} else {
- players[1] = new ArtificialPlayer(new MCTSAI2(50), "MCTS V2 AI");
+ players[1] = new ArtificialPlayer(new MCTSAI4(100, 8), "MCTS V4 AI");
}
if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstReversi()) {
new ShowEnableTutorialWidget(
diff --git a/app/src/main/java/org/toop/app/widget/view/ServerView.java b/app/src/main/java/org/toop/app/widget/view/ServerView.java
index 92c8101..9408b27 100644
--- a/app/src/main/java/org/toop/app/widget/view/ServerView.java
+++ b/app/src/main/java/org/toop/app/widget/view/ServerView.java
@@ -6,6 +6,8 @@ import javafx.scene.control.ComboBox;
import org.toop.app.widget.Primitive;
import org.toop.app.widget.complex.ViewWidget;
+import java.io.Reader;
+import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.function.Consumer;
@@ -15,6 +17,7 @@ import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import org.toop.framework.eventbus.EventFlow;
+import org.toop.framework.eventbus.GlobalEventBus;
import org.toop.framework.networking.connection.events.NetworkEvents;
public final class ServerView extends ViewWidget {
@@ -22,46 +25,65 @@ public final class ServerView extends ViewWidget {
private final Consumer onPlayerClicked;
private final long clientId;
- private final ComboBox gameList;
+ private final ComboBox gameListSub;
+ private final ComboBox gameListTour;
private final ListView