+151
@@ -27,6 +27,12 @@ public class RoundManager {
|
||||
public static final int SMALL_BLIND = 100;
|
||||
public static final int BIG_BLIND = 200;
|
||||
|
||||
/**
|
||||
* Starts a new hand by resetting the game state, ensuring a deck is available, dealing hole cards
|
||||
* to players, posting blinds, and setting the first player to act for the preflop phase.
|
||||
*
|
||||
* @param state The GameState object representing the current state of the game, which will be modified to
|
||||
*/
|
||||
public void startNewHand(GameState state) {
|
||||
// Use GameState's canonical reset
|
||||
state.startNewHand();
|
||||
@@ -44,12 +50,19 @@ public class RoundManager {
|
||||
state.setCurrentPlayerToPreflopFirstToAct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current betting round is finished and advances the game phase if necessary.
|
||||
*
|
||||
* @param state The GameState object representing the current state of the game,
|
||||
* which may be modified to advance the phase or end the hand.
|
||||
*/
|
||||
public void progressIfNeeded(GameState state) {
|
||||
if (state.getPhase() == null) {
|
||||
state.setPhase(GamePhase.PREFLOP);
|
||||
}
|
||||
|
||||
if (state.countNonFoldedPlayers() == 1) {
|
||||
state.setHandActive(false);
|
||||
state.setPhase(GamePhase.FINISHED);
|
||||
return;
|
||||
}
|
||||
@@ -59,9 +72,27 @@ public class RoundManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the current betting round is finished by checking if all active
|
||||
* players have met the current bet or are all-in and by handling special cases for
|
||||
* preflop betting rounds.
|
||||
*
|
||||
* @param state The GameState object representing the current state of the game,
|
||||
* which is used to evaluate the betting round status.
|
||||
* @return true if the betting round is finished and the game can progress to the
|
||||
* next phase, false otherwise.
|
||||
*/
|
||||
private boolean isBettingRoundFinished(GameState state) {
|
||||
int target = state.getTableState().getCurrentBet();
|
||||
|
||||
if (target == 0 && isPostflopStreet(state.getPhase()) && !allActivePlayersActedThisRound(state)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isPendingBigBlindOption(state, target)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Player p : state.getPlayers()) {
|
||||
if (p == null) {
|
||||
continue;
|
||||
@@ -80,6 +111,79 @@ public class RoundManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to determine if the current game phase is a postflop street (FLOP, TURN, RIVER).
|
||||
*
|
||||
* @param phase The GamePhase to check, which is used to determine if the current street is postflop.
|
||||
* @return true if the phase is FLOP, TURN, or RIVER, indicating a postflop street, false otherwise.
|
||||
*/
|
||||
private boolean isPostflopStreet(GamePhase phase) {
|
||||
return phase == GamePhase.FLOP || phase == GamePhase.TURN || phase == GamePhase.RIVER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to check if all active players have acted in the current betting round.
|
||||
* This is used to handle the special case of preflop rounds where no bets have been made yet,
|
||||
* but players still need to have the opportunity to act.
|
||||
*
|
||||
* @param state The GameState object representing the current state of the game, which is
|
||||
* used to check if all active players have acted in the current round.
|
||||
* @return true if all active players have acted in the current round, false if there are
|
||||
* still active players who have not acted yet.
|
||||
*/
|
||||
private boolean allActivePlayersActedThisRound(GameState state) {
|
||||
for (Player p : state.getPlayers()) {
|
||||
if (p == null || p.isFolded() || p.isAllIn()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!state.hasActedThisRound(p.getId())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to determine if the current player has a pending big blind option
|
||||
* in the preflop betting round.
|
||||
*
|
||||
* @param state The GameState object representing the current state of the game,
|
||||
* which is used to determine if the big blind has a pending option
|
||||
* in the preflop round.
|
||||
* @param target The current target bet that players need to meet, which is used to
|
||||
* check if the big blind has a pending option when the target is
|
||||
* equal to the big blind amount.
|
||||
* @return true if the big blind has a pending option to act in the preflop round,
|
||||
* false otherwise.
|
||||
*/
|
||||
private boolean isPendingBigBlindOption(GameState state, int target) {
|
||||
if (state == null || state.getPhase() != GamePhase.PREFLOP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target != BIG_BLIND) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int size = state.getPlayerCount();
|
||||
if (size < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int dealer = state.getDealerIndex();
|
||||
int bigBlindIndex = (size == 2) ? (dealer + 1) % size : (dealer + 2) % size;
|
||||
|
||||
return state.getCurrentPlayerIndex() == bigBlindIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances the game phase to the next stage (FLOP, TURN, RIVER, SHOWDOWN) based on the current phase.
|
||||
*
|
||||
* @param state The GameState object representing the current state of the game, which will be modified
|
||||
* to advance the phase and deal community cards as needed when progressing to the
|
||||
* next stage of the hand.
|
||||
*/
|
||||
private void advancePhase(GameState state) {
|
||||
switch (state.getPhase()) {
|
||||
case PREFLOP -> dealFlop(state);
|
||||
@@ -93,6 +197,13 @@ public class RoundManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that a deck of cards is available in the game state.
|
||||
*
|
||||
* @param state The GameState object representing the current state of the game,
|
||||
* which will be modified to include a new shuffled deck if one
|
||||
* does not already exist.
|
||||
*/
|
||||
private void ensureDeck(GameState state) {
|
||||
Deck deck = state.getDeck();
|
||||
if (deck == null) {
|
||||
@@ -102,6 +213,13 @@ public class RoundManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deals hole cards to each player in the game state by drawing two cards from the
|
||||
* deck for each player and assigning them as their hole cards.
|
||||
*
|
||||
* @param state The GameState object representing the current state of the game,
|
||||
* which will be modified to assign hole cards to each active player.
|
||||
*/
|
||||
private void dealHoleCards(GameState state) {
|
||||
Deck deck = state.getDeck();
|
||||
|
||||
@@ -165,6 +283,15 @@ public class RoundManager {
|
||||
state.getTableState().setCurrentBet(BIG_BLIND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deals the flop by drawing three community cards from the deck and adding them
|
||||
* to the game state, then setting the game phase to FLOP and resetting bets for
|
||||
* the new betting round.
|
||||
*
|
||||
* @param state The GameState object representing the current state of the game,
|
||||
* which will be modified to add three community cards for the flop,
|
||||
* set the phase to FLOP, and reset bets for the new betting round.
|
||||
*/
|
||||
private void dealFlop(GameState state) {
|
||||
ensureDeck(state);
|
||||
Deck deck = state.getDeck();
|
||||
@@ -180,6 +307,15 @@ public class RoundManager {
|
||||
state.setCurrentPlayerToPostflopFirstToAct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deals the turn by drawing one community card from the deck and adding it to
|
||||
* the game state, then setting the game phase to TURN and resetting bets for
|
||||
* the new betting round.
|
||||
*
|
||||
* @param state The GameState object representing the current state of the game,
|
||||
* which will be modified to add one community card for the turn,
|
||||
* set the phase to TURN, and reset bets for the new betting round.
|
||||
*/
|
||||
private void dealTurn(GameState state) {
|
||||
ensureDeck(state);
|
||||
Deck deck = state.getDeck();
|
||||
@@ -193,6 +329,15 @@ public class RoundManager {
|
||||
state.setCurrentPlayerToPostflopFirstToAct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deals the river by drawing one community card from the deck and adding it
|
||||
* to the game state, then setting the game phase to RIVER and resetting bets
|
||||
* for the new betting round.
|
||||
*
|
||||
* @param state The GameState object representing the current state of the game,
|
||||
* which will be modified to add one community card for the river,
|
||||
* set the phase to RIVER, and reset bets for the new betting round.
|
||||
*/
|
||||
private void dealRiver(GameState state) {
|
||||
ensureDeck(state);
|
||||
Deck deck = state.getDeck();
|
||||
@@ -206,6 +351,12 @@ public class RoundManager {
|
||||
state.setCurrentPlayerToPostflopFirstToAct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the showdown phase by setting the game phase to SHOWDOWN.
|
||||
*
|
||||
* @param state The GameState object representing the current state of the game,
|
||||
* which will be modified to set the phase to SHOWDOWN.
|
||||
*/
|
||||
private void showdown(GameState state) {
|
||||
state.setPhase(GamePhase.SHOWDOWN);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user