fix: seat restoration + chip refund on hand error, NoLimit max_raises
Critical fix: complete_hand() now restores seats when run_to_completion() fails, preventing silent NotEnoughPlayers termination that killed simulations at random seeds. Wagered chips are refunded before reset to prevent chip destruction on error path. Also adds max_raises: Option<usize> to BetLimit::NoLimit, propagated across all game/bot/tournament construction sites. NotEnoughPlayers now logs a warning with hand count instead of silently breaking the simulation loop.
This commit is contained in:
parent
edf8d7ae3f
commit
d00df65a98
15 changed files with 131 additions and 41 deletions
|
|
@ -296,7 +296,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn fold_is_always_valid() {
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
assert!(validate_action(
|
||||
&Action::Fold,
|
||||
pid(1),
|
||||
|
|
@ -313,7 +313,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn check_allowed_when_no_bet() {
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
assert!(validate_action(
|
||||
&Action::Check,
|
||||
pid(1),
|
||||
|
|
@ -330,7 +330,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn check_not_allowed_when_bet_exists() {
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
let result = validate_action(
|
||||
&Action::Check,
|
||||
pid(1),
|
||||
|
|
@ -347,7 +347,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn call_always_valid_with_chips() {
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
assert!(validate_action(
|
||||
&Action::Call,
|
||||
pid(1),
|
||||
|
|
@ -364,7 +364,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn raise_below_minimum_rejected() {
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 20 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 20, max_raises: None };
|
||||
let result = validate_action(
|
||||
&Action::Raise { total: 30 },
|
||||
pid(1),
|
||||
|
|
@ -384,7 +384,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn raise_with_insufficient_chips_rejected() {
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
let result = validate_action(
|
||||
&Action::Raise { total: 200 },
|
||||
pid(1),
|
||||
|
|
@ -404,7 +404,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn all_in_with_zero_chips_rejected() {
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
let result = validate_action(
|
||||
&Action::AllIn,
|
||||
pid(1),
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ pub enum BetLimit {
|
|||
NoLimit {
|
||||
/// Minimum raise increment.
|
||||
min_raise: ChipCount,
|
||||
/// Optional cap on voluntary raises per street (None = unlimited).
|
||||
/// When set, the Nth raise is converted to a call automatically.
|
||||
max_raises: Option<usize>,
|
||||
},
|
||||
|
||||
/// Pot-Limit — players may raise up to the current pot size.
|
||||
|
|
@ -80,7 +83,7 @@ pub trait BettingRules {
|
|||
impl BettingRules for BetLimit {
|
||||
fn min_raise_amount(&self, _current_bet: ChipCount, previous_raise: ChipCount) -> ChipCount {
|
||||
match self {
|
||||
BetLimit::NoLimit { min_raise } => (*min_raise).max(previous_raise),
|
||||
BetLimit::NoLimit { min_raise, .. } => (*min_raise).max(previous_raise),
|
||||
BetLimit::PotLimit { min_raise } => (*min_raise).max(previous_raise),
|
||||
BetLimit::FixedLimit {
|
||||
small_bet,
|
||||
|
|
@ -147,6 +150,10 @@ impl BettingRules for BetLimit {
|
|||
/// unused — the cap is intentionally the same on every street.
|
||||
fn can_raise(&self, _street: Street, raises_this_round: usize) -> bool {
|
||||
match self {
|
||||
BetLimit::NoLimit {
|
||||
max_raises: Some(cap),
|
||||
..
|
||||
} => raises_this_round < *cap,
|
||||
BetLimit::NoLimit { .. } | BetLimit::PotLimit { .. } => true,
|
||||
BetLimit::FixedLimit { .. } => raises_this_round < 3,
|
||||
}
|
||||
|
|
@ -267,7 +274,7 @@ mod tests {
|
|||
|
||||
/// Helper — No-Limit with a minimum raise of 10 (big-blind sized).
|
||||
fn nl() -> BetLimit {
|
||||
BetLimit::NoLimit { min_raise: 10 }
|
||||
BetLimit::NoLimit { min_raise: 10, max_raises: None }
|
||||
}
|
||||
|
||||
/// Helper — Pot-Limit with a minimum raise of 10.
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ mod tests {
|
|||
fn make_game_info(current_bet: ChipCount, wagered_this_round: ChipCount) -> GameInfo {
|
||||
GameInfo {
|
||||
num_seats: 2,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10, max_raises: None },
|
||||
small_blind: 5,
|
||||
big_blind: 10,
|
||||
ante: 0,
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ mod tests {
|
|||
) -> GameInfo {
|
||||
GameInfo {
|
||||
num_seats: 2,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20, max_raises: None },
|
||||
small_blind: 10,
|
||||
big_blind: 20,
|
||||
ante: 0,
|
||||
|
|
|
|||
|
|
@ -601,7 +601,7 @@ mod tests {
|
|||
) -> GameInfo {
|
||||
GameInfo {
|
||||
num_seats: 2,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20, max_raises: None },
|
||||
small_blind: 10,
|
||||
big_blind: 20,
|
||||
ante: 0,
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ mod tests {
|
|||
fn make_game_info(current_bet: ChipCount, wagered_this_round: ChipCount) -> GameInfo {
|
||||
GameInfo {
|
||||
num_seats: 2,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10, max_raises: None },
|
||||
small_blind: 5,
|
||||
big_blind: 10,
|
||||
ante: 0,
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ mod tests {
|
|||
) -> GameInfo {
|
||||
GameInfo {
|
||||
num_seats: 2,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10, max_raises: None },
|
||||
small_blind: 5,
|
||||
big_blind: 10,
|
||||
ante: 0,
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ mod tests {
|
|||
) -> GameInfo {
|
||||
GameInfo {
|
||||
num_seats: 2,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10, max_raises: None },
|
||||
small_blind: 5,
|
||||
big_blind: 10,
|
||||
ante: 0,
|
||||
|
|
|
|||
|
|
@ -186,6 +186,9 @@ pub enum BetLimitConfig {
|
|||
NoLimit {
|
||||
/// Minimum raise increment.
|
||||
min_raise: ChipCount,
|
||||
/// Optional cap on voluntary raises per street (None = unlimited).
|
||||
#[serde(default)]
|
||||
max_raises: Option<usize>,
|
||||
},
|
||||
/// Pot-Limit — players may raise up to the current pot size.
|
||||
#[serde(rename = "pot_limit")]
|
||||
|
|
@ -206,7 +209,7 @@ pub enum BetLimitConfig {
|
|||
impl From<BetLimitConfig> for BetLimit {
|
||||
fn from(config: BetLimitConfig) -> Self {
|
||||
match config {
|
||||
BetLimitConfig::NoLimit { min_raise } => BetLimit::NoLimit { min_raise },
|
||||
BetLimitConfig::NoLimit { min_raise, max_raises } => BetLimit::NoLimit { min_raise, max_raises },
|
||||
BetLimitConfig::PotLimit { min_raise } => BetLimit::PotLimit { min_raise },
|
||||
BetLimitConfig::FixedLimit { small_bet, big_bet } => {
|
||||
BetLimit::FixedLimit { small_bet, big_bet }
|
||||
|
|
@ -218,7 +221,7 @@ impl From<BetLimitConfig> for BetLimit {
|
|||
impl From<BetLimit> for BetLimitConfig {
|
||||
fn from(limit: BetLimit) -> Self {
|
||||
match limit {
|
||||
BetLimit::NoLimit { min_raise } => BetLimitConfig::NoLimit { min_raise },
|
||||
BetLimit::NoLimit { min_raise, max_raises } => BetLimitConfig::NoLimit { min_raise, max_raises },
|
||||
BetLimit::PotLimit { min_raise } => BetLimitConfig::PotLimit { min_raise },
|
||||
BetLimit::FixedLimit { small_bet, big_bet } => {
|
||||
BetLimitConfig::FixedLimit { small_bet, big_bet }
|
||||
|
|
@ -411,6 +414,7 @@ impl Default for GameConfig {
|
|||
num_seats: default_num_seats(),
|
||||
bet_limit: BetLimitConfig::NoLimit {
|
||||
min_raise: 20,
|
||||
max_raises: None,
|
||||
},
|
||||
small_blind: default_small_blind(),
|
||||
big_blind: default_big_blind(),
|
||||
|
|
@ -874,7 +878,7 @@ big_bet = 20
|
|||
fn bet_limit_config_to_bet_limit() {
|
||||
let config = BetLimitConfig::NoLimit { min_raise: 20 };
|
||||
let limit: BetLimit = config.into();
|
||||
assert_eq!(limit, BetLimit::NoLimit { min_raise: 20 });
|
||||
assert_eq!(limit, BetLimit::NoLimit { min_raise: 20, max_raises: None });
|
||||
|
||||
let config = BetLimitConfig::FixedLimit {
|
||||
small_bet: 10,
|
||||
|
|
@ -1170,7 +1174,7 @@ min_raise = 50
|
|||
assert_eq!(table_config.small_blind, 10);
|
||||
assert_eq!(table_config.big_blind, 20);
|
||||
assert_eq!(table_config.ante, 5);
|
||||
assert_eq!(table_config.bet_limit, BetLimit::NoLimit { min_raise: 20 });
|
||||
assert_eq!(table_config.bet_limit, BetLimit::NoLimit { min_raise: 20, max_raises: None });
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -559,6 +559,17 @@ impl HandRunner {
|
|||
.unwrap_or(0);
|
||||
let street = self.current_street();
|
||||
|
||||
// Enforce raise cap for No-Limit with max_raises: convert Raise to Call.
|
||||
let action = if let Action::Raise { .. } = &action {
|
||||
if !self.bet_limit.can_raise(street, raises_this_round) {
|
||||
Action::Call
|
||||
} else {
|
||||
action
|
||||
}
|
||||
} else {
|
||||
action
|
||||
};
|
||||
|
||||
validate_action(
|
||||
&action,
|
||||
next_id,
|
||||
|
|
@ -1128,6 +1139,20 @@ impl HandRunner {
|
|||
}
|
||||
}
|
||||
|
||||
// 4b. Reveal all hole cards for RL training (no-op for production bots).
|
||||
{
|
||||
let all_cards: Vec<(PlayerId, HoleCards)> = self
|
||||
.seats
|
||||
.iter()
|
||||
.filter_map(|s| s.hole_cards.map(|hc| (s.player_id, hc)))
|
||||
.collect();
|
||||
let game_info = self.build_game_info();
|
||||
for seat in &mut self.seats {
|
||||
seat.player
|
||||
.cards_revealed_event(&all_cards, &game_info);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Set state to Complete.
|
||||
self.state = HandState::Complete;
|
||||
|
||||
|
|
@ -1643,7 +1668,7 @@ mod tests {
|
|||
|
||||
let seats = vec![seat0, seat1];
|
||||
let deck = Deck::new();
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
|
||||
let mut runner = HandRunner::new(seats, 0, bet_limit, deck, 1);
|
||||
assert_eq!(runner.state(), HandState::Idle);
|
||||
|
|
@ -1678,7 +1703,7 @@ mod tests {
|
|||
|
||||
let seats = vec![seat0, seat1];
|
||||
let deck = Deck::new();
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
|
||||
let mut runner = HandRunner::new(seats, 0, bet_limit, deck, 1);
|
||||
runner.start(10, 20, 0);
|
||||
|
|
@ -1714,7 +1739,7 @@ mod tests {
|
|||
|
||||
let seats = vec![seat0, seat1, seat2];
|
||||
let deck = Deck::new();
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
|
||||
let mut runner = HandRunner::new(seats, 0, bet_limit, deck, 1);
|
||||
runner.start(10, 20, 0);
|
||||
|
|
@ -1740,7 +1765,7 @@ mod tests {
|
|||
|
||||
let seats = vec![seat0, seat1];
|
||||
let deck = Deck::new();
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
|
||||
let mut runner = HandRunner::new(seats, 0, bet_limit, deck, 1);
|
||||
runner.start(10, 20, 0);
|
||||
|
|
@ -1762,7 +1787,7 @@ mod tests {
|
|||
|
||||
let seats = vec![seat0, seat1];
|
||||
let deck = Deck::new();
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
|
||||
let mut runner = HandRunner::new(seats, 0, bet_limit, deck, 1);
|
||||
assert_eq!(runner.state(), HandState::Idle);
|
||||
|
|
@ -1785,7 +1810,7 @@ mod tests {
|
|||
|
||||
let seats = vec![seat0, seat1];
|
||||
let deck = Deck::new();
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
|
||||
let mut runner = HandRunner::new(seats, 0, bet_limit, deck, 1);
|
||||
let result = runner.step();
|
||||
|
|
@ -1805,7 +1830,7 @@ mod tests {
|
|||
|
||||
let seats = vec![seat0, seat1];
|
||||
let deck = Deck::new();
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
|
||||
let mut runner = HandRunner::new(seats, 0, bet_limit, deck, 1);
|
||||
runner.start(10, 20, 0);
|
||||
|
|
@ -1841,7 +1866,7 @@ mod tests {
|
|||
|
||||
let seats = vec![seat0, seat1, seat2];
|
||||
let deck = Deck::new();
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
|
||||
let mut runner = HandRunner::new(seats, 0, bet_limit, deck, 1);
|
||||
runner.start(10, 20, 0);
|
||||
|
|
@ -1957,7 +1982,7 @@ mod tests {
|
|||
|
||||
let seats = vec![seat0, seat1, seat2];
|
||||
let deck = Deck::new();
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
|
||||
let mut runner = HandRunner::new(seats, 0, bet_limit, deck, 1);
|
||||
runner.start(10, 20, 0);
|
||||
|
|
@ -1983,7 +2008,7 @@ mod tests {
|
|||
|
||||
let seats = vec![seat0, seat1];
|
||||
let deck = Deck::new();
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10 };
|
||||
let bet_limit = BetLimit::NoLimit { min_raise: 10, max_raises: None };
|
||||
|
||||
let mut runner = HandRunner::new(seats, 0, bet_limit, deck, 1);
|
||||
runner.start(10, 20, 0);
|
||||
|
|
|
|||
|
|
@ -230,6 +230,24 @@ pub trait HoldemPlayer: Send + Sync {
|
|||
/// Corresponds to `com.biotools.meerkat.Player#gameOverEvent`.
|
||||
fn game_over_event(&mut self, game_info: &GameInfo);
|
||||
|
||||
/// Called after the hand ends with ALL players' hole cards revealed.
|
||||
///
|
||||
/// **Training only** — allows RL agents to compute realized equity for
|
||||
/// every decision point. The default implementation is a no-op; production
|
||||
/// bots should never override this (they don't see opponents' cards).
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `all_hole_cards` — Slice of `(PlayerId, HoleCards)` for every player
|
||||
/// who was dealt into this hand, including those who folded.
|
||||
/// * `game_info` — Final game state snapshot.
|
||||
fn cards_revealed_event(
|
||||
&mut self,
|
||||
_all_hole_cards: &[(PlayerId, HoleCards)],
|
||||
_game_info: &GameInfo,
|
||||
) {
|
||||
}
|
||||
|
||||
/// Signal an early-fold intent.
|
||||
///
|
||||
/// Called by the framework layer when a player wants to fold before it is
|
||||
|
|
|
|||
|
|
@ -129,8 +129,15 @@ pub fn run_cash_game(config: &GameConfig) -> Result<(SimulationStats, Table), Ga
|
|||
}
|
||||
}
|
||||
}
|
||||
Err(GameError::NotEnoughPlayers(_)) => {
|
||||
// Not enough active players to continue.
|
||||
Err(GameError::NotEnoughPlayers(count)) => {
|
||||
// Not enough active players to continue. This should only
|
||||
// happen if reset_bankroll_each_hand / auto_rebuy are both
|
||||
// disabled, or if seats were lost due to a hand error.
|
||||
log::warn!(
|
||||
"Simulation stopped after {} hands: only {count} active players. \
|
||||
Set reset_bankroll_each_hand=true or auto_rebuy=true to prevent this.",
|
||||
stats.total_hands
|
||||
);
|
||||
break;
|
||||
}
|
||||
Err(GameError::RaiseBelowMinimum(raise, min)) => {
|
||||
|
|
|
|||
|
|
@ -887,7 +887,7 @@ mod tests {
|
|||
fn record_tournament_result_processes_completed_tournament() {
|
||||
let config = TableConfig {
|
||||
num_seats: 9,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20, max_raises: None },
|
||||
small_blind: 10,
|
||||
big_blind: 20,
|
||||
ante: 0,
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ impl Default for TableConfig {
|
|||
fn default() -> Self {
|
||||
Self {
|
||||
num_seats: 9,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10, max_raises: None },
|
||||
small_blind: 10,
|
||||
big_blind: 20,
|
||||
ante: 0,
|
||||
|
|
@ -411,7 +411,36 @@ impl Table {
|
|||
.ok_or(GameError::NoHandInProgress)?;
|
||||
|
||||
// Run the hand to completion.
|
||||
let result = runner.run_to_completion()?;
|
||||
let result = match runner.run_to_completion() {
|
||||
Ok(result) => result,
|
||||
Err(e) => {
|
||||
// CRITICAL: Restore seats even on error. Without this, the
|
||||
// seats are trapped inside the dropped runner, leaving
|
||||
// self.seats empty. The next start_hand() would see 0 active
|
||||
// players, return NotEnoughPlayers, and silently terminate
|
||||
// the entire simulation.
|
||||
log::warn!("Hand execution failed ({e:?}) — restoring seats to table");
|
||||
let seats = runner.into_seats();
|
||||
for seat in seats {
|
||||
let idx = seat.index as usize;
|
||||
if idx < self.seats.len() {
|
||||
let mut seat = seat;
|
||||
// Refund wagered chips before resetting — the pot_manager
|
||||
// is dropped with the runner, so wagered chips would
|
||||
// vanish without this refund.
|
||||
seat.stack += seat.wagered_this_hand;
|
||||
if seat.stack == 0 {
|
||||
seat.state = PlayerState::SittingOut;
|
||||
} else {
|
||||
seat.reset_for_new_hand();
|
||||
}
|
||||
self.seats[idx] = Some(seat);
|
||||
}
|
||||
}
|
||||
self.current_hand = None;
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
||||
// Extract seats from the runner and restore them to the table.
|
||||
// HandRunner::into_seats() consumes the runner and returns the seats
|
||||
|
|
@ -829,7 +858,7 @@ mod tests {
|
|||
fn default_config() -> TableConfig {
|
||||
TableConfig {
|
||||
num_seats: 6,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10, max_raises: None },
|
||||
small_blind: 10,
|
||||
big_blind: 20,
|
||||
ante: 0,
|
||||
|
|
@ -1284,7 +1313,7 @@ mod tests {
|
|||
fn test_table_full() {
|
||||
let config = TableConfig {
|
||||
num_seats: 2,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 10, max_raises: None },
|
||||
small_blind: 10,
|
||||
big_blind: 20,
|
||||
ante: 0,
|
||||
|
|
|
|||
|
|
@ -1006,7 +1006,7 @@ mod tests {
|
|||
fn default_table_config() -> TableConfig {
|
||||
TableConfig {
|
||||
num_seats: 9,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20, max_raises: None },
|
||||
small_blind: 10,
|
||||
big_blind: 20,
|
||||
ante: 0,
|
||||
|
|
@ -1188,7 +1188,7 @@ mod tests {
|
|||
fn test_sng_registration_fills_table() {
|
||||
let config = TableConfig {
|
||||
num_seats: 4,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20, max_raises: None },
|
||||
small_blind: 10,
|
||||
big_blind: 20,
|
||||
ante: 0,
|
||||
|
|
@ -1217,7 +1217,7 @@ mod tests {
|
|||
fn test_sng_run_single_hand() {
|
||||
let config = TableConfig {
|
||||
num_seats: 4,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20, max_raises: None },
|
||||
small_blind: 10,
|
||||
big_blind: 20,
|
||||
ante: 0,
|
||||
|
|
@ -1283,7 +1283,7 @@ mod tests {
|
|||
fn test_mtt_table_balancing() {
|
||||
let config = TableConfig {
|
||||
num_seats: 9,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20, max_raises: None },
|
||||
small_blind: 10,
|
||||
big_blind: 20,
|
||||
ante: 0,
|
||||
|
|
@ -1328,7 +1328,7 @@ mod tests {
|
|||
fn test_blind_advancement() {
|
||||
let config = TableConfig {
|
||||
num_seats: 4,
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20 },
|
||||
bet_limit: BetLimit::NoLimit { min_raise: 20, max_raises: None },
|
||||
small_blind: 10,
|
||||
big_blind: 20,
|
||||
ante: 0,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue