feat(bot): POST /api/games instantiates CasualBrain + BotDriver

This commit is contained in:
claude (blind_chess)
2026-04-28 14:10:19 -04:00
parent 9a837ec319
commit 58e1fc5bd8
+20 -3
View File
@@ -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 };
});