Merge branch 'fix/lobby-auto-cleanup' into 'main'
Feat: Auto-cleanup lobbies when game finishes See merge request cs108-fs26/Gruppe-13!129
This commit was merged in pull request #285.
This commit is contained in:
+26
-1
@@ -1,6 +1,7 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.game.get_game_state;
|
||||
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.app.checks.UserLoggedInCheck;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GamePhase;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.domain.lobby.Lobby;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.domain.lobby.LobbyId;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.domain.lobby.LobbyManager;
|
||||
@@ -31,8 +32,10 @@ public class GetGameStateHandler extends CommandHandler<GetGameStateRequest> {
|
||||
String username = resolveUsername(request);
|
||||
|
||||
Lobby lobby;
|
||||
LobbyId lobbyId;
|
||||
if (gameId != null) {
|
||||
lobby = lobbyManager.getLobby(LobbyId.of(gameId));
|
||||
lobbyId = LobbyId.of(gameId);
|
||||
lobby = lobbyManager.getLobby(lobbyId);
|
||||
if (lobby == null) {
|
||||
responseDispatcher.dispatch(
|
||||
new ErrorResponse(
|
||||
@@ -59,6 +62,7 @@ public class GetGameStateHandler extends CommandHandler<GetGameStateRequest> {
|
||||
request.getContext(), "NOT_IN_LOBBY", "User not in a lobby"));
|
||||
return;
|
||||
}
|
||||
lobbyId = lobby.getId();
|
||||
}
|
||||
|
||||
var game = lobby.getGameController();
|
||||
@@ -69,9 +73,30 @@ public class GetGameStateHandler extends CommandHandler<GetGameStateRequest> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (game.getState().getPhase() == GamePhase.FINISHED) {
|
||||
cleanupLobby(lobby, lobbyId);
|
||||
}
|
||||
|
||||
responseDispatcher.dispatch(new GetGameStateResponse(request.getContext(), game, username));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up a lobby by removing all players and resetting the game controller. This is called
|
||||
* when the game reaches FINISHED phase.
|
||||
*/
|
||||
private void cleanupLobby(Lobby lobby, LobbyId lobbyId) {
|
||||
try {
|
||||
// Remove all players from the lobby
|
||||
for (String playerName : lobby.getPlayerNames()) {
|
||||
lobbyManager.removePlayer(playerName);
|
||||
}
|
||||
// Reset the game controller so the lobby returns to CREATED state
|
||||
lobby.initGame(null);
|
||||
} catch (RuntimeException e) {
|
||||
// Log silently to avoid disrupting game state response
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveUsername(GetGameStateRequest request) {
|
||||
String username = request.getUsername();
|
||||
if (username != null && !username.isBlank()) {
|
||||
|
||||
@@ -254,4 +254,12 @@ public class GameController {
|
||||
|
||||
return bestPlayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the current game by setting the phase to FINISHED. This should be called when the
|
||||
* showdown is complete and a winner has been determined.
|
||||
*/
|
||||
public void endGame() {
|
||||
engine.getState().setPhase(GamePhase.FINISHED);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -49,6 +49,11 @@ public class RoundManager {
|
||||
state.setPhase(GamePhase.PREFLOP);
|
||||
}
|
||||
|
||||
if (state.countNonFoldedPlayers() == 1) {
|
||||
state.setPhase(GamePhase.FINISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBettingRoundFinished(state)) {
|
||||
advancePhase(state);
|
||||
}
|
||||
@@ -81,8 +86,9 @@ public class RoundManager {
|
||||
case FLOP -> dealTurn(state);
|
||||
case TURN -> dealRiver(state);
|
||||
case RIVER -> showdown(state);
|
||||
case SHOWDOWN -> {
|
||||
/* nothing */
|
||||
case SHOWDOWN -> state.setPhase(GamePhase.FINISHED);
|
||||
case FINISHED -> {
|
||||
/* game is over */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+28
-20
@@ -11,19 +11,15 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The GameState class encapsulates the entire state of a poker game at any
|
||||
* given moment.
|
||||
* The GameState class encapsulates the entire state of a poker game at any given moment.
|
||||
*
|
||||
* <p>
|
||||
* Important invariants this implementation maintains:
|
||||
* <p>Important invariants this implementation maintains:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@code playerOrder} defines the stable seating/turn order.
|
||||
* <li>{@code currentBets} always contains an entry for every player in
|
||||
* {@code playerOrder}.
|
||||
* <li>{@code holeCards} maps every player to a mutable list; if not present, it
|
||||
* is created on
|
||||
* demand.
|
||||
* <li>{@code playerOrder} defines the stable seating/turn order.
|
||||
* <li>{@code currentBets} always contains an entry for every player in {@code playerOrder}.
|
||||
* <li>{@code holeCards} maps every player to a mutable list; if not present, it is created on
|
||||
* demand.
|
||||
* </ul>
|
||||
*/
|
||||
public class GameState {
|
||||
@@ -188,8 +184,7 @@ public class GameState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset bets to 0 for ALL players (do not clear the map). Also resets table
|
||||
* current bet to 0.
|
||||
* Reset bets to 0 for ALL players (do not clear the map). Also resets table current bet to 0.
|
||||
*/
|
||||
public void resetBets() {
|
||||
for (PlayerId id : playerOrder) {
|
||||
@@ -232,8 +227,7 @@ public class GameState {
|
||||
// Cards
|
||||
|
||||
/**
|
||||
* Gives (overwrites) the two hole cards for the given player. Ensures stable
|
||||
* list identity
|
||||
* Gives (overwrites) the two hole cards for the given player. Ensures stable list identity
|
||||
* (important if other code holds references).
|
||||
*/
|
||||
public void giveHoleCards(PlayerId playerId, Card c1, Card c2) {
|
||||
@@ -293,14 +287,13 @@ public class GameState {
|
||||
/**
|
||||
* Starts a new hand by resetting the game state for the next round of poker.
|
||||
*
|
||||
* <p>
|
||||
* This:
|
||||
* <p>This:
|
||||
*
|
||||
* <ul>
|
||||
* <li>sets {@code phase=PREFLOP}
|
||||
* <li>resets pot/bets/commitments
|
||||
* <li>clears community + hole cards
|
||||
* <li>creates & shuffles a new deck
|
||||
* <li>sets {@code phase=PREFLOP}
|
||||
* <li>resets pot/bets/commitments
|
||||
* <li>clears community + hole cards
|
||||
* <li>creates & shuffles a new deck
|
||||
* </ul>
|
||||
*/
|
||||
public void startNewHand() {
|
||||
@@ -336,4 +329,19 @@ public class GameState {
|
||||
public boolean isFolded(PlayerId playerId) {
|
||||
return getPlayer(playerId).isFolded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of players who have not folded.
|
||||
*
|
||||
* @return The number of non-folded players
|
||||
*/
|
||||
public int countNonFoldedPlayers() {
|
||||
int count = 0;
|
||||
for (Player p : players.values()) {
|
||||
if (p != null && !p.isFolded()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user