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/framework/src/main/java/org/toop/framework/networking/server/Server.java b/framework/src/main/java/org/toop/framework/networking/server/Server.java
index 245cd8e..fa0e910 100644
--- a/framework/src/main/java/org/toop/framework/networking/server/Server.java
+++ b/framework/src/main/java/org/toop/framework/networking/server/Server.java
@@ -11,6 +11,8 @@ import org.toop.framework.networking.server.stores.SubscriptionStore;
import org.toop.framework.networking.server.stores.TurnBasedGameStore;
import org.toop.framework.networking.server.stores.TurnBasedGameTypeStore;
import org.toop.framework.networking.server.tournaments.*;
+import org.toop.framework.networking.server.tournaments.matchmakers.RoundRobinMatchMaker;
+import org.toop.framework.networking.server.tournaments.scoresystems.BasicScoreSystem;
import org.toop.framework.utils.ImmutablePair;
import java.util.*;
@@ -263,18 +265,15 @@ public class Server implements GameServer {
return true;
}
- public void startTournament(Tournament tournament, String gameType) {
+ public void startTournament(String gameType) {
+ Tournament tournament = new BasicTournament(new TournamentBuilder(
+ this,
+ new BasicTournamentRunner(),
+ new RoundRobinMatchMaker(onlineUsers()),
+ new BasicScoreSystem(onlineUsers())
+ ));
try {
- var tb = new TournamentBuilder();
- var cTournament = tb.create(
- tournament,
- onlineUsers(),
- this,
- new BasicScoreManager(new HashMap<>()),
- new BasicMatchManager(),
- new RandomShuffle()
- );
- new Thread(() -> cTournament.run(gameType)).start();
+ new Thread(() -> tournament.run(gameType)).start();
} catch (IllegalArgumentException e) {
getUser("host").send("ERR not enough clients to start a tournament");
} catch (RuntimeException e) {
diff --git a/framework/src/main/java/org/toop/framework/networking/server/handlers/MessageHandler.java b/framework/src/main/java/org/toop/framework/networking/server/handlers/MessageHandler.java
index d42a854..bc5a6c5 100644
--- a/framework/src/main/java/org/toop/framework/networking/server/handlers/MessageHandler.java
+++ b/framework/src/main/java/org/toop/framework/networking/server/handlers/MessageHandler.java
@@ -5,7 +5,7 @@ import org.toop.framework.networking.server.OnlineTurnBasedGame;
import org.toop.framework.networking.server.Server;
import org.toop.framework.networking.server.client.Client;
import org.toop.framework.networking.server.parsing.ParsedMessage;
-import org.toop.framework.networking.server.tournaments.BasicTournament;
+import org.toop.framework.networking.server.tournaments.*;
import org.toop.framework.utils.Utils;
public class MessageHandler implements Handler {
@@ -116,7 +116,7 @@ public class MessageHandler implements Handler {
if (!client.name().equalsIgnoreCase("host")) return;
if (p.args()[0].equalsIgnoreCase("start") && p.args().length > 1) {
- server.startTournament(new BasicTournament(), p.args()[1]);
+ server.startTournament(p.args()[1]);
}
}
}
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicMatchManager.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicMatchManager.java
deleted file mode 100644
index 29ffdf1..0000000
--- a/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicMatchManager.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package org.toop.framework.networking.server.tournaments;
-
-import org.toop.framework.gameFramework.model.game.TurnBasedGame;
-import org.toop.framework.networking.server.OnlineGame;
-import org.toop.framework.networking.server.Server;
-import org.toop.framework.networking.server.client.NettyClient;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.atomic.AtomicReference;
-
-public class BasicMatchManager implements MatchManager {
-
- private final HashMap> matches = new HashMap<>(); // TODO store
- private final ArrayList matchOrder = new ArrayList<>(); // TODO store
- private int matchIndex = 0;
-
- public BasicMatchManager() {}
-
- @Override
- public void addClient(NettyClient client) {
- matches.putIfAbsent(client, new ArrayList<>());
- }
-
- @Override
- public List getClients() {
- return matches.keySet().stream().toList();
- }
-
- @Override
- public void createMatches() {
- for (var match : matches.entrySet()) {
- for (var matchNoSelf : matches.keySet()) {
- if (match.getKey() == matchNoSelf) continue;
-
- match.getValue().addLast(matchNoSelf);
- }
- }
-
- for (var client : matches.entrySet()) {
- for (var opponent : client.getValue()) {
- matchOrder.addLast(new TournamentMatch(client.getKey(), opponent));
- }
- }
- }
-
- @Override
- public TournamentMatch next() {
- matchIndex++;
- if (matchIndex >= matchOrder.size()) return null;
-
- return matchOrder.get(matchIndex);
- }
-
- @Override
- public void run(Server server, ScoreManager scoreManager, String gameType) {
- new Thread(() -> {
- for (var match : matchOrder) {
- final CompletableFuture finished = new CompletableFuture<>();
-
- AtomicReference> game = new AtomicReference<>();
- new Thread(() -> game.set(server.startGame(gameType, finished, match.getLeft(), match.getRight()))).start(); // TODO can possibly create a race condition
-
- finished.join();
- switch (game.get().game().getWinner()) {
- case 0 -> scoreManager.addScore(match.getLeft());
- case 1 -> scoreManager.addScore(match.getRight());
- default -> {}
- }
-
- match.getLeft().clearGame();
- match.getRight().clearGame();
- }
-
- server.endTournament(scoreManager.getScore(), gameType);
- }).start();
- }
-
- @Override
- public void shuffle(Shuffler shuffler) {
- shuffler.shuffle(matchOrder);
- }
-}
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicScoreManager.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicScoreManager.java
deleted file mode 100644
index 95a9cde..0000000
--- a/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicScoreManager.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.toop.framework.networking.server.tournaments;
-
-import org.toop.framework.networking.server.client.NettyClient;
-
-import java.util.Map;
-
-public class BasicScoreManager implements ScoreManager {
-
- private final Map scores;
-
- public BasicScoreManager(Map store) {
- scores = store;
- }
-
- @Override
- public void addClient(NettyClient client) {
- scores.putIfAbsent(client, getInitScore());
- }
-
- @Override
- public void addScore(NettyClient client) {
- int clientScore = scores.get(client);
- scores.put(client, clientScore + getWinPointAmount());
- }
-
- @Override
- public Map getScore() {
- return scores;
- }
-}
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicTournament.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicTournament.java
index 235cb37..50db018 100644
--- a/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicTournament.java
+++ b/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicTournament.java
@@ -1,48 +1,29 @@
package org.toop.framework.networking.server.tournaments;
import org.toop.framework.networking.server.Server;
+import org.toop.framework.networking.server.tournaments.matchmakers.MatchMaker;
+import org.toop.framework.networking.server.tournaments.scoresystems.ScoreSystem;
public class BasicTournament implements Tournament {
- private Server server;
+ private final Server server;
- private ScoreManager scoreManager;
- private MatchManager matchManager;
+ private final ScoreSystem scoreSystem;
+ private final TournamentRunner tournamentRunner;
+ private final MatchMaker matchMaker;
- public BasicTournament() {}
-
- public void init(TournamentBuilder builder) {
+ public BasicTournament(TournamentBuilder builder) {
server = builder.server;
- scoreManager = builder.scoreManager;
- matchManager = builder.matchManager;
+ scoreSystem = builder.scoreSystem;
+ tournamentRunner = builder.tournamentRunner;
+ matchMaker = builder.matchMaker;
}
@Override
public boolean run(String gameType) throws RuntimeException {
if (server.gameTypes().stream().noneMatch(e -> e.equalsIgnoreCase(gameType))) return false;
- matchManager.run(server, scoreManager, gameType);
+ tournamentRunner.run(server, matchMaker, scoreSystem, gameType);
return true;
}
-
-// @Override
-// public HashMap end() {
-//
-// for (var match : matchList) {
-// match.getLeft().clearGame(); // TODO send msg to client
-// match.getRight().clearGame(); // TODO send msg to client
-// }
-//
-// gameType = null;
-// matchList = null;
-// matches.clear();
-//
-// HashMap retScore = new HashMap<>(score);
-//
-// score.clear();
-//
-// clients = null;
-//
-// return retScore;
-// }
}
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicTournamentRunner.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicTournamentRunner.java
new file mode 100644
index 0000000..47341fa
--- /dev/null
+++ b/framework/src/main/java/org/toop/framework/networking/server/tournaments/BasicTournamentRunner.java
@@ -0,0 +1,46 @@
+package org.toop.framework.networking.server.tournaments;
+
+import org.toop.framework.gameFramework.model.game.TurnBasedGame;
+import org.toop.framework.networking.server.OnlineGame;
+import org.toop.framework.networking.server.Server;
+import org.toop.framework.networking.server.tournaments.matchmakers.MatchMaker;
+import org.toop.framework.networking.server.tournaments.scoresystems.ScoreSystem;
+
+import java.util.concurrent.*;
+
+public class BasicTournamentRunner implements TournamentRunner {
+
+ public BasicTournamentRunner() {}
+
+ @Override
+ public void run(Server server, MatchMaker matchMaker, ScoreSystem scoreSystem, String gameType) {
+ ExecutorService threadPool = Executors.newSingleThreadExecutor();
+ try {
+ threadPool.execute(() -> {
+ for (var match : matchMaker) {
+ final CompletableFuture finished = new CompletableFuture<>();
+
+ // Play game and await the results
+ OnlineGame game = server.startGame(gameType, finished, match.getClient0(), match.getClient1()); // TODO can possibly create a race condition
+ finished.join();
+ // End
+
+ // Get result and calculate new score
+ switch (game.game().getWinner()) {
+ case 0 -> scoreSystem.addScore(match.getClient0());
+ case 1 -> scoreSystem.addScore(match.getClient1());
+ default -> {
+ }
+ }
+
+ match.getClient0().clearGame();
+ match.getClient1().clearGame();
+ }
+
+ server.endTournament(scoreSystem.getScore(), gameType);
+ });
+ } finally {
+ threadPool.shutdown();
+ }
+ }
+}
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/MatchManager.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/MatchManager.java
deleted file mode 100644
index 1f1352f..0000000
--- a/framework/src/main/java/org/toop/framework/networking/server/tournaments/MatchManager.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.toop.framework.networking.server.tournaments;
-
-import org.toop.framework.networking.server.Server;
-import org.toop.framework.networking.server.client.NettyClient;
-
-import java.util.List;
-
-public interface MatchManager {
- void addClient(NettyClient client);
- List getClients();
- void createMatches();
- TournamentMatch next();
- void run(Server server, ScoreManager scoreManager, String gameType);
- void shuffle(Shuffler shuffler);
-}
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/Tournament.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/Tournament.java
index 135fe6c..12d588a 100644
--- a/framework/src/main/java/org/toop/framework/networking/server/tournaments/Tournament.java
+++ b/framework/src/main/java/org/toop/framework/networking/server/tournaments/Tournament.java
@@ -5,7 +5,7 @@ import org.toop.framework.networking.server.client.NettyClient;
import java.util.HashMap;
public interface Tournament {
- void init(TournamentBuilder builder);
+// void init(TournamentBuilder builder);
boolean run(String gameType);
// HashMap end();
}
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/TournamentBuilder.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/TournamentBuilder.java
index dfd2ef1..cf52d76 100644
--- a/framework/src/main/java/org/toop/framework/networking/server/tournaments/TournamentBuilder.java
+++ b/framework/src/main/java/org/toop/framework/networking/server/tournaments/TournamentBuilder.java
@@ -1,39 +1,24 @@
package org.toop.framework.networking.server.tournaments;
import org.toop.framework.networking.server.Server;
-import org.toop.framework.networking.server.client.NettyClient;
-
-import java.util.List;
+import org.toop.framework.networking.server.tournaments.matchmakers.MatchMaker;
+import org.toop.framework.networking.server.tournaments.scoresystems.ScoreSystem;
public class TournamentBuilder {
public Server server;
- public ScoreManager scoreManager;
- public MatchManager matchManager;
+ public ScoreSystem scoreSystem;
+ public TournamentRunner tournamentRunner;
+ public MatchMaker matchMaker;
- public TournamentBuilder() {}
-
- public Tournament create(
- Tournament tournament,
- List clients,
+ public TournamentBuilder(
Server server,
- ScoreManager scoreManager,
- MatchManager matchManager,
- Shuffler shuffler
+ TournamentRunner tournamentRunner,
+ MatchMaker matchMaker,
+ ScoreSystem scoreSystem
) {
-
this.server = server;
- this.scoreManager = scoreManager;
- this.matchManager = matchManager;
-
- for (var client : clients) {
- matchManager.addClient(client);
- scoreManager.addClient(client);
- }
-
- matchManager.createMatches();
- matchManager.shuffle(shuffler);
-
- tournament.init(this);
- return tournament;
+ this.tournamentRunner = tournamentRunner;
+ this.matchMaker = matchMaker;
+ this.scoreSystem = scoreSystem;
}
}
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/TournamentMatch.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/TournamentMatch.java
index 7f2067d..ab703e7 100644
--- a/framework/src/main/java/org/toop/framework/networking/server/tournaments/TournamentMatch.java
+++ b/framework/src/main/java/org/toop/framework/networking/server/tournaments/TournamentMatch.java
@@ -7,4 +7,12 @@ public class TournamentMatch extends ImmutablePair {
public TournamentMatch(NettyClient a, NettyClient b) {
super(a, b);
}
+
+ NettyClient getClient0() {
+ return getLeft();
+ }
+
+ NettyClient getClient1() {
+ return getRight();
+ }
}
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/TournamentRunner.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/TournamentRunner.java
new file mode 100644
index 0000000..fe0e9cb
--- /dev/null
+++ b/framework/src/main/java/org/toop/framework/networking/server/tournaments/TournamentRunner.java
@@ -0,0 +1,9 @@
+package org.toop.framework.networking.server.tournaments;
+
+import org.toop.framework.networking.server.Server;
+import org.toop.framework.networking.server.tournaments.matchmakers.MatchMaker;
+import org.toop.framework.networking.server.tournaments.scoresystems.ScoreSystem;
+
+public interface TournamentRunner {
+ void run(Server server, MatchMaker matchMaker, ScoreSystem scoreSystem, String gameType);
+}
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/matchmakers/MatchMaker.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/matchmakers/MatchMaker.java
new file mode 100644
index 0000000..e61d387
--- /dev/null
+++ b/framework/src/main/java/org/toop/framework/networking/server/tournaments/matchmakers/MatchMaker.java
@@ -0,0 +1,5 @@
+package org.toop.framework.networking.server.tournaments.matchmakers;
+
+import org.toop.framework.networking.server.tournaments.TournamentMatch;
+
+public interface MatchMaker extends Iterable {}
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/matchmakers/RoundRobinMatchMaker.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/matchmakers/RoundRobinMatchMaker.java
new file mode 100644
index 0000000..be38af7
--- /dev/null
+++ b/framework/src/main/java/org/toop/framework/networking/server/tournaments/matchmakers/RoundRobinMatchMaker.java
@@ -0,0 +1,65 @@
+package org.toop.framework.networking.server.tournaments.matchmakers;
+
+import org.toop.framework.networking.server.client.NettyClient;
+import org.toop.framework.networking.server.tournaments.TournamentMatch;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+public class RoundRobinMatchMaker implements MatchMaker {
+
+ private final List players;
+
+ public RoundRobinMatchMaker(List players) {
+ this.players = players;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new Iterator<>() {
+
+ private int i = 0;
+ private int j = 1;
+ private boolean reverse = false;
+
+ @Override
+ public boolean hasNext() {
+ return players.size() > 1
+ && i < players.size() - 1
+ && j < players.size();
+ }
+
+ @Override
+ public TournamentMatch next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ NettyClient home = players.get(i);
+ NettyClient away = players.get(j);
+
+ TournamentMatch match = reverse ? new TournamentMatch(away, home) : new TournamentMatch(home, away);
+
+ advance();
+ return match;
+ }
+
+ private void advance() {
+ j++;
+ if (j >= players.size()) {
+ i++;
+ j = i + 1;
+
+ if (i >= players.size() - 1) {
+ if (!reverse) {
+ reverse = true;
+ i = 0;
+ j = 1;
+ }
+ }
+ }
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/scoresystems/BasicScoreSystem.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/scoresystems/BasicScoreSystem.java
new file mode 100644
index 0000000..75625c3
--- /dev/null
+++ b/framework/src/main/java/org/toop/framework/networking/server/tournaments/scoresystems/BasicScoreSystem.java
@@ -0,0 +1,29 @@
+package org.toop.framework.networking.server.tournaments.scoresystems;
+
+import org.toop.framework.networking.server.client.NettyClient;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class BasicScoreSystem implements ScoreSystem {
+
+ private final Map scores = new HashMap<>();
+
+ public BasicScoreSystem(List store) {
+ for (NettyClient c : store) {
+ scores.putIfAbsent(c, getInitScore());
+ }
+ }
+
+ @Override
+ public void addScore(NettyClient client) {
+ int clientScore = scores.get(client);
+ scores.put(client, clientScore + getWinPointAmount());
+ }
+
+ @Override
+ public Map getScore() {
+ return scores;
+ }
+}
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/ScoreManager.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/scoresystems/ScoreSystem.java
similarity index 69%
rename from framework/src/main/java/org/toop/framework/networking/server/tournaments/ScoreManager.java
rename to framework/src/main/java/org/toop/framework/networking/server/tournaments/scoresystems/ScoreSystem.java
index 7a56ac3..a33ba2b 100644
--- a/framework/src/main/java/org/toop/framework/networking/server/tournaments/ScoreManager.java
+++ b/framework/src/main/java/org/toop/framework/networking/server/tournaments/scoresystems/ScoreSystem.java
@@ -1,11 +1,10 @@
-package org.toop.framework.networking.server.tournaments;
+package org.toop.framework.networking.server.tournaments.scoresystems;
import org.toop.framework.networking.server.client.NettyClient;
import java.util.Map;
-public interface ScoreManager {
- void addClient(NettyClient client);
+public interface ScoreSystem {
void addScore(NettyClient client);
Map getScore();
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/RandomShuffle.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/shufflers/RandomShuffle.java
similarity index 88%
rename from framework/src/main/java/org/toop/framework/networking/server/tournaments/RandomShuffle.java
rename to framework/src/main/java/org/toop/framework/networking/server/tournaments/shufflers/RandomShuffle.java
index cdfe5ed..5d40833 100644
--- a/framework/src/main/java/org/toop/framework/networking/server/tournaments/RandomShuffle.java
+++ b/framework/src/main/java/org/toop/framework/networking/server/tournaments/shufflers/RandomShuffle.java
@@ -1,4 +1,4 @@
-package org.toop.framework.networking.server.tournaments;
+package org.toop.framework.networking.server.tournaments.shufflers;
import java.util.List;
import java.util.Random;
diff --git a/framework/src/main/java/org/toop/framework/networking/server/tournaments/Shuffler.java b/framework/src/main/java/org/toop/framework/networking/server/tournaments/shufflers/Shuffler.java
similarity index 59%
rename from framework/src/main/java/org/toop/framework/networking/server/tournaments/Shuffler.java
rename to framework/src/main/java/org/toop/framework/networking/server/tournaments/shufflers/Shuffler.java
index 844fb0e..9f1acf2 100644
--- a/framework/src/main/java/org/toop/framework/networking/server/tournaments/Shuffler.java
+++ b/framework/src/main/java/org/toop/framework/networking/server/tournaments/shufflers/Shuffler.java
@@ -1,4 +1,4 @@
-package org.toop.framework.networking.server.tournaments;
+package org.toop.framework.networking.server.tournaments.shufflers;
import java.util.List;