id: 2a5941626f99461db32313a339981ac4
parent_id: 
item_type: 1
item_id: 3bd32147b8e0490f98ebb0e6cb400c2b
item_updated_time: 1781461617523
title_diff: "[{\"diffs\":[[1,\"Gen 3 Pre-Sweep Analysis — Strategy, Structure, Tests, Performance, Multi-Way\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":77}]"
body_diff: "[{\"diffs\":[[1,\"# Gen 3 Pre-Sweep Comprehensive Analysis\\\n\\\n## 1. Strategy Issues\\\n\\\n### 1a. Threshold Scale Mismatch (PARTIALLY ADDRESSED)\\\nAll thresholds calibrated for full-deck hs (0.3–0.9 scale) but Gen 3 uses range-weighted hs (0.2–0.6 scale).\\\n\\\n**Status:** The OR-chain refactoring to weighted scoring (round 2) partially addresses this — `should_call`/`should_raise` now use dynamic threshold adjustments rather than fixed thresholds. However, the base thresholds (`call_base=0.75`, `raise_base=0.93`) are still calibrated for full-deck hs and may need downward adjustment. The round 2 sweep tests `call_base` at 0.60/0.75/0.85 and `raise_base` at 0.86/0.93/0.97.\\\n\\\n### 1b. Non-deterministic RNG ✅ FIXED\\\nCheck-raise and rope-a-dope now use `decision_rng()` — deterministic `StdRng` seeded from `mc_seed + win_prob.to_bits() + pot_size + num_active`. The `sweep_mode` config flag (default `true`) controls this: `true` = fully deterministic for sweeps, `false` = mixes in system entropy for live play.\\\n\\\n### 1c. Raise OR-chain has too many bypass paths ✅ FIXED\\\nReplaced with `should_raise()` weighted decision. Base threshold from `raise_base` is dynamically lowered by draw quality (`raise_w_draw`) and bluff equity (`raise_w_bluff`). Made hands can now raise (previously only draws raised through the ppot bypass).\\\n\\\n### 1d. No board texture awareness\\\nStill open. No connected/monotone/paired board detection. Only crude npot threshold for \\\"dangerous board.\\\"\\\n\\\n### 1e. Missing Java tactics\\\nStill open. backAlleyMug, luringBet, fakeSemiBluff, scareCardHit not ported.\\\n\\\n## 2. Structure\\\n- Clean module separation (range, model, potential, strategy)\\\n- ~30 private threshold methods\\\n- Gen3Config now has 29 sweepable parameters (was 3)\\\n- `apply_model_modifier` extracted (was inline `/mm` bug at bet site, now `*mm` everywhere)\\\n\\\n## 3. Test Coverage\\\n| Component | Tests |\\\n|-----------|-------|\\\n| hand_range.rs | 14 |\\\n| player_model.rs | 6 |\\\n| hand_potential.rs (range) | 24 |\\\n| rollout_postflop_gen3.rs | 13 |\\\n| **Total** | **340** |\\\n\\\n## 4. Performance\\\n\\\n### Current single-opponent (flop)\\\nExhaustive enumeration with trie. ~5ms/action.\\\n\\\n### Monte Carlo multi-way (implemented, optimized)\\\nUses sparse precomputed pair lists (`nonzero_pairs_by_cards` + `sample_sparse`) and presence mask (`present[]`) instead of per-sample card removal.\\\n\\\n| Opponents | M=20K | M=100K |\\\n|-----------|-------|--------|\\\n| 1 | 0.3ms (exhaustive used instead) | — |\\\n| 5 | ~1.5ms | ~15ms |\\\n| 9 | ~2.5ms | ~25ms |\\\n\\\n### Optimizations Applied (round 2)\\\n- `sample_sparse`: iterates precomputed sparse pair list O(k) instead of O(n²) per sample\\\n- `nonzero_pairs_by_cards`: precomputed once per equity computation, shared across all MC samples\\\n- `present[]` mask: O(1) card removal vs old O(n) swap_remove\\\n- `select_nth_unstable_by`: O(n) partial sort replaces O(n log n) full sort in `init_strong_hands`\\\n- `is_oesd`: fixed `[u8; 6]` stack array replaces heap `Vec` allocation\\\n- `compute_vs_range_multiway_shared`: avoids cloning 2704-entry HandRange once per opponent\\\n- `PotentialResult::fallback()`: shared fallback instead of duplicated struct literals\\\n- `board_completion_count`: extracted `const fn` (was triplicated match block)\\\n\\\n## 5. Parameter Defaults Analysis\\\n\\\n### strong_hands_fraction = 0.20\\\nDefensible as population average. Range weighting via MC importance sampling.\\\n\\\n### bluff_factor = 2.0\\\nSound. Near-balanced for pot-sized bet.\\\n\\\n### draw_call_ppot_thresh = 0.22\\\nAppropriate. Sweep tests 0.15/0.22/0.32.\\\n\\\n### New weighted-decision defaults\\\n| Parameter | Default | Role |\\\n|-----------|---------|------|\\\n| `call_w_draw` | 0.8 | How much strong draws lower call threshold |\\\n| `call_w_pot_odds` | 0.5 | How much favorable pot odds lower call threshold |\\\n| `call_w_commitment` | 0.3 | How much stack commitment lowers call threshold |\\\n| `raise_w_draw` | 0.5 | How much strong draws lower raise threshold |\\\n| `raise_w_bluff` | 0.3 | How much bluff equity lowers raise threshold |\\\n| `range_draw_weight` | 1.0 | Draw weight in opponent range (1.0 = equal to made hands) |\\\n\\\n## 6. Range Estimation from Opponent Actions\\\n\\\n**Infrastructure exists** but **not yet implemented**:\\\n- HandRange supports `weighted_union`, `nonzero_pairs_by_cards`\\\n- StrategyContext has action recorder\\\n- Currently uses static range (same for all opponents)\\\n\\\n**Next:** RangePredictor — per-seat HandRange[], lazily initialized from action patterns.\\\n\\\n## 7. Multi-Way Rollout — Implemented\\\n\\\n- **Exhaustive (HU only):** `compute_vs_range` — exact, trie-optimized\\\n- **Monte Carlo (multi-way):** `compute_vs_range_multiway_shared` — range-weighted importance sampling\\\n- Range weighting = importance weights (zero extra cost)\\\n- ppot/npot extend naturally: classify vs strongest opponent at each point\\\n\\\n## 8. Gen 2 Multi-Way Applicability\\\nGen 2 still uses exhaustive `hp.compute()` (uniform opponent hands, no range). Could benefit from MC for multi-way pots. Not yet migrated.\\\n\\\n## Round 2 Sweep Status (2026-06-14)\\\n- 16 params × 3 values × 4 seeds = 192 runs\\\n- ~82s per run, ~4.5h total\\\n- Early results: most parameters show small but non-zero sensitivity\\\n- `call_w_pot_odds` at 0.75 shows strongest positive swing\\\n- Gen3 currently underperforms Gen2 in 5v5 10-seat format — may need table composition adjustment\\\n\\\n## Recommended Priority (updated)\\\n1. ✅ ~~Add strategy tests~~ — 13 tests added\\\n2. ✅ ~~Parameter sweep~~ — round 2 running\\\n3. ✅ ~~Monte Carlo equity engine~~ — implemented + optimized\\\n4. RangePredictor (per-opponent range tracking)\\\n5. Board texture awareness\\\n6. Port missing tactics\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":5518}]"
metadata_diff: {"new":{"id":"3bd32147b8e0490f98ebb0e6cb400c2b","parent_id":"1246bbc3bb4948fc8329079b84b4ae3d","latitude":"0.00000000","longitude":"0.00000000","altitude":"0.0000","author":"","source_url":"","is_todo":0,"todo_due":0,"todo_completed":0,"source":"joplin-desktop","source_application":"net.cozic.joplin-desktop","application_data":"","order":1781285871732,"markup_language":1,"is_shared":0,"share_id":"","conflict_original_id":"","master_key_id":"","user_data":"","deleted_time":0},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-06-14T18:36:51.078Z
created_time: 2026-06-14T18:36:51.078Z
type_: 13