Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 13 additions & 17 deletions FOG_OF_WAR_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,16 +258,14 @@ go infinite
```

In a fog FEN:
- `?` represents unknown/fogged squares
- `?` (or `*`) represents unknown/fogged squares
- Visible pieces are shown normally (e.g., `p`, `P`, `N`, etc.)
- Empty visible squares are shown as part of the rank count (e.g., `8`, `1`)

The engine will:
1. Parse and store the fog FEN
2. Use it to initialize the belief state (set of possible positions consistent with observations)
3. Search over the belief state to find the best move

**Note**: The fog_fen feature is currently a basic implementation. The engine stores the fog FEN and reports it, but full integration with belief state enumeration requires additional development.
2. Enumerate positions consistent with what the fog FEN shows (permuting hidden opponent pieces across unseen squares)
3. Use that belief state to guide the Obscuro search before selecting a move

## Viewing the Fog-of-War Board State

Expand Down Expand Up @@ -344,14 +342,12 @@ The current implementation includes:
- ✅ FoW visibility computation (Appendix A rules)
- ✅ UCI integration and options
- ✅ Multi-threaded search (1 CFR solver + 2 expanders)
- ✅ Basic fog_fen parsing and storage
- ✅ fog_fen parsing wired into belief state enumeration
- ✅ Belief state management (enumerates hidden opponent permutations up to 1024 states per observation)
- ✅ NNUE evaluation for all FoW variants
- ⚠️ Belief state management (simplified - stores true position only)
- ⚠️ Action purification (placeholder implementation)
- ⚠️ fog_fen integration with belief state (parses but doesn't enumerate)
- 🔲 Full belief enumeration (enumerate positions consistent with observation)
- 🔲 Full KLUSS order-2 neighborhood computation
- 🔲 Complete gadget implementation (Resolve/Maxmargin)
- ⚠️ KLUSS order-2 neighborhood is still simplified
- ⚠️ Resolve/Maxmargin gadget details are incomplete
- 🔲 Instrumentation (Appendix B.4 metrics)


Expand All @@ -369,16 +365,16 @@ The current implementation includes:

**What Doesn't Work Yet**:

1. **Belief enumeration**: The engine doesn't enumerate possible positions consistent with what you see. It only uses the true position, meaning it plays as if it has perfect information about hidden pieces.
2. **fog_fen analysis**: While you can specify a partial observation with `position fog_fen`, the engine doesn't use it to build a proper belief state. It starts from the variant's starting position.
1. **Belief diversity limits**: Enumeration permutes hidden opponent pieces from the current position and caps at 1024 states; it does not yet model captures beyond the observed piece set or piece-in-hand drops for crazyhouse variants.

2. **KLUSS neighborhood**: The KLUSS computation is still a placeholder and does not freeze/unfreeze infosets per the paper's order-2 definition.

3. **True imperfect information play**: Without belief enumeration, the engine essentially plays perfect information chess with FoW move restrictions, rather than reasoning about what might be hidden.
3. **Purification and gadgets**: Action purification and Resolve/Maxmargin gadget details remain simplified, so play quality may vary in tricky information sets.

### Practical Usage

**Current best use case**: Using the standard FoW search to explore how the engine handles the FoW visibility rules and move generation. The search infrastructure is in place for future belief state enumeration.
**Current best use case**: Using `position fog_fen` to explore imperfect-information situations where hidden opponent pieces could be on multiple unseen squares. The engine will enumerate those possibilities and search them, but higher-level gadgets and purification are still simplified.

**Not yet suitable for**: Analyzing positions where you want the engine to reason about hidden pieces based on partial observations.
**Not yet suitable for**: Positions that rely on advanced KLUSS freezing/unfreezing logic or deep purification requirements (e.g., adversarial bluffing scenarios and crazyhouse drop speculation).

For development status and technical details, see `OBSCURO_FOW_IMPLEMENTATION.md`.
119 changes: 15 additions & 104 deletions OBSCURO_FOW_IMPLEMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This implementation follows the Obscuro paper's algorithms for imperfect-informa
- Maintains set P of consistent positions
- Observation history tracking
- From-scratch enumeration (Figure 9, lines 2-4)
- Enumerates hidden opponent piece permutations consistent with `fog_fen` observations (capped at 1024 states)

- [x] **Evaluator Hook** (`src/imperfect/Evaluator.{h,cpp}`)
- MultiPV depth-1 evaluation for all children
Expand Down Expand Up @@ -150,107 +151,17 @@ This section provides a detailed analysis of what remains to be implemented to a



#### 1. Full Belief State Enumeration (HIGH PRIORITY)
#### Addressed Critical Gaps



**Current State**: The belief state module (`Belief.cpp`) stores only the true position FEN. The `sample_states()` method returns a single-element vector containing just the current position.



**What's Needed**:

- **Observation-consistent enumeration**: Given an observation (what the player sees), enumerate ALL positions that could produce that observation

- **Efficient representation**: Use bitboards or piece placement constraints to represent the set of unknown piece locations

- **Incremental updates**: When a new observation arrives, filter existing belief states rather than re-enumerating from scratch



**Algorithm** (from Figure 9, lines 2-4):

```

P ← EnumerateConsistentPositions(observation_history)

I ← SampleSubset(P, MinInfosetSize) // Sample 256 positions

```



**Implementation Tasks**:

1. Implement `enumerate_consistent_positions()` that:

- Parses fog_fen to identify unknown squares ('?')

- Computes all possible piece placements on unknown squares

- Filters positions that would produce the observed fog_fen

- Respects piece count constraints (e.g., max 8 pawns per side)



2. Implement efficient sampling:

- Random sampling from large belief sets

- Stratified sampling to ensure diversity

- Weighted sampling based on position likelihood



**Complexity**: High - this is the most algorithmically complex missing piece



#### 2. fog_fen Integration with Belief State (HIGH PRIORITY)



**Current State**: `position fog_fen <fen>` parses and stores the fog_fen string, but it's not used by the belief state module.



**What's Needed**:

```cpp

// In Planner::construct_subgame():

if (!get_fog_fen().empty()) {

// Parse fog_fen to create observation

Observation obs = parse_fog_fen(get_fog_fen());

// Enumerate positions consistent with this observation

beliefState.enumerate_from_fog_fen(obs);

}

```



**Implementation Tasks**:

1. Create `parse_fog_fen()` function that converts fog_fen string to Observation struct

2. Implement `BeliefState::enumerate_from_fog_fen()`
The latest update implements the two previously missing foundation pieces:

3. Connect fog_fen to belief state in Planner
- **Full belief state enumeration**: `BeliefState::enumerate_candidates()` now permutes hidden opponent pieces across unseen squares (masked by visibility) and keeps every state consistent with the latest observation. Enumeration is capped at 1024 states to prevent combinatorial blowups, and illegal or king-capturable positions are filtered out before sampling.

4. Handle piece-in-hand visibility for crazyhouse variants
- **fog_fen integration**: `BeliefState::parse_fog_fen()` converts partial FoW FEN strings (supports `*` or `?` for unknown squares) into observations, and `Planner::construct_subgame()` seeds the belief state directly from a supplied `fog_fen` before running the solver.



#### 3. Proper KLUSS Order-2 Neighborhood (MEDIUM PRIORITY)
#### 1. Proper KLUSS Order-2 Neighborhood (MEDIUM PRIORITY)



Expand Down Expand Up @@ -296,7 +207,7 @@ For each state s in belief_state:



#### 4. Thread Synchronization Improvements (MEDIUM PRIORITY)
#### 2. Thread Synchronization Improvements (MEDIUM PRIORITY)



Expand Down Expand Up @@ -350,7 +261,7 @@ For each state s in belief_state:



#### 5. Action Purification (MEDIUM PRIORITY)
#### 3. Action Purification (MEDIUM PRIORITY)



Expand Down Expand Up @@ -396,7 +307,7 @@ renormalize(purified)



#### 6. Gadget Implementation (MEDIUM PRIORITY)
#### 4. Gadget Implementation (MEDIUM PRIORITY)



Expand Down Expand Up @@ -440,7 +351,7 @@ renormalize(purified)



#### 7. Leaf Evaluation Integration (MEDIUM PRIORITY)
#### 5. Leaf Evaluation Integration (MEDIUM PRIORITY)



Expand Down Expand Up @@ -476,7 +387,7 @@ renormalize(purified)



#### 8. Instrumentation (Appendix B.4) (LOW PRIORITY)
#### 6. Instrumentation (Appendix B.4) (LOW PRIORITY)



Expand All @@ -492,7 +403,7 @@ renormalize(purified)



#### 9. Memory Management (LOW PRIORITY)
#### 7. Memory Management (LOW PRIORITY)



Expand All @@ -508,7 +419,7 @@ renormalize(purified)



#### 10. Incremental Belief Updates (LOW PRIORITY)
#### 8. Incremental Belief Updates (LOW PRIORITY)



Expand Down Expand Up @@ -568,9 +479,9 @@ renormalize(purified)

**Phase 1: Core Functionality** (Essential for correct play)

1. Full belief state enumeration
1. Full belief state enumeration (hidden-piece permutations, capped at 1024)

2. fog_fen integration
2. fog_fen integration (parse + seed belief state)

3. Action purification

Expand Down
Loading
Loading