Skip to content

Commit 6eeec09

Browse files
authored
Merge pull request #94 from ImperialBower/epic-27
Epic 27 & 28 Features - src/bot/exploit.rs — ExploitConfig, scale_percentage, largest_active_opponent, adjust_profile with 8 deviation rules (fold-to-cbet, calling-station, loose-passive sizing, nit, aggro calldown, WTSD, 3-bet%) - src/bot/exploitative_decider.rs — ExploitativeDecider<D> wrapper with wrap / wrap_with_config constructors - src/bot/sim.rs — SimTable::new_with_registry constructor enabling any Box<dyn BotDecider> with full stats ingestion - src/bot/table_snapshot.rs — SeatInfo gains pub id: Uuid from player.id - src/analysis/player_stats.rs — StatsRegistry::insert_for_test helper (#[cfg(test)]) - src/bot/training/encoding.rs — ExploitConfig ↔ [f64; 16] encoding with per-dimension bounds - src/bot/training/evaluator.rs — evaluate / default_field / run_session for BB/100 fitness - src/bot/training/trainer.rs — ExploitTrainer (1+λ)-ES with Box-Muller Gaussian mutation and 1/5 success rule - src/bot/training/mod.rs — TrainingConfig, TrainingResult, GenerationRecord re-exports - src/prelude.rs — re-exports for ExploitConfig, ExploitativeDecider, training types under feature gates Config/Docs - Cargo.toml — bot-training feature gate; [[example]] and [[test]] entries for training - src/bot/mod.rs — registers exploit, exploitative_decider, training modules under feature gates - src/bot/exploit.rs — #[cfg_attr(feature = "bot-training", derive(Serialize, Deserialize))] on ExploitConfig - ROADMAP.md — EPIC-27 and EPIC-28 rows added to Epics table - docs/EPIC-27_Exploitative_Decider.md — full planning doc, all 14 status rows ✅ - docs/EPIC-28_Profile_Training.md — full planning doc, all status rows ✅ - docs/TUTORIAL_EPIC28_ES_Math.md — 473-line math tutorial (ES algorithm, 1/5 rule, Box-Muller, BB/100 noise, CMA-ES relation, references) - data/exploit_configs/tag_trained.yaml — 100-generation trained config artifact - data/exploit_configs/.gitkeep — directory placeholder Tests/Examples - examples/exploitative_play.rs — TAG-exploit vs LP/TP/Maniac, 1,000 hands, per-rule firing counters via Arc<TelemetryDecider> + SharedTelemetry newtype - examples/train_exploit_config.rs — end-to-end training demo with --generations, --hands, --output flags and YAML save - tests/exploitative_play_smoke.rs — 3 integration tests: chip conservation, stats accumulation, profile deviation firing - tests/training_integration.rs — smoke test (fast) + 200-generation validation test (#[ignore])
2 parents bbacf5f + 3f7b0e3 commit 6eeec09

23 files changed

Lines changed: 9024 additions & 1 deletion

Cargo.toml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "pkcore"
33
description = "Prototype core poker library."
4-
version = "0.0.55"
4+
version = "0.0.56"
55
rust-version = "1.94.1"
66
edition = "2024"
77
authors = ["electronicpanopticon <gaoler@electronicpanopticon.com>"]
@@ -44,6 +44,10 @@ player-stats = []
4444
## `YamlPlayerStatsStore` (one YAML file per player Uuid). Off by default; opt
4545
## in for multi-session experiments. EPIC-26 Phase 4.
4646
player-stats-persistence = ["player-stats", "dep:serde_yaml_bw"]
47+
## Enables `ExploitConfig` YAML serialisation and the `ExploitTrainer`
48+
## gradient-free optimisation loop (EPIC-28). Requires player-stats and
49+
## bot-profiles; adds no external optimiser dependency.
50+
bot-training = ["player-stats", "bot-profiles", "dep:serde_yaml_bw"]
4751

4852
[dependencies]
4953
bint = "0.1.15"
@@ -106,6 +110,14 @@ required-features = ["bot-profiles", "hand-histories", "player-stats"]
106110
name = "player_stats_session"
107111
required-features = ["bot-profiles", "hand-histories", "player-stats-persistence"]
108112

113+
[[example]]
114+
name = "exploitative_play"
115+
required-features = ["bot-profiles", "player-stats"]
116+
117+
[[example]]
118+
name = "train_exploit_config"
119+
required-features = ["bot-training"]
120+
109121
[[test]]
110122
name = "replay_consistency"
111123
required-features = ["hand-histories", "bot-profiles"]
@@ -130,6 +142,14 @@ required-features = ["bot-profiles", "hand-histories", "player-stats"]
130142
name = "player_stats_persistence"
131143
required-features = ["bot-profiles", "hand-histories", "player-stats-persistence"]
132144

145+
[[test]]
146+
name = "exploitative_play_smoke"
147+
required-features = ["bot-profiles", "player-stats"]
148+
149+
[[test]]
150+
name = "training_integration"
151+
required-features = ["bot-training"]
152+
133153
[dev-dependencies]
134154
serde_yaml_bw = "2.5"
135155
clap = { version = "4.6", features = ["derive", "unicode"] }

ROADMAP.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ workspace)
122122
| [EPIC-24](docs/EPIC-24_Demo.md) | *(pkdealer)* Demo Packaging — Docker Compose, `demo.sh`, Grafana dashboards, Langfuse | Planned |
123123
| [EPIC-25](docs/EPIC-25_Range_Frequencies.md) | Range Frequencies — optional per-combo frequency in range strings (`AA:0.5`) | Complete |
124124
| [EPIC-26](docs/EPIC-26_Player_Stats.md) | Player Action Tracking & Opponent Insights — `PlayerStats` / `StatsRegistry` keyed by `Uuid`, derived ratios (VPIP/PFR/AF/WTSD/c-bet/...), exposed to `BotDecider` (no behavior change), optional persistence | Complete |
125+
| [EPIC-27](docs/EPIC-27_Exploitative_Decider.md) | Adaptive Bot Framework — `ExploitativeDecider<D>` wrapper that converts opponent stats into runtime profile deviations; `ExploitConfig` with 8 deviation rules; `SimTable::new_with_registry`; demo + smoke tests | Complete |
126+
| [EPIC-28](docs/EPIC-28_Profile_Training.md) | Cross-Session Profile Training — `ExploitTrainer` (1+λ)-ES loop tunes `ExploitConfig` parameters against a static field; `bot-training` feature; YAML serialisation for trained configs; `train_exploit_config` example | Complete |
125127
| [FEATURE: Activate Bluff Fields](docs/FEATURE_BotProfile_ActivateBluffFields.md) | Wire `bluff_frequency`, `check_raise_frequency`, `postflop_cbet_frequency` into `RuleBasedDecider` | Complete |
126128
| [FEATURE: Position-Aware Decisions](docs/FEATURE_BotProfile_PositionAwareDecisions.md) | Route decisions through `Playbook` position-specific `BettingStrategy` | Complete |
127129
| [FEATURE: BotProfile Type Safety](docs/FEATURE_BotProfile_TypeSafety.md) | `PlayStyle` enum, `Percentage` newtype for frequency fields | Complete |

data/exploit_configs/.gitkeep

Whitespace-only changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
fold_to_cbet_high_threshold: 0.9
2+
fold_to_cbet_low_threshold: 0.1
3+
vpip_calling_station_threshold: 0.2574863530412368
4+
pfr_passive_threshold: 0.05
5+
pfr_nit_threshold: 0.03936617611404843
6+
aggression_factor_threshold: 3.3029093837419525
7+
wtsd_threshold: 0.2596708701629848
8+
three_bet_pct_threshold: 0.16746165417662037
9+
fold_to_cbet_high_multiplier: 1.3863876192682127
10+
fold_to_cbet_low_multiplier: 0.6966971553848362
11+
bluff_vs_station_multiplier: 0.9050397746362656
12+
bluff_vs_wtsd_multiplier: 0.4730447853992028
13+
aggression_vs_nit_multiplier: 0.9001258220183663
14+
aggression_vs_three_bettor_multiplier: 1.0
15+
min_hands_light: 5
16+
min_hands_heavy: 10

0 commit comments

Comments
 (0)