From 9395e857db95481f6e2494d3a841632be0ff97c8 Mon Sep 17 00:00:00 2001 From: Aargh Rai Date: Sat, 18 Jul 2026 14:02:18 +0530 Subject: fixed moved gen & adding messages on asserts --- Plan.md | 100 ---------------------------------------------------------------- 1 file changed, 100 deletions(-) delete mode 100644 Plan.md (limited to 'Plan.md') diff --git a/Plan.md b/Plan.md deleted file mode 100644 index a300420..0000000 --- a/Plan.md +++ /dev/null @@ -1,100 +0,0 @@ -# Gacrux: Pseudo-Legal to Legal Move Conversion Plan - -## Current State -- Move generators produce **pseudo-legal** moves (follow piece movement rules but ignore checks/pins) -- `position_make_move()` has multiple bugs -- No attack detection or legal move filtering exists -- Perft test conditions are inverted - -## Phase 1: Fix Existing Bugs - -### `src/engine/moves.c` — `position_make_move()` -1. **Lines 94, 100**: Add missing semicolons after `assert(0)` -2. **Lines 54-55**: Black long castle modifies `WHITE_ROOK` → should be `BLACK_ROOK` -3. **Lines 71-73**: Black short castle modifies `WHITE_KING`/`WHITE_ROOK` → should be `BLACK_KING`/`BLACK_ROOK` -4. **Lines 96, 98**: `move.from` (u8) compared against `u64` bitboard constants → use square indices 63 and 56 -5. **Missing turn toggle**: `position->turn` never flips after a move - -### `test_perft_starting_position` -6. **Lines 169-176**: `==` → `!=` (test currently passes when counts are wrong) - -## Phase 2: Attack Detection - -Create `src/engine/moves/attack.c` with: -```c -bool square_attacked(position_t position, square_t square, u8 by_color); -``` - -Checks if any piece of `by_color` attacks `square`: -- **Pawn attacks**: Check diagonally forward for enemy pawns -- **Knight attacks**: Use existing `knight_moves[64]` lookup -- **King attacks**: Use existing `920078ULL` pattern -- **Sliding attacks**: Walk rays from target square (for now, ray-walking) - -## Phase 3: Legal Move Filtering - -Modify `get_moves()` (or add `get_legal_moves()`) to: -1. Generate all pseudo-legal moves -2. For each move, make it on a copy of the position -3. Find the friendly king in the resulting position -4. Check if the friendly king is attacked by the opponent -5. If attacked → remove the move (swap with last, decrement length) - -**Castling pre-checks** (in `king.c`): -- King not currently in check -- Squares king passes through are not attacked -- No pieces between king and rook - -## Phase 4: Magic Bitboards (Performance Optimization) - -Replace ray-walking with O(1) magic lookups for sliding piece attacks. - -### Data Structure -```c -typedef struct { - bitboard_t mask; // relevant occupancy bits (excludes edges) - bitboard_t *attacks; // pointer into attack table - bitboard_t magic; // the magic multiplier - int shift; // 64 - popcount(mask) -} magic_t; -``` - -### Attack Tables -- `rook_attacks[0x19000]` (~100KB) -- `bishop_attacks[0x1480]` (~5KB) - -### Index Computation -```c -unsigned index = ((occupied & magic.mask) * magic.magic) >> magic.shift; -return magic.attacks[index]; -``` - -### Initialization -At startup, for each square: -1. Compute mask (pseudo-attacks minus edges) -2. Enumerate all subsets of the mask -3. Compute true attacks via ray-walking (reference) -4. Find magic number via PRNG search - -### Usage -```c -// Move generation -bitboard_t attacks = get_rook_attacks(from_square, all_occupied); -attacks &= ~friendly_pieces; - -// Attack detection -bool square_attacked(...) { - if (get_rook_attacks(sq, occ) & (enemy_rooks | enemy_queens)) return true; - if (get_bishop_attacks(sq, occ) & (enemy_bishops | enemy_queens)) return true; - // ... -} -``` - -## Implementation Order -1. Fix bugs (Phase 1) -2. Add `square_attacked()` with ray-walking -3. Add legal move filtering -4. Fix castling legality -5. Verify perft d0-d7 -6. Uncomment + verify Kiwipete perft -7. Add magic bitboards (Phase 4) -- cgit v1.2.3