diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/game/GameState.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/game/GameState.java index b01fb4b..b462ca5 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/game/GameState.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/game/GameState.java @@ -10,6 +10,7 @@ import java.util.List; public class GameState { public List players = new ArrayList<>(); public List communityCards = new ArrayList<>(); + public List highscoreEntries = new ArrayList<>(); public String phase; public int pot; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/GameClient.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/GameClient.java index e2b34e6..42b4073 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/GameClient.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/GameClient.java @@ -155,6 +155,10 @@ public class GameClient { s.winnerIndex = intVal(l); yield true; } + case String l when l.startsWith("HIGHSCORE=") -> { + s.highscoreEntries.add(value(l)); + yield true; + } default -> false; }; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/LobbyClient.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/LobbyClient.java index 82cde9e..516a603 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/LobbyClient.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/LobbyClient.java @@ -81,6 +81,30 @@ public class LobbyClient { throw new RuntimeException("No LOBBY_ID in response: " + lines); } + /** + * Fetches the global highscores from the server. + * + * @return list of formatted highscore entries, newest entries at the end + */ + public List getHighscores() { + List lines = client.processCommand("GET_HIGHSCORES"); + List params = ClientService.convertToRequestParameters(lines); + + List entries = new ArrayList<>(); + for (RequestParameter p : params) { + if ("HIGHSCORE".equalsIgnoreCase(p.key())) { + entries.add(p.value()); + } + } + + return entries; + } + + /** Clears all global highscores on the server. */ + public void clearHighscores() { + client.processCommand("CLEAR_HIGHSCORES"); + } + /** * Request the server to return the id of the lobby that the client is currently in. * diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/game/get_game_state/GetGameStateResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/game/get_game_state/GetGameStateResponse.java index 83d37f5..795a513 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/game/get_game_state/GetGameStateResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/game/get_game_state/GetGameStateResponse.java @@ -8,6 +8,7 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player.Player; import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player.PlayerId; import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GamePhase; import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState; +import ch.unibas.dmi.dbis.cs108.casono.server.domain.highscore.HighscoreService; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.SuccessResponse; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBody; @@ -50,7 +51,11 @@ public class GetGameStateResponse extends SuccessResponse { builder.param("CURRENT_BET", computeGlobalCurrentBet(state)); builder.param("DEALER", state.getDealerIndex()); builder.param("ACTIVE_PLAYER", state.getCurrentPlayerIndex()); - builder.param("WINNER", computeWinnerIndex(state, game)); + int winnerIndex = computeWinnerIndex(state, game); + builder.param("WINNER", winnerIndex); + + appendWinnerToHighscoresIfFinished(state, winnerIndex); + appendHighscoreEntries(builder); appendCommunityCards(builder, state); @@ -59,6 +64,36 @@ public class GetGameStateResponse extends SuccessResponse { return builder.build(); } + private static void appendWinnerToHighscoresIfFinished(GameState state, int winnerIndex) { + if (winnerIndex < 0 || state.getPhase() != GamePhase.FINISHED) { + return; + } + + Player winner = findPlayerByIndex(state, winnerIndex); + if (winner == null || winner.getId() == null || winner.getId().value() == null) { + return; + } + + HighscoreService.getInstance().appendWinner(winner.getId().value()); + } + + private static Player findPlayerByIndex(GameState state, int winnerIndex) { + int currentIndex = 0; + for (Player player : state.getPlayers()) { + if (currentIndex == winnerIndex) { + return player; + } + currentIndex++; + } + return null; + } + + private static void appendHighscoreEntries(ResponseBodyBuilder builder) { + for (String entry : HighscoreService.getInstance().readFormattedEntries()) { + builder.param("HIGHSCORE", entry); + } + } + private static int computeWinnerIndex(GameState state, GameController game) { GamePhase phase = state.getPhase(); if (phase != GamePhase.SHOWDOWN && phase != GamePhase.FINISHED) {