feat(bots): add named bot profiles with ELO-based difficulty

- 5 bot profiles (Holzpferd Heinz to Meister Magnus, ELO 200-1400) in
  server/bots.ts and client/bots.ts with emoji + descriptions
- Bot users auto-created in DB on server startup (role='bot')
- AI page replaced difficulty buttons with bot profile cards
- Tournament host can add bots via dropdown (POST /:code/add-bot)
- Bot auto-moves triggered on joinLobby and after each human move
- Fixed clock start order so bot-as-white games initialize correctly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Michess
2026-04-14 13:32:43 +02:00
parent b29c467766
commit 157c14c11e
9 changed files with 191 additions and 20 deletions

View File

@@ -1,6 +1,7 @@
import type { Request, Response } from "express";
import TournamentModel from "../db/models/tournament.model.js";
import { activeGames } from "../db/models/game.model.js";
import { db } from "../db/index.js";
import { nanoid } from "nanoid";
import type { Game } from "@michess/types";
@@ -80,3 +81,22 @@ export const startTournament = async (req: Request, res: Response) => {
res.status(200).json(updated);
} catch (e) { console.error(e); res.status(500).end(); }
};
export const addBot = async (req: Request, res: Response) => {
if (!req.session.user?.id || typeof req.session.user.id === "string") { res.status(401).end(); return; }
const { botName } = req.body;
if (!botName) { res.status(400).json({ message: "Bot name erforderlich." }); return; }
try {
const tournament = await TournamentModel.findByCode(req.params.code);
if (!tournament) { res.status(404).end(); return; }
if (tournament.hostId !== req.session.user.id) { res.status(403).end(); return; }
if (tournament.status !== "waiting") { res.status(400).json({ message: "Turnier bereits gestartet." }); return; }
const botRes = await db.query(`SELECT id, name FROM "user" WHERE name=$1 AND role='bot'`, [botName]);
if (!botRes.rows[0]) { res.status(404).json({ message: "Bot nicht gefunden." }); return; }
const bot = botRes.rows[0];
const result = await TournamentModel.joinTournament(req.params.code, bot.id, bot.name);
if (!result) { res.status(400).json({ message: "Bot konnte nicht hinzugefügt werden." }); return; }
const updated = await TournamentModel.findByCode(req.params.code);
res.status(200).json(updated);
} catch (e) { console.error(e); res.status(500).end(); }
};