Show waiting players during practice
This commit is contained in:
65
game.js
65
game.js
@@ -35,6 +35,8 @@ let roomId = "";
|
||||
let gameMode = "practice";
|
||||
let multiplayerState = "local";
|
||||
let botTimer = 0;
|
||||
let lobbyTimer = 0;
|
||||
let waitingPlayers = 0;
|
||||
|
||||
function createBoard() {
|
||||
return Array.from({ length: size }, () => Array(size).fill(empty));
|
||||
@@ -54,6 +56,7 @@ function setupGame() {
|
||||
|
||||
function connectToServer() {
|
||||
gameMode = "online";
|
||||
stopLobbyPolling();
|
||||
closeSocket();
|
||||
localPlayer = "";
|
||||
roomId = "";
|
||||
@@ -103,7 +106,8 @@ function startPracticeMode() {
|
||||
roomId = "";
|
||||
multiplayerState = "local";
|
||||
setupGame();
|
||||
setMultiplayerState("local", "BOT practice. You are X. Random O replies after each move.");
|
||||
setPracticeStatus("BOT practice. You are X. Random O replies after each move.");
|
||||
startLobbyPolling();
|
||||
updateModeButtons();
|
||||
}
|
||||
|
||||
@@ -115,6 +119,40 @@ function closeSocket() {
|
||||
socket = null;
|
||||
}
|
||||
|
||||
function startLobbyPolling() {
|
||||
stopLobbyPolling();
|
||||
checkLobby();
|
||||
lobbyTimer = window.setInterval(checkLobby, 3000);
|
||||
}
|
||||
|
||||
function stopLobbyPolling() {
|
||||
if (lobbyTimer) {
|
||||
window.clearInterval(lobbyTimer);
|
||||
lobbyTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
async function checkLobby() {
|
||||
if (gameMode !== "practice") {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch("/lobby", { cache: "no-store" });
|
||||
if (!response.ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
const status = await response.json();
|
||||
waitingPlayers = Number(status.waitingPlayers || 0);
|
||||
if (!gameOver && currentPlayer === localPlayer) {
|
||||
setPracticeStatus("BOT practice. You are X. Random O replies after each move.");
|
||||
}
|
||||
} catch {
|
||||
waitingPlayers = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function handleServerMessage(payload) {
|
||||
if (payload.type === "waiting") {
|
||||
localPlayer = "";
|
||||
@@ -255,7 +293,7 @@ function playLocalMove(row, col) {
|
||||
}
|
||||
|
||||
if (!gameOver) {
|
||||
setMultiplayerState("local", "Bot thinking...");
|
||||
setPracticeStatus("Bot thinking...");
|
||||
botTimer = window.setTimeout(playBotMove, 360);
|
||||
}
|
||||
}
|
||||
@@ -276,14 +314,14 @@ function applyMove(row, col, player, source) {
|
||||
if (win.length > 0) {
|
||||
winningCells = win;
|
||||
gameOver = true;
|
||||
setMultiplayerState(activeState(), `${player} wins with four in a row.`);
|
||||
setActiveStatus(`${player} wins with four in a row.`);
|
||||
render();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isDraw()) {
|
||||
gameOver = true;
|
||||
setMultiplayerState(activeState(), "Draw. The board is full.");
|
||||
setActiveStatus("Draw. The board is full.");
|
||||
render();
|
||||
return true;
|
||||
}
|
||||
@@ -291,7 +329,7 @@ function applyMove(row, col, player, source) {
|
||||
currentPlayer = opponentOf(player);
|
||||
const captureMessage = captured.length > 0 ? `${player} captured ${captured.length}. ` : "";
|
||||
const turnMessage = currentPlayer === localPlayer ? "Your turn." : waitingMessage();
|
||||
setMultiplayerState(activeState(), `${captureMessage}${turnMessage}`);
|
||||
setActiveStatus(`${captureMessage}${turnMessage}`);
|
||||
render();
|
||||
flashCapturedCells(captured);
|
||||
|
||||
@@ -306,6 +344,15 @@ function activeState() {
|
||||
return gameMode === "practice" ? "local" : "paired";
|
||||
}
|
||||
|
||||
function setActiveStatus(text) {
|
||||
if (gameMode === "practice") {
|
||||
setPracticeStatus(text);
|
||||
return;
|
||||
}
|
||||
|
||||
setMultiplayerState(activeState(), text);
|
||||
}
|
||||
|
||||
function waitingMessage() {
|
||||
return gameMode === "practice" ? "Bot turn." : `Waiting for ${currentPlayer}.`;
|
||||
}
|
||||
@@ -401,6 +448,11 @@ function setMultiplayerState(state, text) {
|
||||
messageElement.textContent = text;
|
||||
}
|
||||
|
||||
function setPracticeStatus(text) {
|
||||
const suffix = waitingPlayers > 0 ? " NET: player waiting." : " NET: no one waiting.";
|
||||
setMultiplayerState("local", `${text}${suffix}`);
|
||||
}
|
||||
|
||||
function playBotMove() {
|
||||
if (gameMode !== "practice" || gameOver || currentPlayer !== "O") {
|
||||
return;
|
||||
@@ -471,7 +523,7 @@ resetButton.addEventListener("click", () => {
|
||||
setupGame();
|
||||
|
||||
if (gameMode === "practice") {
|
||||
setMultiplayerState("local", "BOT practice. You are X. Random O replies after each move.");
|
||||
setPracticeStatus("BOT practice. You are X. Random O replies after each move.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -482,6 +534,7 @@ resetButton.addEventListener("click", () => {
|
||||
practiceButton.addEventListener("click", startPracticeMode);
|
||||
onlineButton.addEventListener("click", () => {
|
||||
gameMode = "online";
|
||||
stopLobbyPolling();
|
||||
localPlayer = "";
|
||||
roomId = "";
|
||||
multiplayerState = "connecting";
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
<div class="rule-card">
|
||||
<h2>MODES</h2>
|
||||
<p>BOT is local practice against random moves. NET pairs the first two connected players automatically.</p>
|
||||
<p>BOT is local practice against random moves and shows if NET has a player waiting. NET pairs the first two connected players automatically.</p>
|
||||
</div>
|
||||
|
||||
<ol id="moveList" class="move-list" aria-label="Move history"></ol>
|
||||
|
||||
16
server.js
16
server.js
@@ -76,6 +76,15 @@ const server = http.createServer((request, response) => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestUrl.pathname === "/lobby") {
|
||||
response.writeHead(200, {
|
||||
"Cache-Control": "no-store",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
});
|
||||
response.end(request.method === "HEAD" ? undefined : JSON.stringify(lobbyStatus()));
|
||||
return;
|
||||
}
|
||||
|
||||
const staticName = staticFiles.get(requestUrl.pathname);
|
||||
if (!staticName) {
|
||||
response.writeHead(404);
|
||||
@@ -257,6 +266,13 @@ function pairClients(xClient, oClient) {
|
||||
send(oClient, { type: "paired", player: "O", roomId });
|
||||
}
|
||||
|
||||
function lobbyStatus() {
|
||||
return {
|
||||
activeGames: rooms.size,
|
||||
waitingPlayers: waitingClientId && clients.has(waitingClientId) ? 1 : 0,
|
||||
};
|
||||
}
|
||||
|
||||
function handleSocketData(client, buffer) {
|
||||
if (!clients.has(client.id)) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user