Files
2026-09-08 18:21:10 +01:00

83 lines
3.4 KiB
PHP

<?php
// Shared helpers for turn-based multiplayer games stored in `matches`.
require_once __DIR__ . '/../lib/bootstrap.php';
function mp_create(string $game, int $uid, string $state): int {
$now = time();
db()->prepare("INSERT INTO matches (game,p1,turn,state,status,created_at,updated_at)
VALUES (?,?,1,?, 'open',?,?)")
->execute([$game, $uid, $state, $now, $now]);
return (int)db()->lastInsertId();
}
function mp_join(string $game, int $mid, int $uid): bool {
$s = db()->prepare("SELECT * FROM matches WHERE id=? AND game=?");
$s->execute([$mid, $game]);
$m = $s->fetch();
if (!$m || $m['status'] !== 'open' || (int)$m['p1'] === $uid) return false;
db()->prepare("UPDATE matches SET p2=?, status='playing', updated_at=? WHERE id=?")
->execute([$uid, time(), $mid]);
return true;
}
function mp_get(string $game, int $mid): ?array {
$s = db()->prepare("SELECT m.*, a.username AS n1, b.username AS n2
FROM matches m
LEFT JOIN users a ON a.id=m.p1
LEFT JOIN users b ON b.id=m.p2
WHERE m.id=? AND m.game=?");
$s->execute([$mid, $game]);
return $s->fetch() ?: null;
}
function mp_save(int $mid, string $state, int $turn, string $status = 'playing', ?int $winner = null): void {
db()->prepare("UPDATE matches SET state=?, turn=?, status=?, winner=?, updated_at=? WHERE id=?")
->execute([$state, $turn, $status, $winner, time(), $mid]);
}
// Which seat is this user in? 1, 2, or 0 for spectator.
function mp_seat(array $m, int $uid): int {
if ((int)$m['p1'] === $uid) return 1;
if ((int)$m['p2'] === $uid) return 2;
return 0;
}
// Render the lobby: open games to join, your active games, and a create button.
function mp_lobby(string $game, string $self, int $uid, string $newState): void {
$d = db();
$s = $d->prepare("SELECT m.*, a.username AS n1 FROM matches m
LEFT JOIN users a ON a.id=m.p1
WHERE m.game=? AND m.status='open' AND m.p1<>?
ORDER BY m.id DESC LIMIT 10");
$s->execute([$game, $uid]);
$open = $s->fetchAll();
$s = $d->prepare("SELECT m.*, a.username AS n1, b.username AS n2 FROM matches m
LEFT JOIN users a ON a.id=m.p1
LEFT JOIN users b ON b.id=m.p2
WHERE m.game=? AND (m.p1=? OR m.p2=?) AND m.status IN ('open','playing')
ORDER BY m.updated_at DESC LIMIT 10");
$s->execute([$game, $uid, $uid]);
$mine = $s->fetchAll();
if ($mine) {
p_para('Your games:');
foreach ($mine as $m) {
$opp = ((int)$m['p1'] === $uid) ? ($m['n2'] ?? 'waiting...') : ($m['n1'] ?? '?');
$yourTurn = ($m['status'] === 'playing' && mp_seat($m, $uid) === (int)$m['turn']);
p_link($self, '#' . $m['id'] . ' vs ' . $opp . ($yourTurn ? ' - YOUR TURN' : ''),
['g' => $m['id']]);
}
}
if ($open) {
p_para('Open games to join:');
foreach ($open as $m) {
p_link($self, 'Join #' . $m['id'] . ' by ' . ($m['n1'] ?? '?'), ['g' => $m['id'], 'join' => 1]);
}
}
if (!$mine && !$open) p_para('No games yet - create one and wait for an opponent.');
p_form($self, [
['name' => 'act', 'type' => 'hidden', 'value' => 'create'],
], 'Create new game');
}