feat: add time controls, correspondence games, and tournament mode

**Zeitmodi (Blitz/Rapid):**
- 5, 10, 30 Min Zeitkontrolle bei Spielerstellung
- Server-seitige Uhren: Zeit wird bei jedem Zug abgezogen
- Timeout-Erkennung via claimTimeout Socket-Event
- Schachuhr-Anzeige in GamePage (rot bei < 30s)
- Turnierspiele erhalten automatisch Zeitkontrolle

**Tagespartien (Correspondence):**
- Neue DB-Tabelle correspondence_game
- REST API: erstellen, beitreten, Zug machen, aufgeben
- Seite /correspondence: Liste aktiver Tagespartien
- Seite /correspondence/[code]: Spielen mit interaktivem Brett
- Einladungslink teilen, Gegner tritt via Link bei

**Turniermodus (Round-Robin):**
- Neue DB-Tabellen: tournament, tournament_player, tournament_round
- Round-Robin Paarungen mit Circle-Methode
- Turnier erstellen: /tournament/create
- Turnierliste: /tournament
- Turnierseite /tournament/[code]: Standings, Runden, Spiele
- Automatische Aktivisierung der nächsten Runde
- Turnierspiele werden als normale activeGames erstellt
- Ergebnisse aktualisieren Punkte automatisch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Michess
2026-04-14 09:44:35 +02:00
parent 09e5271dfb
commit aeb5fe313e
25 changed files with 1653 additions and 16 deletions

View File

@@ -14,11 +14,11 @@ export default function Home() {
<div className="flex flex-col gap-8 w-full max-w-5xl px-4 py-8">
{/* Hauptaktionen */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div className="card bg-base-200 border-2 border-primary shadow-lg">
<div className="card-body gap-3">
<h2 className="card-title text-primary"> Spiel erstellen</h2>
<h2 className="card-title text-primary">Spiel erstellen</h2>
<p className="text-sm opacity-70">Erstelle eine Partie und teile den Einladungslink mit Freunden</p>
<div className="mt-2">
<CreateGame />
@@ -28,7 +28,7 @@ export default function Home() {
<div className="card bg-base-200 shadow-lg">
<div className="card-body gap-3">
<h2 className="card-title">🤖 Gegen KI spielen</h2>
<h2 className="card-title">Gegen KI spielen</h2>
<p className="text-sm opacity-70">Fordere Stockfish auf verschiedenen Stufen heraus von Anfänger bis Meister</p>
<div className="mt-auto pt-4">
<Link href="/ai" className="btn btn-secondary w-full">Jetzt spielen</Link>
@@ -40,7 +40,7 @@ export default function Home() {
<div className="card-body gap-3">
{isLoggedIn ? (
<>
<h2 className="card-title">👥 Freunde</h2>
<h2 className="card-title">Freunde</h2>
<p className="text-sm opacity-70">Freunde hinzufügen, verwalten und zu einer Partie einladen</p>
<div className="mt-auto pt-4">
<Link href="/friends" className="btn btn-outline w-full">Freunde verwalten</Link>
@@ -48,7 +48,7 @@ export default function Home() {
</>
) : (
<>
<h2 className="card-title">🔗 Einladung annehmen</h2>
<h2 className="card-title">Einladung annehmen</h2>
<p className="text-sm opacity-70 mb-2">Einladungslink oder Code eingeben um beizutreten</p>
<JoinGame />
</>
@@ -56,6 +56,26 @@ export default function Home() {
</div>
</div>
<div className="card bg-base-200 shadow-lg">
<div className="card-body gap-3">
<h2 className="card-title">Tagespartien</h2>
<p className="text-sm opacity-70">Spiele in deinem eigenen Tempo Züge bis zu 3 Tage Zeit</p>
<div className="mt-auto pt-4">
<Link href="/correspondence" className="btn btn-outline w-full">Tagespartien</Link>
</div>
</div>
</div>
<div className="card bg-base-200 shadow-lg">
<div className="card-body gap-3">
<h2 className="card-title">Turnier</h2>
<p className="text-sm opacity-70">Spiele Round-Robin Turniere gegen mehrere Gegner</p>
<div className="mt-auto pt-4">
<Link href="/tournament" className="btn btn-outline w-full">Turniere</Link>
</div>
</div>
</div>
</div>
{/* Öffentliche Spiele + Beitreten */}