use std::collections::{HashMap, HashSet};
use std::convert::TryInto;
-use std::time::SystemTime;
+use std::time::{Duration, SystemTime};
use itertools::Itertools;
max_players: u32,
small_blind: u64,
starting_stack: u64,
+ action_timeout_secs: Option<u64>,
}
#[derive(Clone, Debug)]
settings: TexasHoldEmSettings,
rng: WaveRng,
actions_len: usize,
+ last_action_time: Option<SystemTime>,
state: State,
seats: Seats,
stacks: HashMap<Username, u64>,
settings,
rng: seed.into_rng(),
actions_len: 0,
+ last_action_time: None,
state: State::NotStarted,
seats: Seats::new(),
stacks: HashMap::new(),
}
}
- fn take_action(&mut self, ValidatedUserAction(UserAction{username, action, ..}): ValidatedUserAction) -> Result<(), ActionError> {
+ fn take_action(&mut self, ValidatedUserAction(UserAction{timestamp, username, action}): ValidatedUserAction) -> Result<(), ActionError> {
self.actions_len += 1;
+ self.last_action_time = Some(timestamp);
self.rng.advance();
match (self.state, action) {
(_, Action::PlayCard{..}) | (_, Action::ChooseTrumps{..}) => {
ValidatedUserAction(UserAction{timestamp, username, action: Action::EndDeal})
)
} else {
- DealerAction::WaitForPlayer
+ error!("Expected to deal a card but there was no dealer: {:#?}", self);
+ DealerAction::Leave
}
}
State::PostingSmallBlind if self.seats.players_len() == 2 => {
)
} else {
error!("There is no player to post the small blind: {:#?}", self);
- DealerAction::WaitForPlayer
+ DealerAction::Leave
}
}
State::PostingBigBlind if self.seats.players_len() == 2 => {
)
} else {
error!("There is no player to post the big blind: {:#?}", self);
- DealerAction::WaitForPlayer
+ DealerAction::Leave
}
}
State::PostingBigBlind => {
)
} else {
error!("There is no player to post the big blind: {:#?}", self);
- DealerAction::WaitForPlayer
+ DealerAction::Leave
}
}
State::PreFlopBetting | State::PostFlopBetting | State::TurnBetting | State::RiverBetting => {
error!("Logic error: no dealer could be chosen: {:#?}", self);
DealerAction::Leave
}
+ } else if let (Some(last_time), Some(username), Some(timeout)) = (self.last_action_time, self.active, self.settings.action_timeout_secs) {
+ let timeout_time = last_time + Duration::from_secs(timeout);
+ if timestamp >= timeout_time {
+ DealerAction::TakeAction(
+ ValidatedUserAction(UserAction{timestamp, username, action: Action::Fold})
+ )
+ } else {
+ DealerAction::WaitUntil(timeout_time)
+ }
} else {
DealerAction::WaitForPlayer
}
]"#;
let actions = serde_json::from_str(actions).unwrap();
- let settings = r#"{"title":"2-Player TexasHoldEm Test","max_players":2,"small_blind":100,"starting_stack":1000}"#;
+ let settings = r#"{"title":"2-Player TexasHoldEm Test","max_players":2,"small_blind":100,"starting_stack":1000,"action_timeout_secs":null}"#;
let settings = serde_json::from_str(settings).unwrap();
let seed = r#"{"rng":"ChaCha20","seed":"e0355d5c6c63ef757d1b874b0392a3deec73cadfb0a2aa7947a04db651bf9269"}"#;
]"#;
let actions = serde_json::from_str(actions).unwrap();
- let settings = r#"{"title":"2-Player TexasHoldEm Test","max_players":2,"small_blind":25,"starting_stack":1000}"#;
+ let settings = r#"{"title":"2-Player TexasHoldEm Test","max_players":2,"small_blind":25,"starting_stack":1000,"action_timeout_secs":null}"#;
let settings = serde_json::from_str(settings).unwrap();
let seed = r#"{"rng":"ChaCha20","seed":"f05dc83bdce966e72a3a81b19ccded2e70387eb68deacf60ed8de1ee78b9ff0e"}"#;
]"#;
let actions = serde_json::from_str(actions).unwrap();
- let settings = r#"{"title":"2-Player TexasHoldEm Test","max_players":2,"small_blind":100,"starting_stack":1000}"#;
+ let settings = r#"{"title":"2-Player TexasHoldEm Test","max_players":2,"small_blind":100,"starting_stack":1000,"action_timeout_secs":null}"#;
let settings = serde_json::from_str(settings).unwrap();
let seed = r#"{"rng":"ChaCha20","seed":"fd87ec4b51fcaf056ef53c0460322e1fa5261cf2801d005065c9add8ec541bb4"}"#;