array_fill(0, 9, '')])); redirect($SELF, ['g' => $mid]); } if ($act === 'move') { $mid = (int)($_POST['mid'] ?? 0); $m = mp_get('ttt', $mid); $seat = $m ? mp_seat($m, $uid) : 0; if (!$m || $m['status'] !== 'playing') $msg = 'Game is not in play.'; elseif ($seat === 0) $msg = 'You are not in this game.'; elseif ($seat !== (int)$m['turn']) $msg = 'Not your turn.'; else { $st = json_decode($m['state'], true); $cell = (int)($_POST['cell'] ?? 0) - 1; // players type 1-9 if ($cell < 0 || $cell > 8 || $st['b'][$cell] !== '') { $msg = 'That square is not free (pick 1-9).'; } else { $mark = $seat === 1 ? 'X' : 'O'; $st['b'][$cell] = $mark; $w = ttt_win($st['b']); $full = !in_array('', $st['b'], true); if ($w !== null) { mp_save($mid, json_encode($st), $seat, 'done', $uid); db()->prepare("INSERT INTO scores (game,user_id,score,detail,created_at) VALUES ('ttt',?,?,?,?)")->execute([$uid, 50, 'win', time()]); $msg = 'You win!'; } elseif ($full) { mp_save($mid, json_encode($st), $seat, 'done', null); $msg = 'Draw!'; } else { mp_save($mid, json_encode($st), $seat === 1 ? 2 : 1); $msg = 'Move played. Waiting for your opponent.'; } } } } } if ($mid && !empty($_GET['join'])) { if (mp_join('ttt', $mid, $uid)) $msg = 'You joined the game. Player 2 is O.'; else $msg = 'Could not join that game.'; } page_start('Noughts & Crosses', ['back' => '/games.php']); if ($msg) p_para($msg); if (!$mid) { mp_lobby('ttt', $SELF, $uid, json_encode(['b' => array_fill(0, 9, '')])); p_links([['/games.php', 'Games']]); page_end(); exit; } $m = mp_get('ttt', $mid); if (!$m) bail('Game', 'No such game.', $SELF); $st = json_decode($m['state'], true); $b = $st['b']; $seat = mp_seat($m, $uid); p_para('#' . $m['id'] . ': X=' . ($m['n1'] ?? '?') . ' vs O=' . ($m['n2'] ?? 'waiting')); // board: 3 rows, free cells show their number so WAP users know what to type for ($r = 0; $r < 3; $r++) { $cells = []; for ($c = 0; $c < 3; $c++) { $i = $r * 3 + $c; $cells[] = $b[$i] === '' ? (string)($i + 1) : $b[$i]; } p_para(implode(' | ', $cells)); } p_rule(); if ($m['status'] === 'open') { p_para('Waiting for an opponent to join. Tell a friend to open Games > Noughts & Crosses.'); } elseif ($m['status'] === 'done') { if ($m['winner'] === null) p_para('Result: draw.'); else { $wn = ((int)$m['winner'] === (int)$m['p1']) ? $m['n1'] : $m['n2']; p_para('Winner: ' . $wn); } } elseif ($seat === 0) { p_para('You are watching. Turn: player ' . $m['turn']); } elseif ($seat === (int)$m['turn']) { p_para('Your turn (' . ($seat === 1 ? 'X' : 'O') . '). Enter a free square number.'); p_form($SELF . '?g=' . $mid, [ ['name' => 'act', 'type' => 'hidden', 'value' => 'move'], ['name' => 'mid', 'type' => 'hidden', 'value' => (string)$mid], ['name' => 'cell', 'label' => 'Square (1-9)', 'maxlength' => 1, 'format' => 'N'], ], 'Play'); } else { p_para('Opponent to move. Check back shortly.'); } p_links([[$SELF, 'Refresh', ['g' => $mid]], [$SELF, 'Lobby'], ['/games.php', 'Games']]); page_end();