From 58e1fc5bd8328bd291bd31a7a3cfa62b7fda8d83 Mon Sep 17 00:00:00 2001 From: "claude (blind_chess)" Date: Tue, 28 Apr 2026 14:10:19 -0400 Subject: [PATCH] feat(bot): POST /api/games instantiates CasualBrain + BotDriver --- packages/server/src/server.ts | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/server/src/server.ts b/packages/server/src/server.ts index 6360878..f3f8918 100644 --- a/packages/server/src/server.ts +++ b/packages/server/src/server.ts @@ -8,9 +8,11 @@ import { chooseSide, createGame, pruneFinished, + attachBotDriver, } from './games.js'; import { attachSocket } from './ws.js'; import { createGameSchema } from './validation.js'; +import { CasualBrain, BotDriver } from './bot/index.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -45,13 +47,28 @@ fastify.post('/api/games', async (req, reply) => { reply.code(400); return { error: 'malformed', detail: parsed.error.issues }; } - const { mode, side, highlightingEnabled } = parsed.data; + const { mode, side, highlightingEnabled, vsAi } = parsed.data; + + // Phase 1: only 'casual' is implemented. 'recon' returns 503. + if (vsAi && vsAi.brain === 'recon') { + reply.code(503); + return { error: 'ai_offline', detail: 'recon bot not yet implemented' }; + } + const creatorSide = chooseSide(side); - const { game, creatorToken } = createGame({ mode, creatorSide, highlightingEnabled }); + const { game, creatorToken } = createGame({ mode, creatorSide, highlightingEnabled, vsAi }); + + // For AI games, wire the bot. + if (vsAi && game.aiOpponent) { + const brain = new CasualBrain({}); + const driver = new BotDriver({ game, brain, color: game.aiOpponent.color }); + await driver.init(); + attachBotDriver(game.id, driver); + } const publicBase = PUBLIC_BASE || (req.headers.host ? `${req.protocol}://${req.headers.host}` : ''); - const joinUrl = `${publicBase}/g/${game.id}`; + const joinUrl = vsAi ? null : `${publicBase}/g/${game.id}`; return { gameId: game.id, creatorToken, creatorColor: creatorSide, joinUrl }; });