Fix: formatting and checkstyle issues

This commit is contained in:
Julian Kropff
2026-04-05 11:15:26 +02:00
parent d4e69d26d7
commit bf7ac4fc34
41 changed files with 623 additions and 822 deletions
@@ -17,9 +17,8 @@ import java.util.List;
import java.util.Map;
/**
* GameController is responsible for managing the flow of the poker game. It
* interacts with the GameEngine to process player actions and update the game
* state accordingly.
* GameController is responsible for managing the flow of the poker game. It interacts with the
* GameEngine to process player actions and update the game state accordingly.
*/
public class GameController {
@@ -48,7 +47,7 @@ public class GameController {
/**
* Adds a player to the game with the specified name and initial chip count.
*
* @param name The name of the player to add.
* @param name The name of the player to add.
* @param chips The initial number of chips the player has.
*/
public void addPlayer(PlayerId name, int chips) {
@@ -58,14 +57,13 @@ public class GameController {
// players.add(id);
// engine.getState().addPlayer(id, chips);
players.add(name);
engine.getState().addPlayer(name, chips);
players.add(name);
engine.getState().addPlayer(name, chips);
}
/**
* Initializes a new hand by preparing the deck, setting the phase to PREFLOP,
* rotating the dealer, dealing hole cards, posting blinds,
* and setting the first active player.
* Initializes a new hand by preparing the deck, setting the phase to PREFLOP, rotating the
* dealer, dealing hole cards, posting blinds, and setting the first active player.
*/
public void startGame() {
@@ -86,9 +84,7 @@ public class GameController {
engine.getState().setCurrentPlayerIndex(nextPlayerIndex);
}
/**
* Rotates the dealer position to the next player in the list.
*/
/** Rotates the dealer position to the next player in the list. */
private void rotateDealer() {
dealerIndex = (dealerIndex + DEALER_OFFSET) % players.size();
}
@@ -103,8 +99,8 @@ public class GameController {
}
/**
* Determines the small and big blind players relative to the dealer
* and submits the corresponding blind actions to the engine.
* Determines the small and big blind players relative to the dealer and submits the
* corresponding blind actions to the engine.
*/
public void postBlinds() {
@@ -115,9 +111,7 @@ public class GameController {
engine.processAction(new BlindAction(bigBlind, BIG_BLIND));
}
/**
* Deals hole cards to each player from the deck.
*/
/** Deals hole cards to each player from the deck. */
public void dealHoleCards() {
Deck deck = engine.getState().getDeck();
@@ -131,9 +125,7 @@ public class GameController {
}
}
/**
* Draws three cards from the deck and adds them as community cards (flop).
*/
/** Draws three cards from the deck and adds them as community cards (flop). */
public void dealFlop() {
Deck deck = engine.getState().getDeck();
@@ -144,16 +136,14 @@ public class GameController {
}
/**
* Deals the turn by drawing one community card from the deck and adding it to
* the game state.
* Deals the turn by drawing one community card from the deck and adding it to the game state.
*/
public void dealTurn() {
engine.getState().addCommunityCard(engine.getState().getDeck().draw());
}
/**
* Deals the river by drawing one community card from the deck and adding it to
* the game state.
* Deals the river by drawing one community card from the deck and adding it to the game state.
*/
public void dealRiver() {
engine.getState().addCommunityCard(engine.getState().getDeck().draw());
@@ -183,7 +173,7 @@ public class GameController {
* Processes a player's raise action by sending a RaiseAction to the GameEngine.
*
* @param playerId The ID of the player who is raising.
* @param amount The amount the player is raising.
* @param amount The amount the player is raising.
*/
public void playerRaise(PlayerId playerId, int amount) {
// engine.processAction(new RaiseAction(PlayerId.of(playerId), amount));
@@ -211,19 +201,19 @@ public class GameController {
/**
* Retrieves the hole cards for each player in the game.
*
* @return A map where the key is the player's name and the value is a list of
* Card objects representing the player's hole cards.
* @return A map where the key is the player's name and the value is a list of Card objects
* representing the player's hole cards.
*/
public Map<PlayerId, List<Card>> getPlayerCards() {
return engine.getState().getPlayerCards();
}
/**
* Determines the winner of the current hand by evaluating the best possible
* poker hand for each active player.
* Determines the winner of the current hand by evaluating the best possible poker hand for each
* active player.
*
* The evaluation is based on the player's two hole cards combined with the
* five community cards on the board.
* <p>The evaluation is based on the player's two hole cards combined with the five community
* cards on the board.
*
* @return The ID of the winning player.
*/
@@ -3,10 +3,9 @@ package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.action;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player.PlayerId;
/**
* AbstractAction serves as a base class for all player actions in the poker
* game.
* It implements the Action interface and provides a common implementation for
* retrieving the player ID associated with the action.
* AbstractAction serves as a base class for all player actions in the poker game. It implements the
* Action interface and provides a common implementation for retrieving the player ID associated
* with the action.
*/
public abstract class AbstractAction implements Action {
protected final PlayerId playerId;
@@ -1,13 +1,12 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.action;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player.PlayerId;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* The Action interface defines the structure for all player actions in the
* poker game. Each action must specify its type, provide an implementation for
* executing the action on the game state, and identify the player performing
* the action.
* The Action interface defines the structure for all player actions in the poker game. Each action
* must specify its type, provide an implementation for executing the action on the game state, and
* identify the player performing the action.
*/
public interface Action {
ActionType getType();
@@ -1,9 +1,9 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.action;
/**
* ActionType is an enumeration that defines the various types of actions that
* players can perform in a poker game. Each action type corresponds to a
* specific move or decision that a player can make during their turn.
* ActionType is an enumeration that defines the various types of actions that players can perform
* in a poker game. Each action type corresponds to a specific move or decision that a player can
* make during their turn.
*/
public enum ActionType {
FOLD,
@@ -5,11 +5,9 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player.PlayerId;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* AllInAction represents the action of a player going all-in in a poker game.
* When
* a player goes all-in, they bet all of their remaining chips. This action
* updates the player's chip count, adds the bet to the pot, and updates the
* current bet for the player in the game state.
* AllInAction represents the action of a player going all-in in a poker game. When a player goes
* all-in, they bet all of their remaining chips. This action updates the player's chip count, adds
* the bet to the pot, and updates the current bet for the player in the game state.
*/
public class AllInAction extends AbstractAction {
@@ -33,9 +31,8 @@ public class AllInAction extends AbstractAction {
}
/**
* Executes the all-in action on the given game state. This method updates the
* player's chip count, adds the bet to the pot, and updates the current bet
* for the player in the game state.
* Executes the all-in action on the given game state. This method updates the player's chip
* count, adds the bet to the pot, and updates the current bet for the player in the game state.
*
* @param state The current game state on which to execute the action.
*/
@@ -5,9 +5,9 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player.PlayerId;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* Represents a bet action where a player contributes a fixed amount of chips.
* The amount is deducted from the player's chips, added to the pot, and both
* the player's current bet and the table's current bet are set to this amount.
* Represents a bet action where a player contributes a fixed amount of chips. The amount is
* deducted from the player's chips, added to the pot, and both the player's current bet and the
* table's current bet are set to this amount.
*/
public class BetAction extends AbstractAction {
@@ -17,7 +17,7 @@ public class BetAction extends AbstractAction {
* Constructs a BetAction for the specified player ID and bet amount.
*
* @param playerId The ID of the player performing the bet action.
* @param amount The amount of chips the player is betting.
* @param amount The amount of chips the player is betting.
*/
public BetAction(PlayerId playerId, int amount) {
super(playerId);
@@ -44,9 +44,8 @@ public class BetAction extends AbstractAction {
}
/**
* Executes the bet action on the given game state. This method updates the
* player's chip count, adds the bet to the pot, and updates the current bet
* for the player in the game state.
* Executes the bet action on the given game state. This method updates the player's chip count,
* adds the bet to the pot, and updates the current bet for the player in the game state.
*
* @param state The current game state on which to execute the action.
*/
@@ -5,9 +5,8 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player.PlayerId;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* Executes a blind by deducting chips from the player, adding them to the pot,
* increasing the player's current bet, and updating the table's current bet
* if the blind exceeds the existing bet.
* Executes a blind by deducting chips from the player, adding them to the pot, increasing the
* player's current bet, and updating the table's current bet if the blind exceeds the existing bet.
*/
public class BlindAction implements Action {
@@ -18,7 +17,7 @@ public class BlindAction implements Action {
* Constructs a BlindAction for the specified player ID and blind amount.
*
* @param playerId The ID of the player posting the blind bet.
* @param amount The amount of chips the player is posting as a blind bet.
* @param amount The amount of chips the player is posting as a blind bet.
*/
public BlindAction(PlayerId playerId, int amount) {
this.playerId = playerId;
@@ -41,14 +40,14 @@ public class BlindAction implements Action {
* @return The player ID associated with this action.
*/
@Override
public PlayerId getPlayerId() {
public PlayerId getPlayerId() {
return playerId;
}
/**
* Executes the blind action on the given game state. This method updates the
* player's chip count, adds the blind bet to the pot, and updates the current
* bet for the player in the game state.
* Executes the blind action on the given game state. This method updates the player's chip
* count, adds the blind bet to the pot, and updates the current bet for the player in the game
* state.
*
* @param state The current game state on which to execute the action.
*/
@@ -5,11 +5,10 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player.PlayerId;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* CallAction represents the action of a player calling in a poker game. When a
* player calls, they match the current bet on the table by paying the
* difference between their current bet and the table's current bet. This action
* updates the player's chip count, adds the required amount to the pot, and
* updates the player's current bet accordingly.
* CallAction represents the action of a player calling in a poker game. When a player calls, they
* match the current bet on the table by paying the difference between their current bet and the
* table's current bet. This action updates the player's chip count, adds the required amount to the
* pot, and updates the player's current bet accordingly.
*/
public class CallAction extends AbstractAction {
@@ -33,10 +32,9 @@ public class CallAction extends AbstractAction {
}
/**
* Executes the call action on the given game state. This method checks if
* the player is folded, calculates the amount to call, updates the player's
* chip count, adds the amount to the pot, and updates the player's current
* bet.
* Executes the call action on the given game state. This method checks if the player is folded,
* calculates the amount to call, updates the player's chip count, adds the amount to the pot,
* and updates the player's current bet.
*
* @param state the current game state on which to execute the call action
*/
@@ -5,10 +5,9 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player.PlayerId;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* FoldAction represents the action of a player folding in a poker game. When a
* player folds, they forfeit their hand and are no longer active in the current
* round. This action updates the player's status to indicate that they have
* folded.
* FoldAction represents the action of a player folding in a poker game. When a player folds, they
* forfeit their hand and are no longer active in the current round. This action updates the
* player's status to indicate that they have folded.
*/
public class FoldAction extends AbstractAction {
@@ -32,8 +31,8 @@ public class FoldAction extends AbstractAction {
}
/**
* Executes the fold action on the given game state. This method updates the
* player's status to indicate that they have folded.
* Executes the fold action on the given game state. This method updates the player's status to
* indicate that they have folded.
*
* @param state The current game state on which to execute the action.
*/
@@ -11,7 +11,7 @@ public class RaiseAction extends AbstractAction {
/**
* Constructs a RaiseAction for the specified player ID and raise amount.
*
* @param playerId The ID of the player performing the raise action.
* @param playerId The ID of the player performing the raise action.
* @param raiseAmount The amount of chips the player is raising.
*/
public RaiseAction(PlayerId playerId, int raiseAmount) {
@@ -39,9 +39,9 @@ public class RaiseAction extends AbstractAction {
}
/**
* Executes the raise action on the given game state. This method updates the
* player's chip count, adds the raise amount to the pot, and updates the
* current bet for the player in the game state.
* Executes the raise action on the given game state. This method updates the player's chip
* count, adds the raise amount to the pot, and updates the current bet for the player in the
* game state.
*
* @param state The current game state on which to execute the action.
*/
@@ -1,11 +1,10 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.deck;
/**
* The Card class represents a single playing card in a standard deck of cards.
* Each card has a suit (Hearts, Diamonds, Clubs, Spades) and a rank (2-10,
* Jack, Queen, King, Ace).
* This class provides methods to retrieve the suit and rank of the card, as
* well as a string representation of the card.
* The Card class represents a single playing card in a standard deck of cards. Each card has a suit
* (Hearts, Diamonds, Clubs, Spades) and a rank (2-10, Jack, Queen, King, Ace). This class provides
* methods to retrieve the suit and rank of the card, as well as a string representation of the
* card.
*/
public class Card {
@@ -6,20 +6,18 @@ import java.util.LinkedList;
import java.util.List;
/**
* The Deck class represents a standard deck of playing cards. It provides
* functionality to create a full deck of 52 cards, shuffle the deck, and draw
* cards from it. The deck is initialized with all combinations of suits and
* ranks, and can be manipulated through its methods.
* The Deck class represents a standard deck of playing cards. It provides functionality to create a
* full deck of 52 cards, shuffle the deck, and draw cards from it. The deck is initialized with all
* combinations of suits and ranks, and can be manipulated through its methods.
*/
public class Deck {
private List<Card> cards;
/**
* Constructs a new Deck object and initializes it with a standard set of 52
* playing cards. The deck is created by iterating through all suits and ranks,
* creating a Card object for each combination, and adding it to the list of
* cards.
* Constructs a new Deck object and initializes it with a standard set of 52 playing cards. The
* deck is created by iterating through all suits and ranks, creating a Card object for each
* combination, and adding it to the list of cards.
*/
public Deck() {
@@ -33,19 +31,18 @@ public class Deck {
}
/**
* Shuffles the deck of cards using the Collections.shuffle method, which
* randomly permutes the list of cards. This method can be called to randomize
* the order of the cards in the deck before drawing.
* Shuffles the deck of cards using the Collections.shuffle method, which randomly permutes the
* list of cards. This method can be called to randomize the order of the cards in the deck
* before drawing.
*/
public void shuffle() {
Collections.shuffle(cards);
}
/**
* Draws and removes the last card in the list, which represents the top of the deck.
* This method removes and returns the last card in the list of cards, which
* represents the top of the deck. If the deck is empty, this method will throw an
* IndexOutOfBoundsException.
* Draws and removes the last card in the list, which represents the top of the deck. This
* method removes and returns the last card in the list of cards, which represents the top of
* the deck. If the deck is empty, this method will throw an IndexOutOfBoundsException.
*
* @return The Card object that was drawn from the deck.
*/
@@ -54,9 +51,9 @@ public class Deck {
}
/**
* Retrieves the current list of cards in the deck. This method returns a new
* LinkedList containing the cards, which allows for safe manipulation of the
* returned list without affecting the internal state of the deck.
* Retrieves the current list of cards in the deck. This method returns a new LinkedList
* containing the cards, which allows for safe manipulation of the returned list without
* affecting the internal state of the deck.
*
* @return A List of Card objects currently in the deck.
*/
@@ -1,9 +1,9 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.deck;
/**
* The Rank enumeration represents the rank of a playing card in a standard
* deck of cards. It includes the ranks from Two to Ace, which are used to
* determine the value of the card in various card games, including poker.
* The Rank enumeration represents the rank of a playing card in a standard deck of cards. It
* includes the ranks from Two to Ace, which are used to determine the value of the card in various
* card games, including poker.
*/
public enum Rank {
TWO,
@@ -1,10 +1,9 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.deck;
/**
* The Suit enumeration represents the four suits of a standard deck of playing
* cards: Hearts, Diamonds, Clubs, and Spades. Each suit is used to categorize
* the cards and can have different values in various card games, including
* poker.
* The Suit enumeration represents the four suits of a standard deck of playing cards: Hearts,
* Diamonds, Clubs, and Spades. Each suit is used to categorize the cards and can have different
* values in various card games, including poker.
*/
public enum Suit {
HEARTS,
@@ -5,12 +5,11 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.rules.RuleEngine;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* The GameEngine class is responsible for managing the core logic of the poker
* game. It integrates the RuleEngine, RoundManager, and TurnManager to
* orchestrate the flow of the game. The GameEngine processes player actions,
* updates the game state accordingly, and ensures that the game progresses
* through its various stages (pre-flop, flop, turn, river) while adhering to
* the rules of poker.
* The GameEngine class is responsible for managing the core logic of the poker game. It integrates
* the RuleEngine, RoundManager, and TurnManager to orchestrate the flow of the game. The GameEngine
* processes player actions, updates the game state accordingly, and ensures that the game
* progresses through its various stages (pre-flop, flop, turn, river) while adhering to the rules
* of poker.
*/
public class GameEngine {
@@ -21,18 +20,17 @@ public class GameEngine {
private final GameState state;
/**
* Constructs a GameEngine with the specified game state, rule engine, round
* manager, and turn manager.
* Constructs a GameEngine with the specified game state, rule engine, round manager, and turn
* manager.
*
* @param state The initial game state to be managed by the engine.
* @param ruleEngine The RuleEngine instance responsible for validating player
* actions.
* @param roundManager The RoundManager instance responsible for managing the
* progression of rounds.
* @param turnManager The TurnManager instance responsible for managing player
* turns.
* @param state The initial game state to be managed by the engine.
* @param ruleEngine The RuleEngine instance responsible for validating player actions.
* @param roundManager The RoundManager instance responsible for managing the progression of
* rounds.
* @param turnManager The TurnManager instance responsible for managing player turns.
*/
public GameEngine(GameState state,
public GameEngine(
GameState state,
RuleEngine ruleEngine,
RoundManager roundManager,
TurnManager turnManager) {
@@ -43,8 +41,8 @@ public class GameEngine {
}
/**
* Starts a new hand with the provided game state. This method initializes the
* round manager to begin a new hand and sets up the game state accordingly.
* Starts a new hand with the provided game state. This method initializes the round manager to
* begin a new hand and sets up the game state accordingly.
*
* @param state The game state to be used for starting the new hand.
*/
@@ -53,17 +51,17 @@ public class GameEngine {
}
/**
* Starts a new hand using the current game state. This method is a convenience
* method that calls the startNewHand method with the current state of the game.
* Starts a new hand using the current game state. This method is a convenience method that
* calls the startNewHand method with the current state of the game.
*/
public void startNewHand() {
roundManager.startNewHand(state);
}
/**
* Processes a player action by validating it against the game rules, executing
* the action, progressing to the next player's turn, and checking if the
* round should progress to the next stage.
* Processes a player action by validating it against the game rules, executing the action,
* progressing to the next player's turn, and checking if the round should progress to the next
* stage.
*
* @param action The player action to be processed.
*/
@@ -72,14 +70,12 @@ public class GameEngine {
}
/**
* Handles a player action by performing the following steps:
* 1. Validates the action against the game rules using the RuleEngine.
* 2. Executes the action, which updates the game state accordingly.
* 3. Advances to the next player's turn using the TurnManager.
* 4. Checks if the round should progress to the next stage (e.g., from pre-flop
* to flop) using the RoundManager.
* Handles a player action by performing the following steps: 1. Validates the action against
* the game rules using the RuleEngine. 2. Executes the action, which updates the game state
* accordingly. 3. Advances to the next player's turn using the TurnManager. 4. Checks if the
* round should progress to the next stage (e.g., from pre-flop to flop) using the RoundManager.
*
* @param state The current game state on which to execute the action.
* @param state The current game state on which to execute the action.
* @param action The player action to be processed.
*/
public void handleAction(GameState state, Action action) {
@@ -7,11 +7,10 @@ import java.util.ArrayList;
import java.util.List;
/**
* RoundManager is responsible for managing the flow of a poker game round. It
* handles the progression of the game through its various phases (pre-flop,
* flop, turn, river) and manages player actions such as posting blinds and
* dealing cards. The RoundManager ensures that the game state is updated
* correctly based on player actions and the current phase of the game.
* RoundManager is responsible for managing the flow of a poker game round. It handles the
* progression of the game through its various phases (pre-flop, flop, turn, river) and manages
* player actions such as posting blinds and dealing cards. The RoundManager ensures that the game
* state is updated correctly based on player actions and the current phase of the game.
*/
public class RoundManager {
@@ -19,9 +18,9 @@ public class RoundManager {
public static final int BIG_BLIND = 200;
/**
* Starts a new hand by initializing the game state, dealing cards to players,
* and posting blinds. This method sets the hand as active and resets any
* necessary state variables to prepare for a new round of play.
* Starts a new hand by initializing the game state, dealing cards to players, and posting
* blinds. This method sets the hand as active and resets any necessary state variables to
* prepare for a new round of play.
*
* @param state The game state to be used for starting the new hand.
*/
@@ -35,13 +34,12 @@ public class RoundManager {
}
/**
* Checks if the betting round is finished and advances the game phase if
* necessary. This method evaluates the current bets of all active players and
* determines if the betting round can be concluded. If all players have met
* the current bet or are all-in, the game phase is advanced to the next stage.
* Checks if the betting round is finished and advances the game phase if necessary. This method
* evaluates the current bets of all active players and determines if the betting round can be
* concluded. If all players have met the current bet or are all-in, the game phase is advanced
* to the next stage.
*
* @param state The current game state to be evaluated for betting round
* progression.
* @param state The current game state to be evaluated for betting round progression.
*/
public void progressIfNeeded(GameState state) {
@@ -51,13 +49,11 @@ public class RoundManager {
}
/**
* Determines if the betting round is finished by checking if all active players
* have met the current bet or are all-in. This method iterates through all
* players in the game state and evaluates their bets against the current bet on
* the table.
* Determines if the betting round is finished by checking if all active players have met the
* current bet or are all-in. This method iterates through all players in the game state and
* evaluates their bets against the current bet on the table.
*
* @param state The current game state to be evaluated for betting round
* completion.
* @param state The current game state to be evaluated for betting round completion.
* @return true if the betting round is finished, false otherwise.
*/
private boolean isBettingRoundFinished(GameState state) {
@@ -82,10 +78,9 @@ public class RoundManager {
}
/**
* Advances the game phase to the next stage (flop, turn, river, or showdown)
* based on the current phase of the game. This method is called when the
* betting round is finished and updates the game state accordingly to reflect
* the new phase of play.
* Advances the game phase to the next stage (flop, turn, river, or showdown) based on the
* current phase of the game. This method is called when the betting round is finished and
* updates the game state accordingly to reflect the new phase of play.
*
* @param state The current game state to be updated with the new phase.
*/
@@ -100,10 +95,9 @@ public class RoundManager {
}
/**
* Handles the posting of blinds at the start of a new hand. This method
* identifies the players responsible for posting the small and big blinds,
* updates their chip counts, adds the blind amounts to the pot, and updates
* the current bets for those players in the game state.
* Handles the posting of blinds at the start of a new hand. This method identifies the players
* responsible for posting the small and big blinds, updates their chip counts, adds the blind
* amounts to the pot, and updates the current bets for those players in the game state.
*
* @param state The current game state to be updated with the posted blinds.
*/
@@ -127,18 +121,13 @@ public class RoundManager {
state.getTableState().setCurrentBet(bigBlind);
}
private void dealCards(GameState state) {
}
private void dealCards(GameState state) {}
private void dealFlop(GameState state) {
}
private void dealFlop(GameState state) {}
private void dealTurn(GameState state) {
}
private void dealTurn(GameState state) {}
private void dealRiver(GameState state) {
}
private void dealRiver(GameState state) {}
private void showdown(GameState state) {
}
private void showdown(GameState state) {}
}
@@ -3,28 +3,23 @@ package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.engine;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* The TurnManager class is responsible for managing the flow of turns in a
* poker
* game. It provides functionality to determine the next player in the sequence
* and update the game state accordingly. The TurnManager ensures that players
* take their turns in the correct order, allowing for a smooth and organized
* gameplay experience.
* The TurnManager class is responsible for managing the flow of turns in a poker game. It provides
* functionality to determine the next player in the sequence and update the game state accordingly.
* The TurnManager ensures that players take their turns in the correct order, allowing for a smooth
* and organized gameplay experience.
*/
public class TurnManager {
/**
* Advances the game state to the next player's turn. This method calculates
* the index of the next player based on the current player index and the total
* number of players in the game. It then updates the game state to reflect
* the new current player.
* Advances the game state to the next player's turn. This method calculates the index of the
* next player based on the current player index and the total number of players in the game. It
* then updates the game state to reflect the new current player.
*
* @param state The current game state that will be updated to reflect the next
* player's turn.
* @param state The current game state that will be updated to reflect the next player's turn.
*/
public void nextPlayer(GameState state) {
int next = (state.getCurrentPlayerIndex() + 1)
% state.getPlayers().size();
int next = (state.getCurrentPlayerIndex() + 1) % state.getPlayers().size();
state.setCurrentPlayerIndex(next);
}
@@ -10,13 +10,11 @@ import java.util.Set;
import java.util.stream.Collectors;
/**
* The HandEvaluator class provides functionality to evaluate a poker hand and
* determine its rank. It analyzes a list of cards and identifies the best
* possible hand according to standard poker rules, such as flushes, straights,
* pairs, and more. The evaluation process involves counting card ranks,
* grouping
* by suits, and checking for specific hand combinations to assign the correct
* hand rank.
* The HandEvaluator class provides functionality to evaluate a poker hand and determine its rank.
* It analyzes a list of cards and identifies the best possible hand according to standard poker
* rules, such as flushes, straights, pairs, and more. The evaluation process involves counting card
* ranks, grouping by suits, and checking for specific hand combinations to assign the correct hand
* rank.
*/
public class HandEvaluator {
private static final int RANK_OFFSET = 2;
@@ -97,9 +95,7 @@ public class HandEvaluator {
return onePair;
}
return new HandRank(
HandRank.Type.HIGH_CARD,
ranks.stream().limit(HAND_SIZE).toList());
return new HandRank(HandRank.Type.HIGH_CARD, ranks.stream().limit(HAND_SIZE).toList());
}
/**
@@ -119,38 +115,32 @@ public class HandEvaluator {
* Helper method to count the occurrences of each card rank in the hand.
*
* @param ranks A list of integer ranks representing the cards in the hand.
* @return A map where the key is the card rank and the value is the count of
* occurrences.
* @return A map where the key is the card rank and the value is the count of occurrences.
*/
private static Map<Integer, Long> getRankCount(List<Integer> ranks) {
return ranks.stream()
.collect(Collectors.groupingBy(r -> r, Collectors.counting()));
return ranks.stream().collect(Collectors.groupingBy(r -> r, Collectors.counting()));
}
/**
* Helper method to group the cards by their suits.
*
* @param cards A list of Card objects representing the player's hand.
* @return A map where the key is the Suit and the value is a list of Cards
* belonging to that suit.
* @return A map where the key is the Suit and the value is a list of Cards belonging to that
* suit.
*/
private static Map<Suit, List<Card>> groupBySuit(List<Card> cards) {
return cards.stream()
.collect(Collectors.groupingBy(Card::getSuit));
return cards.stream().collect(Collectors.groupingBy(Card::getSuit));
}
/**
* Helper method to identify if there is a flush in the hand and return the
* corresponding cards.
* Helper method to identify if there is a flush in the hand and return the corresponding cards.
*
* @param suits A map where the key is the Suit and the value is a list of Cards
* belonging to that suit.
* @return A list of Card objects that form a flush, or null if no flush is
* found.
* @param suits A map where the key is the Suit and the value is a list of Cards belonging to
* that suit.
* @return A list of Card objects that form a flush, or null if no flush is found.
*/
private static List<Card> getFlushCards(Map<Suit, List<Card>> suits) {
return suits.values()
.stream()
return suits.values().stream()
.filter(s -> s.size() >= MIN_FLUSH_SIZE)
.findFirst()
.orElse(null);
@@ -163,11 +153,12 @@ public class HandEvaluator {
* @return A HandRank object representing the flush hand rank.
*/
private static HandRank buildFlush(List<Card> flushCards) {
List<Integer> flushRanks = flushCards.stream()
.map(c -> c.getRank().ordinal() + CARD_VALUE_OFFSET)
.sorted(Comparator.reverseOrder())
.limit(HAND_SIZE)
.toList();
List<Integer> flushRanks =
flushCards.stream()
.map(c -> c.getRank().ordinal() + CARD_VALUE_OFFSET)
.sorted(Comparator.reverseOrder())
.limit(HAND_SIZE)
.toList();
return new HandRank(HandRank.Type.FLUSH, flushRanks);
}
@@ -176,29 +167,31 @@ public class HandEvaluator {
* Helper method to check for a straight flush or royal flush in the hand.
*
* @param flushCards A list of Card objects that form a flush.
* @return A HandRank object representing the straight flush or royal flush hand
* rank, or null if neither is found.
* @return A HandRank object representing the straight flush or royal flush hand rank, or null
* if neither is found.
*/
private static HandRank checkStraightFlush(List<Card> flushCards) {
if (flushCards == null) {
return null;
}
List<Integer> flushRanks = flushCards.stream()
.map(c -> c.getRank().ordinal() + RANK_OFFSET)
.sorted(Comparator.reverseOrder())
.toList();
List<Integer> flushRanks =
flushCards.stream()
.map(c -> c.getRank().ordinal() + RANK_OFFSET)
.sorted(Comparator.reverseOrder())
.toList();
if (!isStraight(flushRanks)) {
return null;
}
if (flushRanks.containsAll(List.of(
ROYAL_FLUSH_ACE,
ROYAL_FLUSH_KING,
ROYAL_FLUSH_QUEEN,
ROYAL_FLUSH_JACK,
ROYAL_FLUSH_TEN))) {
if (flushRanks.containsAll(
List.of(
ROYAL_FLUSH_ACE,
ROYAL_FLUSH_KING,
ROYAL_FLUSH_QUEEN,
ROYAL_FLUSH_JACK,
ROYAL_FLUSH_TEN))) {
return new HandRank(HandRank.Type.ROYAL_FLUSH, flushRanks);
}
@@ -209,10 +202,9 @@ public class HandEvaluator {
/**
* Helper method to check for a four of a kind hand rank.
*
* @param rankCount A map where the key is the card rank and the value is the
* count of occurrences.
* @return A HandRank object representing the four of a kind hand rank, or null
* if not found.
* @param rankCount A map where the key is the card rank and the value is the count of
* occurrences.
* @return A HandRank object representing the four of a kind hand rank, or null if not found.
*/
private static HandRank checkFourOfAKind(Map<Integer, Long> rankCount) {
if (!rankCount.containsValue(FOUR_OF_A_KIND_COUNT)) {
@@ -221,34 +213,31 @@ public class HandEvaluator {
int quad = getRank(rankCount, FOUR_OF_A_KIND);
return new HandRank(
HandRank.Type.FOUR_OF_A_KIND,
List.of(quad));
return new HandRank(HandRank.Type.FOUR_OF_A_KIND, List.of(quad));
}
/**
* Helper method to check for a full house hand rank.
*
* @param rankCount A map where the key is the card rank and the value is the
* count of occurrences.
* @return A HandRank object representing the full house hand rank, or null if
* not found.
* @param rankCount A map where the key is the card rank and the value is the count of
* occurrences.
* @return A HandRank object representing the full house hand rank, or null if not found.
*/
private static HandRank checkFullHouse(Map<Integer, Long> rankCount) {
List<Integer> trips = rankCount.entrySet()
.stream()
.filter(e -> e.getValue() >= THREE_OF_A_KIND)
.map(Map.Entry::getKey)
.sorted(Comparator.reverseOrder())
.toList();
List<Integer> trips =
rankCount.entrySet().stream()
.filter(e -> e.getValue() >= THREE_OF_A_KIND)
.map(Map.Entry::getKey)
.sorted(Comparator.reverseOrder())
.toList();
List<Integer> pairs = rankCount.entrySet()
.stream()
.filter(e -> e.getValue() >= PAIR)
.map(Map.Entry::getKey)
.sorted(Comparator.reverseOrder())
.toList();
List<Integer> pairs =
rankCount.entrySet().stream()
.filter(e -> e.getValue() >= PAIR)
.map(Map.Entry::getKey)
.sorted(Comparator.reverseOrder())
.toList();
if (trips.isEmpty()) {
return null;
@@ -256,27 +245,21 @@ public class HandEvaluator {
int three = trips.get(FIRST_INDEX);
Integer pair = pairs.stream()
.filter(p -> p != three)
.findFirst()
.orElse(null);
Integer pair = pairs.stream().filter(p -> p != three).findFirst().orElse(null);
if (pair == null) {
return null;
}
return new HandRank(
HandRank.Type.FULL_HOUSE,
List.of(three, pair));
return new HandRank(HandRank.Type.FULL_HOUSE, List.of(three, pair));
}
/**
* Helper method to check for a three of a kind hand rank.
*
* @param rankCount A map where the key is the card rank and the value is the
* count of occurrences.
* @return A HandRank object representing the three of a kind hand rank, or null
* if not found.
* @param rankCount A map where the key is the card rank and the value is the count of
* occurrences.
* @return A HandRank object representing the three of a kind hand rank, or null if not found.
*/
private static HandRank checkThreeOfAKind(Map<Integer, Long> rankCount) {
if (!rankCount.containsValue(THREE_OF_A_KIND_COUNT)) {
@@ -285,57 +268,45 @@ public class HandEvaluator {
int tripsRank = getRank(rankCount, THREE_OF_A_KIND_RANK);
return new HandRank(
HandRank.Type.THREE_OF_A_KIND,
List.of(tripsRank));
return new HandRank(HandRank.Type.THREE_OF_A_KIND, List.of(tripsRank));
}
/**
* Helper method to check for a two pair hand rank.
*
* @param rankCount A map where the key is the card rank and the value is the
* count of occurrences.
* @return A HandRank object representing the two pair hand rank, or null if
* not found.
* @param rankCount A map where the key is the card rank and the value is the count of
* occurrences.
* @return A HandRank object representing the two pair hand rank, or null if not found.
*/
private static HandRank checkTwoPair(Map<Integer, Long> rankCount) {
long pairCount = rankCount.values()
.stream()
.filter(v -> v == PAIR)
.count();
long pairCount = rankCount.values().stream().filter(v -> v == PAIR).count();
if (pairCount < PAIR) {
return null;
}
List<Integer> pairRanks = rankCount.entrySet()
.stream()
.filter(e -> e.getValue() == PAIR)
.map(Map.Entry::getKey)
.sorted(Comparator.reverseOrder())
.limit(PAIR)
.toList();
List<Integer> pairRanks =
rankCount.entrySet().stream()
.filter(e -> e.getValue() == PAIR)
.map(Map.Entry::getKey)
.sorted(Comparator.reverseOrder())
.limit(PAIR)
.toList();
return new HandRank(
HandRank.Type.TWO_PAIR,
pairRanks);
return new HandRank(HandRank.Type.TWO_PAIR, pairRanks);
}
/**
* Helper method to check for a one pair hand rank.
*
* @param rankCount A map where the key is the card rank and the value is the
* count of occurrences.
* @return A HandRank object representing the one pair hand rank, or null if
* not found.
* @param rankCount A map where the key is the card rank and the value is the count of
* occurrences.
* @return A HandRank object representing the one pair hand rank, or null if not found.
*/
private static HandRank checkOnePair(Map<Integer, Long> rankCount) {
long pairCount = rankCount.values()
.stream()
.filter(v -> v == PAIR)
.count();
long pairCount = rankCount.values().stream().filter(v -> v == PAIR).count();
if (pairCount != ONE_PAIR) {
return null;
@@ -343,26 +314,19 @@ public class HandEvaluator {
int pair = getRank(rankCount, PAIR);
return new HandRank(
HandRank.Type.ONE_PAIR,
List.of(pair));
return new HandRank(HandRank.Type.ONE_PAIR, List.of(pair));
}
/**
* Helper method to get the rank of a card based on the count of occurrences in
* the hand.
* Helper method to get the rank of a card based on the count of occurrences in the hand.
*
* @param map A map where the key is the card rank and the value is the count
* of occurrences.
* @param count The specific count to look for (e.g., 2 for pairs, 3 for three
* of a kind).
* @return The rank of the card that matches the specified count, or 0 if none
* found.
* @param map A map where the key is the card rank and the value is the count of occurrences.
* @param count The specific count to look for (e.g., 2 for pairs, 3 for three of a kind).
* @return The rank of the card that matches the specified count, or 0 if none found.
*/
private static int getRank(Map<Integer, Long> map, int count) {
return map.entrySet()
.stream()
return map.entrySet().stream()
.filter(e -> e.getValue() == count)
.map(Map.Entry::getKey)
.max(Integer::compare)
@@ -380,12 +344,13 @@ public class HandEvaluator {
Set<Integer> unique = new HashSet<>(ranks);
// Wheel Straight A-2-3-4-5
if (unique.containsAll(List.of(
ROYAL_FLUSH_ACE,
ROYAL_FLUSH_KING,
ROYAL_FLUSH_QUEEN,
ROYAL_FLUSH_JACK,
ROYAL_FLUSH_TEN))) {
if (unique.containsAll(
List.of(
ROYAL_FLUSH_ACE,
ROYAL_FLUSH_KING,
ROYAL_FLUSH_QUEEN,
ROYAL_FLUSH_JACK,
ROYAL_FLUSH_TEN))) {
return true;
}
@@ -3,20 +3,17 @@ package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.evaluator;
import java.util.List;
/**
* HandRank represents the rank of a poker hand, including its type (e.g.,
* flush,
* straight) and the kickers used for tie-breaking. It implements the
* Comparable interface to allow for easy comparison between different hand
* ranks.
* HandRank represents the rank of a poker hand, including its type (e.g., flush, straight) and the
* kickers used for tie-breaking. It implements the Comparable interface to allow for easy
* comparison between different hand ranks.
*/
public class HandRank implements Comparable<HandRank> {
/**
* The Type enumeration defines the different types of poker hands, each with
* an associated strength value for comparison purposes.
* The Type enumeration defines the different types of poker hands, each with an associated
* strength value for comparison purposes.
*/
public enum Type {
HIGH_CARD(1),
ONE_PAIR(2),
TWO_PAIR(3),
@@ -45,7 +42,7 @@ public class HandRank implements Comparable<HandRank> {
/**
* Constructs a HandRank with the specified type and kickers.
*
* @param type The type of the hand (e.g., flush, straight).
* @param type The type of the hand (e.g., flush, straight).
* @param kickers A list of integers representing the kickers for tie-breaking.
*/
public HandRank(Type type, List<Integer> kickers) {
@@ -72,19 +69,17 @@ public class HandRank implements Comparable<HandRank> {
}
/**
* Compares this HandRank with another HandRank for ordering. The comparison is
* based first on the type of the hand and then on the kickers for tie-breaking.
* Compares this HandRank with another HandRank for ordering. The comparison is based first on
* the type of the hand and then on the kickers for tie-breaking.
*
* @param other The other HandRank to compare against.
* @return A negative integer, zero, or a positive integer as this HandRank is
* less than, equal to, or greater than the specified HandRank.
* @return A negative integer, zero, or a positive integer as this HandRank is less than, equal
* to, or greater than the specified HandRank.
*/
@Override
public int compareTo(HandRank other) {
int typeCompare = Integer.compare(
this.type.getStrength(),
other.type.getStrength());
int typeCompare = Integer.compare(this.type.getStrength(), other.type.getStrength());
if (typeCompare != 0) {
return typeCompare;
@@ -92,9 +87,7 @@ public class HandRank implements Comparable<HandRank> {
for (int i = 0; i < Math.min(kickers.size(), other.kickers.size()); i++) {
int cmp = Integer.compare(
kickers.get(i),
other.kickers.get(i));
int cmp = Integer.compare(kickers.get(i), other.kickers.get(i));
if (cmp != 0) {
return cmp;
@@ -5,10 +5,9 @@ import java.util.ArrayList;
import java.util.List;
/**
* The Player class represents a participant in the poker game. It holds
* information about the player's identity, chip count, status, and hand of
* cards. The class provides methods for managing the player's chips, hand, and
* status during the game.
* The Player class represents a participant in the poker game. It holds information about the
* player's identity, chip count, status, and hand of cards. The class provides methods for managing
* the player's chips, hand, and status during the game.
*/
public class Player {
@@ -17,13 +16,13 @@ public class Player {
private PlayerStatus status;
private boolean folded = false;
private List<Card> hand = new ArrayList<>();
private List<Card> hand = new ArrayList<>();
/**
* Constructs a Player with the specified ID and initial chip count. The
* player's status is set to ACTIVE by default.
* Constructs a Player with the specified ID and initial chip count. The player's status is set
* to ACTIVE by default.
*
* @param id The unique identifier for the player.
* @param id The unique identifier for the player.
* @param chips The initial number of chips the player has.
*/
public Player(PlayerId id, int chips) {
@@ -51,8 +50,7 @@ public class Player {
}
/**
* Returns the display name of the player.
* Currently identical to the player ID.
* Returns the display name of the player. Currently identical to the player ID.
*
* @return The player's name.
*/
@@ -70,8 +68,8 @@ public class Player {
}
/**
* Removes a specified amount of chips from the player's total. If the amount
* exceeds the player's current chips, it sets the chip count to zero.
* Removes a specified amount of chips from the player's total. If the amount exceeds the
* player's current chips, it sets the chip count to zero.
*
* @param amount The number of chips to remove from the player.
*/
@@ -127,9 +125,7 @@ public class Player {
hand.add(card);
}
/**
* Clears the player's hand of cards, removing all cards from the hand.
*/
/** Clears the player's hand of cards, removing all cards from the hand. */
public void clearHand() {
hand.clear();
}
@@ -3,16 +3,16 @@ package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player;
import java.util.Objects;
/**
* PlayerId is a value object that represents the unique identifier of a player
* in the game. It encapsulates a string value and provides validation to ensure
* that it is not null. The PlayerId class also includes a factory method for
* creating instances and overrides the toString method for easy representation.
* PlayerId is a value object that represents the unique identifier of a player in the game. It
* encapsulates a string value and provides validation to ensure that it is not null. The PlayerId
* class also includes a factory method for creating instances and overrides the toString method for
* easy representation.
*/
public record PlayerId(String value) {
/**
* Constructs a PlayerId with the specified value. The constructor validates
* that the value is not null.
* Constructs a PlayerId with the specified value. The constructor validates that the value is
* not null.
*
* @param value the string value representing the player's unique identifier
* @throws NullPointerException if the value is null
@@ -32,8 +32,7 @@ public record PlayerId(String value) {
}
/**
* Returns the string representation of the PlayerId, which is the encapsulated
* value.
* Returns the string representation of the PlayerId, which is the encapsulated value.
*
* @return the string value of the PlayerId
*/
@@ -1,10 +1,9 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player;
/**
* The PlayerStatus enumeration represents the various states a player can be in
* during a poker game. It helps to track the player's current status, such as
* whether they are actively participating in the hand, have folded, are all-in,
* or have been eliminated from the game.
* The PlayerStatus enumeration represents the various states a player can be in during a poker
* game. It helps to track the player's current status, such as whether they are actively
* participating in the hand, have folded, are all-in, or have been eliminated from the game.
*/
public enum PlayerStatus {
ACTIVE,
@@ -4,11 +4,10 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.action.Action;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* The Rule interface defines the structure for all rules in the poker game.
* Each rule must provide a validate method that checks if a given action is
* valid based on the current game state. If the action violates the rule, a
* RuleViolationException should be thrown to indicate the specific rule that
* was violated.
* The Rule interface defines the structure for all rules in the poker game. Each rule must provide
* a validate method that checks if a given action is valid based on the current game state. If the
* action violates the rule, a RuleViolationException should be thrown to indicate the specific rule
* that was violated.
*/
public interface Rule {
void validate(GameState state, Action action);
@@ -5,12 +5,10 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
import java.util.List;
/**
* The RuleEngine class is responsible for managing and validating a list of
* rules in the poker game. It provides a method to validate a given action
* against all the rules, ensuring that the action complies with the game's
* regulations. If any rule is violated during validation, a
* RuleViolationException
* will be thrown, indicating the specific rule that was not followed.
* The RuleEngine class is responsible for managing and validating a list of rules in the poker
* game. It provides a method to validate a given action against all the rules, ensuring that the
* action complies with the game's regulations. If any rule is violated during validation, a
* RuleViolationException will be thrown, indicating the specific rule that was not followed.
*/
public class RuleEngine {
@@ -26,11 +24,10 @@ public class RuleEngine {
}
/**
* Validates the given action against all the rules in the RuleEngine. If any
* rule is violated, a RuleViolationException will be thrown, indicating the
* specific rule that was not followed.
* Validates the given action against all the rules in the RuleEngine. If any rule is violated,
* a RuleViolationException will be thrown, indicating the specific rule that was not followed.
*
* @param state The current state of the game.
* @param state The current state of the game.
* @param action The action to be validated against the rules.
* @throws RuleViolationException if any rule is violated during validation.
*/
@@ -1,18 +1,17 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.rules;
/**
* RuleViolationException is a custom exception that is thrown when a player
* action violates a specific rule in the poker game. This exception provides
* a message detailing the nature of the rule violation, allowing for better
* error handling and user feedback when invalid actions are attempted.
* RuleViolationException is a custom exception that is thrown when a player action violates a
* specific rule in the poker game. This exception provides a message detailing the nature of the
* rule violation, allowing for better error handling and user feedback when invalid actions are
* attempted.
*/
public class RuleViolationException extends RuntimeException {
/**
* Constructs a new RuleViolationException with the specified detail message.
*
* @param message The detail message explaining the reason for the rule
* violation.
* @param message The detail message explaining the reason for the rule violation.
*/
public RuleViolationException(String message) {
super(message);
@@ -7,20 +7,18 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.rules.RuleViolationExc
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* The AcceptedActionRule class implements the Rule interface and defines the
* validation logic for accepted player actions in a poker game. It checks
* whether the action type is one of the allowed types (FOLD, CALL, RAISE,
* CHECK, BET, ALL_IN) and throws a RuleViolationException if the action is not
* allowed.
* The AcceptedActionRule class implements the Rule interface and defines the validation logic for
* accepted player actions in a poker game. It checks whether the action type is one of the allowed
* types (FOLD, CALL, RAISE, CHECK, BET, ALL_IN) and throws a RuleViolationException if the action
* is not allowed.
*/
public class AcceptedActionRule implements Rule {
/**
* Validates the given action against the accepted action types for a poker
* game. If the action type is not one of the allowed types, a
* RuleViolationException is thrown.
* Validates the given action against the accepted action types for a poker game. If the action
* type is not one of the allowed types, a RuleViolationException is thrown.
*
* @param state The current state of the game.
* @param state The current state of the game.
* @param action The action to be validated.
* @throws RuleViolationException if the action type is not allowed.
*/
@@ -30,8 +28,7 @@ public class AcceptedActionRule implements Rule {
ActionType type = action.getType();
switch (type) {
case FOLD, CALL, RAISE, CHECK, BET, ALL_IN -> {
}
case FOLD, CALL, RAISE, CHECK, BET, ALL_IN -> {}
default -> throw new RuleViolationException("Action not allowed");
}
}
@@ -10,20 +10,19 @@ import java.util.ArrayList;
import java.util.List;
/**
* The ActionOrderRule class implements the Rule interface and defines the
* validation logic for ensuring that players take their turns in the correct
* order during a poker game. It checks whether the player performing the action
* is the current player whose turn it is, and throws a RuleViolationException
* if the action is attempted out of turn.
* The ActionOrderRule class implements the Rule interface and defines the validation logic for
* ensuring that players take their turns in the correct order during a poker game. It checks
* whether the player performing the action is the current player whose turn it is, and throws a
* RuleViolationException if the action is attempted out of turn.
*/
public class ActionOrderRule implements Rule {
/**
* Validates that the player performing the action is the current player
* whose turn it is in the game. If the action is attempted by a player who
* is not the current player, a RuleViolationException is thrown.
* Validates that the player performing the action is the current player whose turn it is in the
* game. If the action is attempted by a player who is not the current player, a
* RuleViolationException is thrown.
*
* @param state The current state of the game.
* @param state The current state of the game.
* @param action The action to be validated.
* @throws RuleViolationException if the action is attempted out of turn.
*/
@@ -8,21 +8,18 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.rules.RuleViolationExc
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* The AllInRule class implements the Rule interface and defines the validation
* logic for the "all-in" action in a poker game. It checks whether the player
* attempting to go all-in has any chips left, and throws a
* RuleViolationException
* if the player has no chips to bet.
* The AllInRule class implements the Rule interface and defines the validation logic for the
* "all-in" action in a poker game. It checks whether the player attempting to go all-in has any
* chips left, and throws a RuleViolationException if the player has no chips to bet.
*/
public class AllInRule implements Rule {
/**
* Validates the "all-in" action by checking if the player has any chips left.
* If the player has no chips, a RuleViolationException is thrown.
* Validates the "all-in" action by checking if the player has any chips left. If the player has
* no chips, a RuleViolationException is thrown.
*
* @param state The current state of the game.
* @param action The action to be validated, which should be an instance of
* AllInAction.
* @param state The current state of the game.
* @param action The action to be validated, which should be an instance of AllInAction.
* @throws RuleViolationException if the player has no chips to go all-in.
*/
@Override
@@ -7,25 +7,21 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.rules.RuleViolationExc
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* The BindingDeclarationRule class implements the Rule interface and defines
* the
* validation logic for binding declarations in a poker game. It checks whether
* a raise action is an under-raise or string bet by comparing the raise amount
* to the current bet commitment of the player. If the raise amount is less than
* the committed amount, a RuleViolationException is thrown.
* The BindingDeclarationRule class implements the Rule interface and defines the validation logic
* for binding declarations in a poker game. It checks whether a raise action is an under-raise or
* string bet by comparing the raise amount to the current bet commitment of the player. If the
* raise amount is less than the committed amount, a RuleViolationException is thrown.
*/
public class BindingDeclarationRule implements Rule {
/**
* Validates the raise action by checking if the raise amount is less than the
* current bet commitment of the player. If it is, a RuleViolationException is
* thrown, indicating an illegal under-raise or string bet.
* Validates the raise action by checking if the raise amount is less than the current bet
* commitment of the player. If it is, a RuleViolationException is thrown, indicating an illegal
* under-raise or string bet.
*
* @param state The current state of the game.
* @param action The action to be validated, which should be an instance of
* RaiseAction.
* @throws RuleViolationException if the raise amount is less than the current
* bet commitment.
* @param state The current state of the game.
* @param action The action to be validated, which should be an instance of RaiseAction.
* @throws RuleViolationException if the raise amount is less than the current bet commitment.
*/
@Override
public void validate(GameState state, Action action) {
@@ -6,20 +6,19 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.rules.RuleViolationExc
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* The HandActiveRule class implements the Rule interface and defines the
* validation logic for checking if there is an active hand in a poker game.
* It ensures that players can only perform actions when there is an active
* hand,
* and throws a RuleViolationException if there is no active hand.
* The HandActiveRule class implements the Rule interface and defines the validation logic for
* checking if there is an active hand in a poker game. It ensures that players can only perform
* actions when there is an active hand, and throws a RuleViolationException if there is no active
* hand.
*/
public class HandActiveRule implements Rule {
/**
* Validates that there is an active hand in the game. If there is no active
* hand, a RuleViolationException is thrown, indicating that players cannot
* perform actions without an active hand.
* Validates that there is an active hand in the game. If there is no active hand, a
* RuleViolationException is thrown, indicating that players cannot perform actions without an
* active hand.
*
* @param state The current state of the game.
* @param state The current state of the game.
* @param action The action to be validated.
* @throws RuleViolationException if there is no active hand in the game.
*/
@@ -7,22 +7,19 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.rules.RuleViolationExc
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* The MinimumBetRule class implements the Rule interface and defines the
* validation logic for ensuring that a player's bet meets the minimum bet
* requirement in a poker game. It checks if the bet amount is less than the
* minimum bet (usually determined by the big blind) and throws a
* The MinimumBetRule class implements the Rule interface and defines the validation logic for
* ensuring that a player's bet meets the minimum bet requirement in a poker game. It checks if the
* bet amount is less than the minimum bet (usually determined by the big blind) and throws a
* RuleViolationException if the bet is below the minimum.
*/
public class MinimumBetRule implements Rule {
/**
* Validates the bet action by checking if the bet amount is less than the
* minimum bet. If it is, a RuleViolationException is thrown, indicating that
* the bet is below the minimum.
* Validates the bet action by checking if the bet amount is less than the minimum bet. If it
* is, a RuleViolationException is thrown, indicating that the bet is below the minimum.
*
* @param state The current state of the game.
* @param action The action to be validated, which should be an instance of
* BetAction.
* @param state The current state of the game.
* @param action The action to be validated, which should be an instance of BetAction.
* @throws RuleViolationException if the bet amount is below the minimum bet.
*/
@Override
@@ -7,24 +7,21 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.rules.RuleViolationExc
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* The MinimumRaiseRule class implements the Rule interface and defines the
* validation logic for ensuring that a raise action in a poker game meets the
* minimum raise requirement. It checks if the amount of the raise is less than
* the minimum raise defined in the game state, and if so, it throws a
* RuleViolationException indicating that the raise is too small.
* The MinimumRaiseRule class implements the Rule interface and defines the validation logic for
* ensuring that a raise action in a poker game meets the minimum raise requirement. It checks if
* the amount of the raise is less than the minimum raise defined in the game state, and if so, it
* throws a RuleViolationException indicating that the raise is too small.
*/
public class MinimumRaiseRule implements Rule {
/**
* Validates the raise action by checking if the raise amount is less than the
* minimum raise defined in the game state. If it is, a RuleViolationException
* is thrown, indicating that the raise is too small.
* Validates the raise action by checking if the raise amount is less than the minimum raise
* defined in the game state. If it is, a RuleViolationException is thrown, indicating that the
* raise is too small.
*
* @param state The current state of the game.
* @param action The action to be validated, which should be an instance of
* RaiseAction.
* @throws RuleViolationException if the raise amount is less than the minimum
* raise.
* @param state The current state of the game.
* @param action The action to be validated, which should be an instance of RaiseAction.
* @throws RuleViolationException if the raise amount is less than the minimum raise.
*/
@Override
public void validate(GameState state, Action action) {
@@ -37,8 +34,7 @@ public class MinimumRaiseRule implements Rule {
int amount = raise.getAmount();
if (amount < minRaise) {
throw new RuleViolationException(
"Raise too small. Min is " + minRaise);
throw new RuleViolationException("Raise too small. Min is " + minRaise);
}
}
}
@@ -7,27 +7,25 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.rules.RuleViolationExc
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* The OutOfTurnRule class implements the Rule interface and defines the
* validation logic for out-of-turn actions in a poker game. It checks whether
* out-of-turn actions are allowed in the current game state and, if so, whether
* the action type is permitted (e.g., only fold allowed out of turn). If an
* out-of-turn action is not allowed or if the action type is not permitted,
* a RuleViolationException is thrown.
* The OutOfTurnRule class implements the Rule interface and defines the validation logic for
* out-of-turn actions in a poker game. It checks whether out-of-turn actions are allowed in the
* current game state and, if so, whether the action type is permitted (e.g., only fold allowed out
* of turn). If an out-of-turn action is not allowed or if the action type is not permitted, a
* RuleViolationException is thrown.
*/
public class OutOfTurnRule implements Rule {
/**
* Validates the given action against the rules for out-of-turn actions in a
* poker game. If out-of-turn actions are not allowed, the method returns
* without throwing an exception. If out-of-turn actions are allowed, it checks
* whether the action type is permitted (e.g., only fold allowed out of turn)
* and
* throws a RuleViolationException if the action type is not permitted.
* Validates the given action against the rules for out-of-turn actions in a poker game. If
* out-of-turn actions are not allowed, the method returns without throwing an exception. If
* out-of-turn actions are allowed, it checks whether the action type is permitted (e.g., only
* fold allowed out of turn) and throws a RuleViolationException if the action type is not
* permitted.
*
* @param state The current state of the game.
* @param state The current state of the game.
* @param action The action to be validated.
* @throws RuleViolationException if the action is not allowed out of turn or if
* the action type is not permitted.
* @throws RuleViolationException if the action is not allowed out of turn or if the action type
* is not permitted.
*/
@Override
public void validate(GameState state, Action action) {
@@ -7,28 +7,23 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.rules.RuleViolationExc
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state.GameState;
/**
* The RaiseReopenRule class implements the Rule interface and defines the
* validation logic for allowing raises to reopen betting in a poker game. It
* checks if the action is a RaiseAction and if the betting is open for raising.
* If betting is not open or if reopening betting is not allowed, it throws a
* RuleViolationException with an appropriate message.
* The RaiseReopenRule class implements the Rule interface and defines the validation logic for
* allowing raises to reopen betting in a poker game. It checks if the action is a RaiseAction and
* if the betting is open for raising. If betting is not open or if reopening betting is not
* allowed, it throws a RuleViolationException with an appropriate message.
*/
public class RaiseReopenRule implements Rule {
/**
* Validates the raise action by checking if the betting is open for raising and
* if reopening betting is allowed. If betting is not open, a
* RuleViolationException
* is thrown with the message "Betting not open for raise". If reopening betting
* is not allowed, a RuleViolationException is thrown with the message "Raise
* not
* allowed anymore".
* Validates the raise action by checking if the betting is open for raising and if reopening
* betting is allowed. If betting is not open, a RuleViolationException is thrown with the
* message "Betting not open for raise". If reopening betting is not allowed, a
* RuleViolationException is thrown with the message "Raise not allowed anymore".
*
* @param state The current state of the game.
* @param action The action to be validated, which should be an instance of
* RaiseAction.
* @throws RuleViolationException if betting is not open for raising or if
* reopening betting is not allowed.
* @param state The current state of the game.
* @param action The action to be validated, which should be an instance of RaiseAction.
* @throws RuleViolationException if betting is not open for raising or if reopening betting is
* not allowed.
*/
@Override
public void validate(GameState state, Action action) {
@@ -12,21 +12,19 @@ import java.util.ArrayList;
import java.util.List;
/**
* The CardsSpeakRule class implements the Rule interface and defines the logic
* for
* determining the winner of a poker hand based on the players' hole cards and
* the community cards. It evaluates each player's hand, compares their ranks,
* and awards the pot to the player with the best hand.
* The CardsSpeakRule class implements the Rule interface and defines the logic for determining the
* winner of a poker hand based on the players' hole cards and the community cards. It evaluates
* each player's hand, compares their ranks, and awards the pot to the player with the best hand.
*/
public class CardsSpeakRule implements Rule {
/**
* Validates the action for the showdown phase. In this implementation, the
* CardsSpeakRule does not perform any validation, as it is responsible for
* determining the winner based on the players' hands. The validation logic for
* player actions during the showdown phase should be handled by other rules.
* Validates the action for the showdown phase. In this implementation, the CardsSpeakRule does
* not perform any validation, as it is responsible for determining the winner based on the
* players' hands. The validation logic for player actions during the showdown phase should be
* handled by other rules.
*
* @param state The current state of the game.
* @param state The current state of the game.
* @param action The action to be validated.
*/
@Override
@@ -35,15 +33,13 @@ public class CardsSpeakRule implements Rule {
}
/**
* Determines the winner of the poker hand by evaluating each player's hand
* rank based on their hole cards and the community cards. It compares the
* hand ranks of all active players and returns the player with the best hand.
* Determines the winner of the poker hand by evaluating each player's hand rank based on their
* hole cards and the community cards. It compares the hand ranks of all active players and
* returns the player with the best hand.
*
* @param state The current state of the game, which includes player
* information,
* hole cards, and community cards.
* @return The player with the best hand, or null if there are no active
* players.
* @param state The current state of the game, which includes player information, hole cards,
* and community cards.
* @return The player with the best hand, or null if there are no active players.
*/
public Player determineWinner(GameState state) {
@@ -76,13 +72,12 @@ public class CardsSpeakRule implements Rule {
}
/**
* Awards the pot to the winner of the poker hand. It determines the winner(s)
* using the determineWinner method, retrieves the total amount in the pot,
* and adds it to the winner's chips. Finally, it resets the pot for the next
* hand.
* Awards the pot to the winner of the poker hand. It determines the winner(s) using the
* determineWinner method, retrieves the total amount in the pot, and adds it to the winner's
* chips. Finally, it resets the pot for the next hand.
*
* @param state The current state of the game, which includes player information
* and pot details.
* @param state The current state of the game, which includes player information and pot
* details.
*/
public void awardPot(GameState state) {
@@ -4,11 +4,10 @@ import java.util.HashMap;
import java.util.Map;
/**
* Represents the betting state of the current hand, including the pot size,
* the current highest bet, and the individual bets made by each player.
* It keeps track of the total pot, the current bet amount, and the bets made
* by each player. This class is essential for managing the betting rounds and
* ensuring that all players' bets are accounted for during the game.
* Represents the betting state of the current hand, including the pot size, the current highest
* bet, and the individual bets made by each player. It keeps track of the total pot, the current
* bet amount, and the bets made by each player. This class is essential for managing the betting
* rounds and ensuring that all players' bets are accounted for during the game.
*/
public class BettingState {
@@ -1,11 +1,10 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state;
/**
* The GamePhase enumeration represents the different phases of a poker game.
* Each phase corresponds to a specific stage in the game, such as waiting for
* players, dealing cards, and determining the winner. This enumeration is
* essential for managing the flow of the game and ensuring that actions are
* performed at the appropriate times.
* The GamePhase enumeration represents the different phases of a poker game. Each phase corresponds
* to a specific stage in the game, such as waiting for players, dealing cards, and determining the
* winner. This enumeration is essential for managing the flow of the game and ensuring that actions
* are performed at the appropriate times.
*/
public enum GamePhase {
WAITING,
@@ -11,12 +11,11 @@ import java.util.List;
import java.util.Map;
/**
* The GameState class encapsulates the entire state of a poker game at any
* given
* moment. It maintains information about the players, the pot, the current
* phase of the game, the dealer position, and the cards in play. This class is
* central to managing the flow of the game and ensuring that all actions and
* decisions are based on an accurate representation of the current game state.
* The GameState class encapsulates the entire state of a poker game at any given moment. It
* maintains information about the players, the pot, the current phase of the game, the dealer
* position, and the cards in play. This class is central to managing the flow of the game and
* ensuring that all actions and decisions are based on an accurate representation of the current
* game state.
*/
public class GameState {
@@ -99,8 +98,7 @@ public class GameState {
}
/**
* Returns the current state of the table, including player statuses and
* positions.
* Returns the current state of the table, including player statuses and positions.
*
* @return A TableState object representing the current state of the table.
*/
@@ -109,8 +107,8 @@ public class GameState {
}
/**
* Returns the current pot, which contains the total amount of chips bet by
* players in the current hand.
* Returns the current pot, which contains the total amount of chips bet by players in the
* current hand.
*
* @return A Pot object representing the current pot.
*/
@@ -140,10 +138,10 @@ public class GameState {
* Returns the hole cards for a specific player based on their ID.
*
* @param playerId The ID of the player whose hole cards are being requested.
* @return A list of Card objects representing the player's hole cards, or an
* empty list if the player has no hole cards.
* @return A list of Card objects representing the player's hole cards, or an empty list if the
* player has no hole cards.
*/
public List<Card> getHoleCards(PlayerId playerId) {
public List<Card> getHoleCards(PlayerId playerId) {
return holeCards.getOrDefault(playerId, new ArrayList<>());
}
@@ -159,8 +157,8 @@ public class GameState {
/**
* Returns a map of player IDs to their current hole cards.
*
* @return A map where the key is the player ID and the value is a list of
* Card objects representing the player's hole cards.
* @return A map where the key is the player ID and the value is a list of Card objects
* representing the player's hole cards.
*/
public Map<PlayerId, List<Card>> getPlayerCards() {
return holeCards;
@@ -216,19 +214,18 @@ public class GameState {
/**
* Sets the current deck of cards being used in the game.
*
* @param deck A Deck object representing the new deck of cards to be used in
* the game.
* @param deck A Deck object representing the new deck of cards to be used in the game.
*/
public void setDeck(Deck deck) {
this.deck = deck;
}
/**
* Adds a player to the game with the specified ID and initial chip count. This
* method creates a new Player object, adds it to the list of players, and
* initializes the player's current bet and bet commitment in the game state.
* Adds a player to the game with the specified ID and initial chip count. This method creates a
* new Player object, adds it to the list of players, and initializes the player's current bet
* and bet commitment in the game state.
*
* @param id The ID of the player to add.
* @param id The ID of the player to add.
* @param chips The initial number of chips the player has.
*/
public void addPlayer(PlayerId id, int chips) {
@@ -248,37 +245,36 @@ public class GameState {
* Retrieves the current bet amount for a specific player based on their ID.
*
* @param playerId The ID of the player whose current bet is being requested.
* @return An integer representing the current bet amount for the specified
* player, or 0 if the player has not placed any bets.
* @return An integer representing the current bet amount for the specified player, or 0 if the
* player has not placed any bets.
*/
public int getCurrentBet(PlayerId playerId) {
return currentBets.getOrDefault(playerId, 0);
}
/**
* Sets the current bet amount for a specific player based on their ID. This
* method updates the currentBets map with the new bet amount for the specified
* player.
* Sets the current bet amount for a specific player based on their ID. This method updates the
* currentBets map with the new bet amount for the specified player.
*
* @param playerId The ID of the player whose current bet is being set.
* @param amount The new bet amount to be set for the specified player.
* @param amount The new bet amount to be set for the specified player.
*/
public void setCurrentBet(PlayerId playerId, int amount) {
currentBets.put(playerId, amount);
}
/**
* Resets the current bets for all players by clearing the currentBets map. This
* method is typically called at the start of a new hand to ensure that all
* players' bets are reset to zero.
* Resets the current bets for all players by clearing the currentBets map. This method is
* typically called at the start of a new hand to ensure that all players' bets are reset to
* zero.
*/
public void resetBets() {
currentBets.clear();
}
/**
* Adds a specified amount to the pot. This method updates the total amount in
* the pot by adding the given amount to it.
* Adds a specified amount to the pot. This method updates the total amount in the pot by adding
* the given amount to it.
*
* @param amount The amount of chips to be added to the pot.
*/
@@ -287,9 +283,9 @@ public class GameState {
}
/**
* Returns whether out-of-turn actions are allowed in the game. Out-of-turn
* actions refer to players being able to act when it is not their turn, which
* can be a feature in some poker variants or game modes.
* Returns whether out-of-turn actions are allowed in the game. Out-of-turn actions refer to
* players being able to act when it is not their turn, which can be a feature in some poker
* variants or game modes.
*
* @return true if out-of-turn actions are allowed, false otherwise.
*/
@@ -298,12 +294,11 @@ public class GameState {
}
/**
* Sets whether out-of-turn actions are allowed in the game. This method updates
* the allowOutOfTurn flag, which determines if players can act when it is not
* their turn.
* Sets whether out-of-turn actions are allowed in the game. This method updates the
* allowOutOfTurn flag, which determines if players can act when it is not their turn.
*
* @param allowOutOfTurn A boolean value indicating whether out-of-turn actions
* should be allowed in the game.
* @param allowOutOfTurn A boolean value indicating whether out-of-turn actions should be
* allowed in the game.
*/
public void setAllowOutOfTurn(boolean allowOutOfTurn) {
this.allowOutOfTurn = allowOutOfTurn;
@@ -312,9 +307,9 @@ public class GameState {
// PLAYER HELPERS
/**
* Retrieves a player from the game based on their ID. This method searches the
* list of players for a player with the specified ID and returns it. If no
* player with the given ID is found, a RuntimeException is thrown.
* Retrieves a player from the game based on their ID. This method searches the list of players
* for a player with the specified ID and returns it. If no player with the given ID is found, a
* RuntimeException is thrown.
*
* @param id The ID of the player to retrieve.
* @return The Player object corresponding to the specified ID.
@@ -333,29 +328,24 @@ public class GameState {
// BET COMMITMENTS
/**
* Retrieves the current bet commitment for a specific player based on their ID.
* A bet commitment represents the total amount a player has committed to the
* pot in the current hand, including all bets, raises, and calls they have
* made.
* Retrieves the current bet commitment for a specific player based on their ID. A bet
* commitment represents the total amount a player has committed to the pot in the current hand,
* including all bets, raises, and calls they have made.
*
* @param playerId The ID of the player whose current bet commitment is being
* requested.
* @return An integer representing the current bet commitment for the specified
* player, or 0 if the player has not made any bet commitments.
* @param playerId The ID of the player whose current bet commitment is being requested.
* @return An integer representing the current bet commitment for the specified player, or 0 if
* the player has not made any bet commitments.
*/
public int getCurrentBetCommitment(PlayerId playerId) {
return playerBetCommitments.getOrDefault(playerId, 0);
}
/**
* Sets the current bet commitment for a specific player based on their ID. This
* method updates the playerBetCommitments map with the new bet commitment
* amount for the specified player.
* Sets the current bet commitment for a specific player based on their ID. This method updates
* the playerBetCommitments map with the new bet commitment amount for the specified player.
*
* @param playerId The ID of the player whose current bet commitment is being
* set.
* @param amount The new bet commitment amount to be set for the specified
* player.
* @param playerId The ID of the player whose current bet commitment is being set.
* @param amount The new bet commitment amount to be set for the specified player.
*/
public void setCurrentBetCommitment(PlayerId playerId, int amount) {
playerBetCommitments.put(playerId, amount);
@@ -364,15 +354,13 @@ public class GameState {
// CARDS
/**
* Gives hole cards to a specific player based on their ID. This method takes
* two Card objects representing the player's hole cards and adds them to the
* holeCards map under the player's ID.
* Gives hole cards to a specific player based on their ID. This method takes two Card objects
* representing the player's hole cards and adds them to the holeCards map under the player's
* ID.
*
* @param playerId The ID of the player to whom the hole cards are being given.
* @param c1 The first Card object representing one of the player's hole
* cards.
* @param c2 The second Card object representing the other hole card for
* the player.
* @param c1 The first Card object representing one of the player's hole cards.
* @param c2 The second Card object representing the other hole card for the player.
*/
public void giveHoleCards(PlayerId playerId, Card c1, Card c2) {
@@ -384,22 +372,19 @@ public class GameState {
}
/**
* Adds a community card to the game state. This method takes a Card object
* representing a community card and adds it to the list of community cards on
* the table.
* Adds a community card to the game state. This method takes a Card object representing a
* community card and adds it to the list of community cards on the table.
*
* @param card The Card object representing the community card to be added to
* the
* game state.
* @param card The Card object representing the community card to be added to the game state.
*/
public void addCommunityCard(Card card) {
communityCards.add(card);
}
/**
* Resets the community cards by clearing the list of community cards. This
* method is typically called at the start of a new hand to ensure that all
* community cards from the previous hand are removed from the game state.
* Resets the community cards by clearing the list of community cards. This method is typically
* called at the start of a new hand to ensure that all community cards from the previous hand
* are removed from the game state.
*/
public void resetCommunityCards() {
communityCards.clear();
@@ -408,10 +393,9 @@ public class GameState {
// TURN MANAGEMENT
/**
* Advances the turn to the next player in the players list. This method updates
* the currentPlayerIndex by incrementing it and wrapping around to the start of
* the list if necessary, ensuring that the turn order is maintained correctly
* throughout the game.
* Advances the turn to the next player in the players list. This method updates the
* currentPlayerIndex by incrementing it and wrapping around to the start of the list if
* necessary, ensuring that the turn order is maintained correctly throughout the game.
*/
public void nextPlayer() {
int start = currentPlayerIndex;
@@ -431,19 +415,17 @@ public class GameState {
// Dealer Rotation
/**
* Rotates the dealer position to the next player in the players list. This
* method updates the dealerIndex by incrementing it and wrapping around to the
* start of the list if necessary, ensuring that the dealer position rotates
* correctly after each hand.
* Rotates the dealer position to the next player in the players list. This method updates the
* dealerIndex by incrementing it and wrapping around to the start of the list if necessary,
* ensuring that the dealer position rotates correctly after each hand.
*/
public void rotateDealer() {
dealerIndex = (dealerIndex + 1) % playerOrder.size();
}
/**
* Retrieves the current dealer based on the dealerIndex. This method returns
* the Player object corresponding to the current dealer position in the players
* list.
* Retrieves the current dealer based on the dealerIndex. This method returns the Player object
* corresponding to the current dealer position in the players list.
*
* @return The Player object representing the current dealer.
*/
@@ -455,12 +437,10 @@ public class GameState {
// HAND RESET
/**
* Starts a new hand by resetting the game state for the next round of poker.
* This
* method sets the handActive flag to true, resets the game phase to PREFLOP,
* clears the pot, resets all player bets and bet commitments, clears the
* community cards, and initializes a new shuffled deck of cards for the new
* hand.
* Starts a new hand by resetting the game state for the next round of poker. This method sets
* the handActive flag to true, resets the game phase to PREFLOP, clears the pot, resets all
* player bets and bet commitments, clears the community cards, and initializes a new shuffled
* deck of cards for the new hand.
*/
public void startNewHand() {
@@ -486,9 +466,9 @@ public class GameState {
}
/**
* Folds a player in the current hand. This method adds the specified player's ID
* to the set of folded players, indicating that the player has folded and is
* no longer active in the current hand.
* Folds a player in the current hand. This method adds the specified player's ID to the set of
* folded players, indicating that the player has folded and is no longer active in the current
* hand.
*
* @param playerId The ID of the player who is folding.
*/
@@ -497,9 +477,9 @@ public class GameState {
}
/**
* Checks if a specific player has folded in the current hand. This method
* checks if the specified player's ID is present in the set of folded players,
* indicating that the player has folded.
* Checks if a specific player has folded in the current hand. This method checks if the
* specified player's ID is present in the set of folded players, indicating that the player has
* folded.
*
* @param playerId The ID of the player to check for folding status.
* @return true if the player has folded, false otherwise.
@@ -1,11 +1,10 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state;
/**
* The Pot class represents the total amount of chips that players have bet in a
* poker game. It provides methods to add chips to the pot, retrieve the
* current amount, and reset the pot for a new round. This class is essential
* for managing the betting aspect of the game and ensuring that the pot is
* accurately maintained throughout the game.
* The Pot class represents the total amount of chips that players have bet in a poker game. It
* provides methods to add chips to the pot, retrieve the current amount, and reset the pot for a
* new round. This class is essential for managing the betting aspect of the game and ensuring that
* the pot is accurately maintained throughout the game.
*/
public class Pot {
@@ -36,10 +35,7 @@ public class Pot {
// return total;
// }
/**
* Resets the pot to zero, typically used at the end of a round or when
* starting a new game.
*/
/** Resets the pot to zero, typically used at the end of a round or when starting a new game. */
public void reset() {
amount = 0;
}
@@ -1,12 +1,11 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.game.state;
/**
* The TableState class represents the current state of the poker table during a
* game. It keeps track of the current bet, the last raise size, the minimum
* raise amount, and the big blind. Additionally, it manages the betting status,
* including whether betting is currently open and if it can be reopened after
* being closed. The class also tracks the last aggressor's ID to determine who
* made the most recent aggressive action (like a raise) in the betting round.
* The TableState class represents the current state of the poker table during a game. It keeps
* track of the current bet, the last raise size, the minimum raise amount, and the big blind.
* Additionally, it manages the betting status, including whether betting is currently open and if
* it can be reopened after being closed. The class also tracks the last aggressor's ID to determine
* who made the most recent aggressive action (like a raise) in the betting round.
*/
public class TableState {
@@ -21,9 +20,9 @@ public class TableState {
private String lastAggressorId;
/**
* Retrieves the current bet amount for the table. This value represents the
* highest bet that has been placed in the current betting round and is used to
* determine how much players need to call or raise to stay in the hand.
* Retrieves the current bet amount for the table. This value represents the highest bet that
* has been placed in the current betting round and is used to determine how much players need
* to call or raise to stay in the hand.
*
* @return The current bet amount for the table.
*/
@@ -32,9 +31,8 @@ public class TableState {
}
/**
* Sets the current bet amount for the table. This method is typically called
* when a player places a bet or raises, updating the current bet to reflect
* the new amount.
* Sets the current bet amount for the table. This method is typically called when a player
* places a bet or raises, updating the current bet to reflect the new amount.
*
* @param currentBet The new current bet amount to set for the table.
*/
@@ -43,8 +41,8 @@ public class TableState {
}
/**
* Returns the big blind amount. The big blind serves as a baseline
* for betting and is often used to determine the minimum bet or raise.
* Returns the big blind amount. The big blind serves as a baseline for betting and is often
* used to determine the minimum bet or raise.
*
* @return The big blind amount.
*/
@@ -53,9 +51,8 @@ public class TableState {
}
/**
* Sets the big blind amount for the game. The big blind is a forced bet that
* players must post before the cards are dealt, and it serves as a baseline for
* betting in the game.
* Sets the big blind amount for the game. The big blind is a forced bet that players must post
* before the cards are dealt, and it serves as a baseline for betting in the game.
*
* @param bigBlind The amount to set as the big blind for the game.
*/
@@ -64,9 +61,9 @@ public class TableState {
}
/**
* Retrieves the minimum raise amount for the current betting round. The
* minimum raise is typically determined by the size of the last raise or the
* big blind, ensuring that players must raise by at least a certain amount.
* Retrieves the minimum raise amount for the current betting round. The minimum raise is
* typically determined by the size of the last raise or the big blind, ensuring that players
* must raise by at least a certain amount.
*
* @return The minimum raise amount for the current betting round.
*/
@@ -75,21 +72,19 @@ public class TableState {
}
/**
* Sets the minimum raise amount for the current betting round. This method is
* typically called after a raise is made, updating the minimum raise to ensure
* that subsequent raises meet the required amount.
* Sets the minimum raise amount for the current betting round. This method is typically called
* after a raise is made, updating the minimum raise to ensure that subsequent raises meet the
* required amount.
*
* @param minRaise The new minimum raise amount to set for the current betting
* round.
* @param minRaise The new minimum raise amount to set for the current betting round.
*/
public void setMinRaise(int minRaise) {
this.minRaise = minRaise;
}
/**
* Checks if betting is currently open at the table. This status indicates
* whether players are allowed to place bets or raises during the current
* betting round.
* Checks if betting is currently open at the table. This status indicates whether players are
* allowed to place bets or raises during the current betting round.
*
* @return true if betting is open, false otherwise.
*/
@@ -98,21 +93,20 @@ public class TableState {
}
/**
* Sets the betting status for the table. This method can be used to open or
* close betting during a betting round, controlling whether players can place
* bets or raises.
* Sets the betting status for the table. This method can be used to open or close betting
* during a betting round, controlling whether players can place bets or raises.
*
* @param bettingOpen The new betting status to set for the table (true for
* open, false for closed).
* @param bettingOpen The new betting status to set for the table (true for open, false for
* closed).
*/
public void setBettingOpen(boolean bettingOpen) {
this.bettingOpen = bettingOpen;
}
/**
* Checks if betting can be reopened after being closed. This status allows for
* scenarios where betting may be temporarily closed (e.g., after a raise) but
* can be reopened to allow other players to respond.
* Checks if betting can be reopened after being closed. This status allows for scenarios where
* betting may be temporarily closed (e.g., after a raise) but can be reopened to allow other
* players to respond.
*
* @return true if betting can be reopened, false otherwise.
*/
@@ -121,22 +115,21 @@ public class TableState {
}
/**
* Sets whether betting can be reopened after being closed. This method is
* typically called after a raise is made, allowing for the possibility of
* reopening betting to let other players respond to the raise.
* Sets whether betting can be reopened after being closed. This method is typically called
* after a raise is made, allowing for the possibility of reopening betting to let other players
* respond to the raise.
*
* @param canReopenBetting The new status indicating whether betting can be
* reopened (true or false).
* @param canReopenBetting The new status indicating whether betting can be reopened (true or
* false).
*/
public void setCanReopenBetting(boolean canReopenBetting) {
this.canReopenBetting = canReopenBetting;
}
/**
* Retrieves the ID of the last aggressor in the current betting round. The
* last aggressor is the player who made the most recent aggressive action (like
* a raise) and is important for determining the flow of betting and who may
* have the opportunity to respond.
* Retrieves the ID of the last aggressor in the current betting round. The last aggressor is
* the player who made the most recent aggressive action (like a raise) and is important for
* determining the flow of betting and who may have the opportunity to respond.
*
* @return The ID of the last aggressor in the current betting round.
*/
@@ -145,12 +138,11 @@ public class TableState {
}
/**
* Sets the ID of the last aggressor in the current betting round. This method
* is typically called after a player makes an aggressive action (like a raise),
* updating the last aggressor ID to reflect the most recent aggressive action.
* Sets the ID of the last aggressor in the current betting round. This method is typically
* called after a player makes an aggressive action (like a raise), updating the last aggressor
* ID to reflect the most recent aggressive action.
*
* @param lastAggressorId The new ID of the last aggressor to set for the
* current betting round.
* @param lastAggressorId The new ID of the last aggressor to set for the current betting round.
*/
public void setLastAggressorId(String lastAggressorId) {
this.lastAggressorId = lastAggressorId;
@@ -1,57 +1,58 @@
package ch.unibas.dmi.dbis.cs108.casono.server.domain.game;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.deck.Card;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.deck.Deck;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.deck.Rank;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.deck.Suit;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.engine.GameEngine;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.evaluator.HandEvaluator;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.evaluator.HandRank;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player.PlayerId;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.rules.RuleEngine;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.engine.RoundManager;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.engine.TurnManager;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.evaluator.HandEvaluator;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.evaluator.HandRank;
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.rules.RuleEngine;
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.game.deck.Card;
import ch.unibas.dmi.dbis.cs108.casono.server.domain.game.player.Player;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import org.junit.jupiter.api.Test;
import java.util.*;
import static org.junit.jupiter.api.Assertions.*;
import java.util.*;
import java.util.logging.Logger;
/**
* The GameControllerTest class contains unit tests for the GameController
* class,
* which manages the flow of a poker game. These tests simulate various game
* scenarios, including player actions, card dealing, and hand evaluation, to
* ensure that the GameController behaves as expected under different
* conditions.
* The GameControllerTest class contains unit tests for the GameController class, which manages the
* flow of a poker game. These tests simulate various game scenarios, including player actions, card
* dealing, and hand evaluation, to ensure that the GameController behaves as expected under
* different conditions.
*/
public class GameControllerTest {
private static final Logger logger = Logger.getLogger(GameControllerTest.class.getName());
private static final Logger LOGGER = Logger.getLogger(GameControllerTest.class.getName());
/**
* This test simulates a specific game scenario where Julian is expected to
* win with a Two Pair hand. It sets up a fixed deck to ensure that the
* desired cards are dealt to the players and verifies that the hand
* evaluation correctly identifies Julian as the winner.
* This test simulates a specific game scenario where Julian is expected to win with a Two Pair
* hand. It sets up a fixed deck to ensure that the desired cards are dealt to the players and
* verifies that the hand evaluation correctly identifies Julian as the winner.
*/
@Test
public void testFullPokerGameSimulation1() {
GameState state = new GameState();
GameEngine engine = new GameEngine(
state,
new RuleEngine(new ArrayList<>()),
new RoundManager(),
new TurnManager());
GameEngine engine =
new GameEngine(
state,
new RuleEngine(new ArrayList<>()),
new RoundManager(),
new TurnManager());
GameController game = new GameController(engine);
@@ -116,24 +117,25 @@ public class GameControllerTest {
assertEquals(4, game.getState().getPlayers().size());
logger.info("Test 1 was successfully completed");
LOGGER.info("Test 1 was successfully completed");
}
/**
* This test simulates a full poker game, including player actions, card
* dealing, and hand evaluation. It verifies that the game state is updated
* correctly throughout the game and that the expected outcomes are achieved.
* This test simulates a full poker game, including player actions, card dealing, and hand
* evaluation. It verifies that the game state is updated correctly throughout the game and that
* the expected outcomes are achieved.
*/
@Test
public void testFullPokerGameSimulation2() {
GameState state = new GameState();
GameEngine engine = new GameEngine(
state,
new RuleEngine(new ArrayList<>()),
new RoundManager(),
new TurnManager());
GameEngine engine =
new GameEngine(
state,
new RuleEngine(new ArrayList<>()),
new RoundManager(),
new TurnManager());
GameController game = new GameController(engine);
@@ -142,24 +144,15 @@ public class GameControllerTest {
game.addPlayer(PlayerId.of("Jona"), 20000);
game.addPlayer(PlayerId.of("Lars"), 20000);
assertEquals(
4,
game.getState().getPlayers().size(),
"There should be exactly 4 players");
assertEquals(4, game.getState().getPlayers().size(), "There should be exactly 4 players");
game.startGame();
assertEquals(
GamePhase.PREFLOP,
game.getState().getPhase(),
"The hand must start preflop");
assertEquals(GamePhase.PREFLOP, game.getState().getPhase(), "The hand must start preflop");
Map<PlayerId, List<Card>> playerCards = game.getPlayerCards();
assertEquals(
4,
playerCards.size(),
"All players must receive cards");
assertEquals(4, playerCards.size(), "All players must receive cards");
for (Map.Entry<PlayerId, List<Card>> entry : playerCards.entrySet()) {
@@ -177,9 +170,7 @@ public class GameControllerTest {
String key = c.getRank() + "-" + c.getSuit();
assertFalse(
seenCards.contains(key),
"Duplicate card found: " + key);
assertFalse(seenCards.contains(key), "Duplicate card found: " + key);
seenCards.add(key);
}
@@ -196,91 +187,68 @@ public class GameControllerTest {
int potAfter = game.getState().getPot().getAmount();
assertTrue(
potAfter >= potBefore,
"The pot must be larger after actions");
assertTrue(potAfter >= potBefore, "The pot must be larger after actions");
game.dealFlop();
assertEquals(
3,
game.getCommunityCards().size(),
"The flop must have 3 cards");
assertEquals(3, game.getCommunityCards().size(), "The flop must have 3 cards");
game.dealTurn();
assertEquals(
4,
game.getCommunityCards().size(),
"A turn must result in 4 cards");
assertEquals(4, game.getCommunityCards().size(), "A turn must result in 4 cards");
game.dealRiver();
assertEquals(
5,
game.getCommunityCards().size(),
"The river must consist of 5 cards");
assertEquals(5, game.getCommunityCards().size(), "The river must consist of 5 cards");
for (Card c : game.getCommunityCards()) {
String key = c.getRank() + "-" + c.getSuit();
assertFalse(
seenCards.contains(key),
"Duplicate board card detected: " + key);
assertFalse(seenCards.contains(key), "Duplicate board card detected: " + key);
seenCards.add(key);
}
assertTrue(
seenCards.size() <= 52,
"There can be a maximum of 52 cards");
assertTrue(seenCards.size() <= 52, "There can be a maximum of 52 cards");
assertTrue(
game.getState().getPot().getAmount() > 0,
"The pot must contain chips");
assertTrue(game.getState().getPot().getAmount() > 0, "The pot must contain chips");
for (Player p : game.getState().getPlayers()) {
assertTrue(
p.getChips() >= 0,
"A player may not have any negative chips: " + p.getId());
assertTrue(p.getChips() >= 0, "A player may not have any negative chips: " + p.getId());
}
assertEquals(
4,
game.getState().getPlayers().size(),
"The number of players must not change");
4, game.getState().getPlayers().size(), "The number of players must not change");
for (Player p : game.getState().getPlayers()) {
logger.info(
p.getId() +
" | Chips: " + p.getChips());
LOGGER.info(p.getId() + " | Chips: " + p.getChips());
}
logger.info("Pot: " + game.getState().getPot().getAmount());
logger.info("Board: " + game.getCommunityCards());
LOGGER.info("Pot: " + game.getState().getPot().getAmount());
LOGGER.info("Board: " + game.getCommunityCards());
logger.info("Test 2 was successfully completed");
LOGGER.info("Test 2 was successfully completed");
}
/**
* This test simulates a specific game scenario where Julian is expected to
* win with a Two Pair hand. It sets up a fixed deck to ensure that the
* desired cards are dealt to the players and verifies that the hand
* evaluation correctly identifies Julian as the winner.
* This test simulates a specific game scenario where Julian is expected to win with a Two Pair
* hand. It sets up a fixed deck to ensure that the desired cards are dealt to the players and
* verifies that the hand evaluation correctly identifies Julian as the winner.
*/
@Test
public void testFullPokerGameSimulation3() {
GameState state = new GameState();
GameEngine engine = new GameEngine(
state,
new RuleEngine(new ArrayList<>()),
new RoundManager(),
new TurnManager());
GameEngine engine =
new GameEngine(
state,
new RuleEngine(new ArrayList<>()),
new RoundManager(),
new TurnManager());
GameController game = new GameController(engine);
@@ -350,25 +318,26 @@ public class GameControllerTest {
assertTrue(julianRank.compareTo(larsRank) > 0);
logger.info("Correct scenario: Julian wins with two pair.");
logger.info("Test 3 was successfully completed");
LOGGER.info("Correct scenario: Julian wins with two pair.");
LOGGER.info("Test 3 was successfully completed");
}
/**
* This test simulates a full poker game, including player actions, card
* dealing, and hand evaluation. It verifies that the game state is updated
* correctly throughout the game and that the expected outcomes are achieved.
* This test simulates a full poker game, including player actions, card dealing, and hand
* evaluation. It verifies that the game state is updated correctly throughout the game and that
* the expected outcomes are achieved.
*/
@Test
public void testFullPokerGameSimulation4() {
GameState state = new GameState();
GameEngine engine = new GameEngine(
state,
new RuleEngine(new ArrayList<>()),
new RoundManager(),
new TurnManager());
GameEngine engine =
new GameEngine(
state,
new RuleEngine(new ArrayList<>()),
new RoundManager(),
new TurnManager());
GameController game = new GameController(engine);
@@ -431,35 +400,34 @@ public class GameControllerTest {
assertTrue(game.getState().getPot().getAmount() > 0, "Pot must not be zero");
assertEquals(4, game.getState().getPlayers().size(),
"Player count must remain stable");
assertEquals(4, game.getState().getPlayers().size(), "Player count must remain stable");
long activePlayers = game.getState().getPlayers().stream()
.filter(p -> p.getChips() > 0)
.count();
long activePlayers =
game.getState().getPlayers().stream().filter(p -> p.getChips() > 0).count();
assertTrue(activePlayers >= 1, "At least one player must still have chips");
assertNotNull(game.getState().getPhase());
logger.info("Test 4 was successfully completed");
LOGGER.info("Test 4 was successfully completed");
}
/**
* This test simulates a full poker game, including player actions, card
* dealing, and hand evaluation. It verifies that the game state is updated
* correctly throughout the game and that the expected outcomes are achieved.
* This test simulates a full poker game, including player actions, card dealing, and hand
* evaluation. It verifies that the game state is updated correctly throughout the game and that
* the expected outcomes are achieved.
*/
@Test
public void testFullPokerGameSimulation5() {
GameState state = new GameState();
GameEngine engine = new GameEngine(
state,
new RuleEngine(new ArrayList<>()),
new RoundManager(),
new TurnManager());
GameEngine engine =
new GameEngine(
state,
new RuleEngine(new ArrayList<>()),
new RoundManager(),
new TurnManager());
GameController game = new GameController(engine);
@@ -476,8 +444,7 @@ public class GameControllerTest {
game.playerCall(PlayerId.of("ShortStack"));
for (Player p : game.getState().getPlayers()) {
assertTrue(p.getChips() >= 0,
"Negative chips detected for " + p.getId());
assertTrue(p.getChips() >= 0, "Negative chips detected for " + p.getId());
}
assertTrue(game.getState().getPot().getAmount() > 0);
@@ -490,9 +457,8 @@ public class GameControllerTest {
game.playerFold(PlayerId.of("Caller"));
game.playerFold(PlayerId.of("MidStack"));
long activePlayers = game.getState().getPlayers().stream()
.filter(p -> p.getChips() > 0)
.count();
long activePlayers =
game.getState().getPlayers().stream().filter(p -> p.getChips() > 0).count();
assertTrue(activePlayers >= 1, "At least one player must remain");
@@ -529,12 +495,10 @@ public class GameControllerTest {
assertNotNull(winner, "Winner should not be null");
assertTrue(
game.getPlayerCards().containsKey(winner),
"Winner must be a valid player");
assertTrue(game.getPlayerCards().containsKey(winner), "Winner must be a valid player");
logger.info("Winner determined: " + winner);
LOGGER.info("Winner determined: " + winner);
logger.info("Test 5 was successfully completed");
LOGGER.info("Test 5 was successfully completed");
}
}