Skip to content

Commit c5a6bf4

Browse files
feat(preflop-charts): scenario-scoped charts, TUI viewer, and verify command
Rework the preflop chart system around (position, scenario) — each `PositionCharts` holds one `PreflopChart` per scenario (rfi/vs_open/ vs_3bet/vs_4bet), replacing the labeled Raise/ThreeBet/FourBet scheme that tried to pack every scenario into one strategy. `PreflopStrategy` collapses to `{raise, call}` with fold implicit; both fields are optional in JSON so the common `{"raise": 1.0}` case is terse. A new `four_bet_plus_multiplier` (default 2.5) sizes 4-bet raises in Vs3Bet. Adds `rsp arena charts` (interactive TUI hand-grid viewer with auto-switching to a non-empty scenario when seats change) and `rsp arena verify` with `--summary` for combo-weighted range stats per position/scenario. The in-tree example config is rewritten in the new format; a one-shot migration script for local configs lives outside the tree.
1 parent f9e6276 commit c5a6bf4

16 files changed

Lines changed: 3607 additions & 3821 deletions

File tree

examples/configs/preflop_6max_rfi.json

Lines changed: 918 additions & 2873 deletions
Large diffs are not rendered by default.

src/arena/agent/config.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ pub enum AgentConfig {
274274
///
275275
/// Can be either a preset name (e.g., "6max_gto", "tight", "loose")
276276
/// or an inline chart configuration.
277-
#[derive(Debug, Clone, Serialize, Deserialize)]
277+
#[derive(Debug, Clone, Serialize)]
278278
#[serde(untagged)]
279279
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
280280
pub enum PreflopChartConfigOption {
@@ -284,6 +284,26 @@ pub enum PreflopChartConfigOption {
284284
Inline(PreflopChartConfig),
285285
}
286286

287+
// Custom Deserialize so failures on the inline path surface the *specific*
288+
// PreflopChartConfig parse error (e.g. "missing field `charts`", "unknown
289+
// field `position`") instead of serde's generic "data did not match any
290+
// variant of untagged enum" message, which is useless when debugging a
291+
// malformed config.
292+
impl<'de> Deserialize<'de> for PreflopChartConfigOption {
293+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
294+
where
295+
D: serde::Deserializer<'de>,
296+
{
297+
let value = serde_json::Value::deserialize(deserializer)?;
298+
if let serde_json::Value::String(s) = &value {
299+
return Ok(PreflopChartConfigOption::Preset(s.clone()));
300+
}
301+
serde_json::from_value::<PreflopChartConfig>(value)
302+
.map(PreflopChartConfigOption::Inline)
303+
.map_err(serde::de::Error::custom)
304+
}
305+
}
306+
287307
impl Default for PreflopChartConfigOption {
288308
fn default() -> Self {
289309
PreflopChartConfigOption::Preset("6max_gto".to_string())

src/arena/cfr/action_generator/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub use configurable::{
1515
RoundActionConfig,
1616
};
1717
pub use preflop_chart::{
18-
PreflopChartActionConfig, PreflopChartActionGenerator, PreflopChartConfig,
18+
PositionCharts, PreflopChartActionConfig, PreflopChartActionGenerator, PreflopChartConfig,
1919
PreflopChartConfigError,
2020
};
2121
pub use simple::SimpleActionGenerator;

0 commit comments

Comments
 (0)