const menuPanel = document.getElementById('menu'); const gamePanel = document.getElementById('game'); const statusDiv = document.getElementById('connection-status'); const createBtn = document.getElementById('create-btn'); const joinBtn = document.getElementById('join-btn'); const joinInput = document.getElementById('join-code'); const displayCode = document.getElementById('display-code'); const turnStatus = document.getElementById('turn-status'); const surrenderBtn = document.getElementById('surrender-btn'); const cells = document.querySelectorAll('.cell'); let mySymbol = ''; let ws = null; let currentCode = ''; function connect() { const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; ws = new WebSocket(`${protocol}//${window.location.host}/game`); ws.onopen = () => { statusDiv.textContent = 'Connected to Server'; statusDiv.style.color = '#10b981'; }; ws.onclose = () => { statusDiv.textContent = 'Disconnected. Reconnecting...'; statusDiv.style.color = '#ef4444'; setTimeout(connect, 2000); }; ws.onmessage = (event) => { handleMessage(event.data); }; } function send(msg) { if (ws && ws.readyState === WebSocket.OPEN) { ws.send(msg); } } createBtn.addEventListener('click', () => { send('CREATE'); }); joinBtn.addEventListener('click', () => { const code = joinInput.value.trim(); if (code) send(`JOIN ${code}`); }); surrenderBtn.addEventListener('click', () => { if (confirm('Are you sure you want to surrender?')) { send('SURRENDER'); } }); cells.forEach(cell => { cell.addEventListener('click', () => { const r = cell.dataset.r; const c = cell.dataset.c; send(`MOVE ${r} ${c}`); }); }); function handleMessage(msg) { console.log("Received:", msg); const parts = msg.split(' '); const cmd = parts[0]; switch (cmd) { case 'GAME_CREATED': currentCode = parts[1]; mySymbol = 'X'; enterGame(); updateStatus("Waiting for opponent..."); break; case 'JOIN_SUCCESS': currentCode = joinInput.value; mySymbol = 'O'; enterGame(); updateStatus("Connected! Game starting soon..."); break; case 'START': updateStatus("Game Started! X goes first."); break; case 'BOARD': const boardStr = msg.substring(6); updateBoard(boardStr); break; case 'TURN': const turn = parts[1]; if (turn === mySymbol) { updateStatus(`Your Turn (${mySymbol})`, true); } else { updateStatus(`Opponent's Turn (${turn})`, false); } break; case 'WIN': const winner = msg.substring(4); alert(`Game Over! Winner: ${winner}`); resetGame(); break; case 'DRAW': alert("Game Over! It's a draw!"); resetGame(); break; case 'ERROR:': alert(msg); break; } } function enterGame() { menuPanel.classList.add('hidden'); gamePanel.classList.remove('hidden'); displayCode.textContent = currentCode; // Clear board cells.forEach(c => { c.textContent = ''; c.className = 'cell'; }); } function resetGame() { menuPanel.classList.remove('hidden'); gamePanel.classList.add('hidden'); currentCode = ''; mySymbol = ''; joinInput.value = ''; statusDiv.textContent = 'Connected to Server'; statusDiv.style.color = '#10b981'; } function updateBoard(boardStr) { cells.forEach((cell, i) => { if (i < boardStr.length) { const char = boardStr.charAt(i); cell.textContent = char === ' ' ? '' : char; cell.className = 'cell'; if (char === 'X') cell.classList.add('x'); if (char === 'O') cell.classList.add('o'); } }); } function updateStatus(text, isAction = false) { turnStatus.textContent = text; if (isAction) { turnStatus.style.color = '#10b981'; // Green for 'your turn' } else { turnStatus.style.color = '#a1a1aa'; } } connect();