feat(bot): vanilla CasualBrain delegates to js-chess-engine
The hand-rolled scoring heuristic lost to a random-move baseline 7-7 in
self-play — far below the spec's >=80% acceptance bar. Swap in a real
chess engine (js-chess-engine, MIT, ~400KB, no native deps) for vanilla
mode at level 2 with randomness=30 to break threefold cycles.
- BrainInput.fen added; driver populates it ONLY in vanilla mode.
Blind mode omits the FEN so the engine path can't smuggle opponent
positions past the view filter.
- CasualBrain in vanilla: convert FEN -> EngineGame -> ai({level: 2});
validate the engine's move is in legalCandidates; fall back to
heuristic on miss.
- Blind mode unchanged (engine isn't useful when only own pieces are
visible — that's Phase 2 Recon's territory).
Self-play vs RandomBrain (100 games each direction, vanilla):
- Casual(W) vs Random(B): W=97%
- Random(W) vs Casual(B): B=96%
Casual-vs-Casual vanilla balanced, ~5-30ms/move. All 54 tests still pass.
Refresh .secrets.baseline (stale) to allow new pnpm-lock.yaml hashes.
This commit is contained in:
@@ -115,6 +115,10 @@ export class BotDriver {
|
||||
attemptHistory,
|
||||
drawOfferFromOpponent: !!(this.game.drawOffer && this.game.drawOffer.from !== this.color),
|
||||
ply: this.game.chess.history().length,
|
||||
// Vanilla mode: full reveal, FEN exposes nothing the brain can't already
|
||||
// see. Blind mode: omit FEN so the engine path can't smuggle opponent
|
||||
// positions past the view filter.
|
||||
fen: this.game.mode === 'vanilla' ? this.game.chess.fen() : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user