| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <title>Online Checkers</title> |
| <style> |
| body { font-family: sans-serif; text-align: center; } |
| table { border-collapse: collapse; margin: 20px auto; } |
| td { |
| width: 60px; height: 60px; text-align: center; vertical-align: middle; |
| border: 1px solid #444; font-size: 24px; |
| } |
| .black { background-color: #444; color: white; } |
| .red { background-color: red; color: white; } |
| .empty { background-color: #eee; } |
| .highlight { background-color: yellow !important; } |
| </style> |
| </head> |
| <body> |
| <h1>Online Checkers</h1> |
| <p id="status">Connecting...</p> |
| <table id="board"></table> |
|
|
| <script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script> |
| <script> |
| const socket = io(); |
| |
| let myColor = null; |
| let selected = null; |
| const boardElement = document.getElementById('board'); |
| const statusElement = document.getElementById('status'); |
| |
| socket.on('connect', () => { |
| const name = prompt("Enter your name:"); |
| socket.emit('set_name', { name: name || 'Player' }); |
| }); |
| |
| socket.on('match_found', data => { |
| myColor = data.color; |
| statusElement.innerText = `Matched! You are ${myColor}. Opponent: ${data.opponent}`; |
| }); |
| |
| socket.on('opponent_move', data => { |
| fetch('/state') |
| .then(res => res.json()) |
| .then(updateBoard); |
| }); |
| |
| socket.on('multi_jump', data => { |
| selected = data.from; |
| renderBoard(); |
| }); |
| |
| socket.on('game_over', data => { |
| statusElement.innerText = `Game over! Winner: ${data.winner}`; |
| }); |
| |
| socket.on('opponent_disconnected', () => { |
| statusElement.innerText = "Opponent disconnected. Game ended."; |
| }); |
| |
| function updateBoard(data) { |
| renderBoard(data.board); |
| } |
| |
| function renderBoard(boardData = null) { |
| boardElement.innerHTML = ''; |
| fetch('/state') |
| .then(res => res.json()) |
| .then(data => { |
| const board = data.board; |
| for (let i = 0; i < 8; i++) { |
| const row = document.createElement('tr'); |
| for (let j = 0; j < 8; j++) { |
| const cell = document.createElement('td'); |
| const piece = board[i][j]; |
| cell.className = (i + j) % 2 === 1 ? 'black' : 'empty'; |
| if (piece === 'r') cell.innerText = 'r'; |
| if (piece === 'R') cell.innerText = 'R'; |
| if (piece === 'b') cell.innerText = 'b'; |
| if (piece === 'B') cell.innerText = 'B'; |
| |
| if (selected && selected[0] === i && selected[1] === j) |
| cell.classList.add('highlight'); |
| |
| cell.onclick = () => handleClick(i, j, board); |
| row.appendChild(cell); |
| } |
| boardElement.appendChild(row); |
| } |
| }); |
| } |
| |
| function handleClick(i, j, board) { |
| const piece = board[i][j]; |
| if (selected) { |
| socket.emit('move', { from: selected, to: [i, j] }); |
| selected = null; |
| } else if (piece && myColor[0] === piece.toLowerCase()) { |
| selected = [i, j]; |
| renderBoard(); |
| } |
| } |
| |
| setInterval(renderBoard, 1500); |
| </script> |
| </body> |
| </html> |