diff --git a/app/src/main/java/org/toop/Main.java b/app/src/main/java/org/toop/Main.java index d3ef1db..428b668 100644 --- a/app/src/main/java/org/toop/Main.java +++ b/app/src/main/java/org/toop/Main.java @@ -1,9 +1,9 @@ package org.toop; + import org.toop.app.App; -import org.toop.framework.gameFramework.model.player.Player; -import org.toop.game.games.reversi.BitboardReversi; -import org.toop.game.players.ArtificialPlayer; +import org.toop.framework.game.games.reversi.BitboardReversi; +import org.toop.framework.game.players.ArtificialPlayer; import org.toop.game.players.ai.MCTSAI; import org.toop.game.players.ai.RandomAI; import org.toop.game.players.ai.mcts.MCTSAI1; @@ -11,19 +11,24 @@ import org.toop.game.players.ai.mcts.MCTSAI2; import org.toop.game.players.ai.mcts.MCTSAI3; import org.toop.game.players.ai.mcts.MCTSAI4; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + public final class Main { static void main(String[] args) { - // App.run(args); - testMCTS(25); + ExecutorService executor = Executors.newFixedThreadPool(1); + + executor.execute(() -> testMCTS(25)); + App.run(args); } private static void testMCTS(int games) { var versions = new ArtificialPlayer[5]; - versions[0] = new ArtificialPlayer<>(new RandomAI(), "Random AI"); - versions[1] = new ArtificialPlayer<>(new MCTSAI1(1000), "MCTS V1 AI"); - versions[2] = new ArtificialPlayer<>(new MCTSAI2(1000), "MCTS V2 AI"); - versions[3] = new ArtificialPlayer<>(new MCTSAI3(10, 10), "MCTS V3 AI"); - versions[4] = new ArtificialPlayer<>(new MCTSAI4(10, 10), "MCTS V4 AI"); + versions[0] = new ArtificialPlayer(new RandomAI(), "Random AI"); + versions[1] = new ArtificialPlayer(new MCTSAI1(1000), "MCTS V1 AI"); + versions[2] = new ArtificialPlayer(new MCTSAI2(1000), "MCTS V2 AI"); + versions[3] = new ArtificialPlayer(new MCTSAI3(10, 10), "MCTS V3 AI"); + versions[4] = new ArtificialPlayer(new MCTSAI4(10, 10), "MCTS V4 AI"); for (int i = 0; i < versions.length; i++) { for (int j = i + 1; j < versions.length; j++) { @@ -35,12 +40,13 @@ public final class Main { } } - private static void testAI(int games, ArtificialPlayer[] ais) { + private static void testAI(int games, ArtificialPlayer[] ais) { int wins = 0; int ties = 0; for (int i = 0; i < games; i++) { - final BitboardReversi match = new BitboardReversi(ais); + final BitboardReversi match = new BitboardReversi(); + match.init(ais); while (!match.isTerminal()) { final int currentAI = match.getCurrentTurn(); @@ -48,7 +54,7 @@ public final class Main { match.play(move); - if (ais[currentAI].getAi() instanceof MCTSAI mcts) { + if (ais[currentAI].getAi() instanceof MCTSAI mcts) { final int lastIterations = mcts.getLastIterations(); System.out.printf("iterations %s: %d\n", ais[currentAI].getName(), lastIterations); } diff --git a/app/src/main/java/org/toop/app/Server.java b/app/src/main/java/org/toop/app/Server.java index 43129e1..06a5b75 100644 --- a/app/src/main/java/org/toop/app/Server.java +++ b/app/src/main/java/org/toop/app/Server.java @@ -20,8 +20,7 @@ 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.MCTSAI3; +import org.toop.game.players.ai.mcts.MCTSAI3; import org.toop.local.AppContext; import java.util.Arrays; @@ -211,7 +210,7 @@ public final class Server { Player[] players = new Player[2]; - players[userStartingTurn] = new ArtificialPlayer(new MCTSAI3(1000), user); + players[userStartingTurn] = new ArtificialPlayer(new MCTSAI3(1000, Runtime.getRuntime().availableProcessors()), user); players[opponentStartingTurn] = new OnlinePlayer(response.opponent()); switch (type) { 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 1a6f1da..3fee500 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,13 +13,9 @@ 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.game.players.ai.MCTSAI1; -import org.toop.game.players.ai.MCTSAI2; -import org.toop.game.players.ai.MCTSAI3; -import org.toop.game.players.ai.MCTSAI4; -import org.toop.game.players.ai.MCTSAI5; import org.toop.game.players.ai.MiniMaxAI; -import org.toop.game.players.ai.RandomAI; +import org.toop.game.players.ai.mcts.MCTSAI1; +import org.toop.game.players.ai.mcts.MCTSAI3; import org.toop.local.AppContext; import javafx.geometry.Pos; @@ -56,7 +53,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); @@ -85,12 +82,12 @@ public class LocalMultiplayerView extends ViewWidget { 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 MCTSAI3(50, Runtime.getRuntime().availableProcessors()), "MCTS V3 AI"); } if (information.players[1].isHuman) { players[1] = new LocalPlayer(information.players[1].name); } else { - players[1] = new ArtificialPlayer(new MCTSAI(50), "MCTS V1 AI"); + players[1] = new ArtificialPlayer(new MCTSAI1(50), "MCTS V1 AI"); } if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstReversi()) { new ShowEnableTutorialWidget( diff --git a/framework/src/main/java/org/toop/framework/game/players/ArtificialPlayer.java b/framework/src/main/java/org/toop/framework/game/players/ArtificialPlayer.java index 23bb2bc..43167c9 100644 --- a/framework/src/main/java/org/toop/framework/game/players/ArtificialPlayer.java +++ b/framework/src/main/java/org/toop/framework/game/players/ArtificialPlayer.java @@ -57,4 +57,8 @@ public class ArtificialPlayer extends AbstractPlayer { public ArtificialPlayer deepCopy() { return new ArtificialPlayer(this); } + + public AI getAi() { + return ai; + } } diff --git a/game/src/main/java/org/toop/game/players/ai/MCTSAI.java b/game/src/main/java/org/toop/game/players/ai/MCTSAI.java index 9be5358..2ddda4b 100644 --- a/game/src/main/java/org/toop/game/players/ai/MCTSAI.java +++ b/game/src/main/java/org/toop/game/players/ai/MCTSAI.java @@ -5,8 +5,8 @@ import org.toop.framework.gameFramework.model.player.AbstractAI; import java.util.Random; -public class MCTSAI2 extends AbstractAI { - private static class Node { +public abstract class MCTSAI extends AbstractAI { + protected static class Node { public TurnBasedGame state; public long move; @@ -181,7 +181,7 @@ public class MCTSAI2 extends AbstractAI { return mostVisitedChild; } - protected Node findOrResetRoot(Node root, T game) { + protected Node findOrResetRoot(Node root, TurnBasedGame game) { if (root == null) { return new Node(game.deepCopy()); } diff --git a/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI1.java b/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI1.java index c52472a..6733e43 100644 --- a/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI1.java +++ b/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI1.java @@ -3,22 +3,22 @@ package org.toop.game.players.ai.mcts; import org.toop.framework.gameFramework.model.game.TurnBasedGame; import org.toop.game.players.ai.MCTSAI; -public class MCTSAI1> extends MCTSAI { +public class MCTSAI1 extends MCTSAI { public MCTSAI1(int milliseconds) { super(milliseconds); } - public MCTSAI1(MCTSAI1 other) { + public MCTSAI1(MCTSAI1 other) { super(other); } @Override - public MCTSAI1 deepCopy() { - return new MCTSAI1<>(this); + public MCTSAI1 deepCopy() { + return new MCTSAI1(this); } @Override - public long getMove(T game) { + public long getMove(TurnBasedGame game) { final Node root = new Node(game, null, 0L); final long endTime = System.nanoTime() + milliseconds * 1_000_000L; diff --git a/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI2.java b/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI2.java index aabafb6..c7247a2 100644 --- a/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI2.java +++ b/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI2.java @@ -3,7 +3,7 @@ package org.toop.game.players.ai.mcts; import org.toop.framework.gameFramework.model.game.TurnBasedGame; import org.toop.game.players.ai.MCTSAI; -public class MCTSAI2> extends MCTSAI { +public class MCTSAI2 extends MCTSAI { private Node root; public MCTSAI2(int milliseconds) { @@ -12,19 +12,19 @@ public class MCTSAI2> extends MCTSAI { this.root = null; } - public MCTSAI2(MCTSAI2 other) { + public MCTSAI2(MCTSAI2 other) { super(other); this.root = other.root; } @Override - public MCTSAI2 deepCopy() { - return new MCTSAI2<>(this); + public MCTSAI2 deepCopy() { + return new MCTSAI2(this); } @Override - public long getMove(T game) { + public long getMove(TurnBasedGame game) { root = findOrResetRoot(root, game); final long endTime = System.nanoTime() + milliseconds * 1_000_000L; diff --git a/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI3.java b/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI3.java index ab86b11..8ada67e 100644 --- a/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI3.java +++ b/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI3.java @@ -10,7 +10,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -public class MCTSAI3> extends MCTSAI { +public class MCTSAI3 extends MCTSAI { private final int threads; public MCTSAI3(int milliseconds, int threads) { @@ -19,19 +19,19 @@ public class MCTSAI3> extends MCTSAI { this.threads = threads; } - public MCTSAI3(MCTSAI3 other) { + public MCTSAI3(MCTSAI3 other) { super(other); this.threads = other.threads; } @Override - public MCTSAI3 deepCopy() { - return new MCTSAI3<>(this); + public MCTSAI3 deepCopy() { + return new MCTSAI3(this); } @Override - public long getMove(T game) { + public long getMove(TurnBasedGame game) { final ExecutorService pool = Executors.newFixedThreadPool(threads); final long endTime = System.nanoTime() + milliseconds * 1_000_000L; diff --git a/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI4.java b/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI4.java index ff2fb59..c89839b 100644 --- a/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI4.java +++ b/game/src/main/java/org/toop/game/players/ai/mcts/MCTSAI4.java @@ -10,7 +10,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -public class MCTSAI4> extends MCTSAI { +public class MCTSAI4 extends MCTSAI { private final int threads; private final Node[] threadRoots; @@ -21,7 +21,7 @@ public class MCTSAI4> extends MCTSAI { this.threadRoots = new Node[threads]; } - public MCTSAI4(MCTSAI4 other) { + public MCTSAI4(MCTSAI4 other) { super(other); this.threads = other.threads; @@ -29,12 +29,12 @@ public class MCTSAI4> extends MCTSAI { } @Override - public MCTSAI4 deepCopy() { - return new MCTSAI4<>(this); + public MCTSAI4 deepCopy() { + return new MCTSAI4(this); } @Override - public long getMove(T game) { + public long getMove(TurnBasedGame game) { for (int i = 0; i < threads; i++) { threadRoots[i] = findOrResetRoot(threadRoots[i], game); }