Spaces:
Running
Running
now add live playing and adding more context of adding a live game of chess with deepseek and other player
b722814 verified | <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ChessVision Pro - Ultimate Chess Experience</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <style> | |
| .chess-board { | |
| display: grid; | |
| grid-template-columns: repeat(8, 1fr); | |
| grid-template-rows: repeat(8, 1fr); | |
| width: min(90vw, 600px); | |
| height: min(90vw, 600px); | |
| border: 4px solid #8B4513; | |
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); | |
| } | |
| .chess-square { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 2rem; | |
| transition: all 0.2s ease; | |
| cursor: pointer; | |
| } | |
| .chess-square:hover { | |
| transform: scale(1.05); | |
| z-index: 10; | |
| } | |
| .white-square { | |
| background-color: #F0D9B5; | |
| } | |
| .black-square { | |
| background-color: #B58863; | |
| } | |
| .selected { | |
| background-color: #90EE90 ; | |
| } | |
| .possible-move { | |
| position: relative; | |
| } | |
| .possible-move::after { | |
| content: ''; | |
| position: absolute; | |
| width: 20px; | |
| height: 20px; | |
| background-color: rgba(0, 255, 0, 0.3); | |
| border-radius: 50%; | |
| } | |
| .piece { | |
| user-select: none; | |
| filter: drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.3)); | |
| } | |
| @keyframes pieceMove { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.1); } | |
| 100% { transform: scale(1); } | |
| } | |
| .moving { | |
| animation: pieceMove 0.3s ease; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gradient-to-br from-gray-900 to-gray-800 min-h-screen text-white"> | |
| <!-- Header --> | |
| <header class="bg-black/50 backdrop-blur-sm border-b border-gray-700 py-4"> | |
| <div class="container mx-auto px-4"> | |
| <div class="flex items-center justify-between"> | |
| <div class="flex items-center space-x-3"> | |
| <i data-feather="award" class="text-yellow-400"></i> | |
| <h1 class="text-2xl font-bold bg-gradient-to-r from-yellow-400 to-orange-500 bg-clip-text text-transparent"> | |
| ChessVision Pro ♟️ | |
| </h1> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <button class="bg-green-600 hover:bg-green-700 px-4 py-2 rounded-lg transition-colors flex items-center space-x-2"> | |
| <i data-feather="refresh-cw"></i> | |
| <span>New Game</span> | |
| </button> | |
| <button class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg transition-colors flex items-center space-x-2"> | |
| <i data-feather="users"></i> | |
| <span>Multiplayer</span> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </header> | |
| <main class="container mx-auto px-4 py-8"> | |
| <div class="grid lg:grid-cols-3 gap-8 items-start"> | |
| <!-- Left Sidebar --> | |
| <div class="space-y-6"> | |
| <div class="bg-gray-800/50 backdrop-blur-sm rounded-xl p-6 border border-gray-700"> | |
| <h2 class="text-xl font-bold mb-4 flex items-center space-x-2"> | |
| <i data-feather="users"></i> | |
| <span>Game Mode</span> | |
| </h2> | |
| <div class="space-y-3"> | |
| <button class="w-full bg-purple-600 hover:bg-purple-700 px-4 py-3 rounded-lg transition-colors flex items-center space-x-2 justify-center game-mode-btn" data-mode="ai"> | |
| <i data-feather="cpu"></i> | |
| <span>Play vs AI (DeepSeek)</span> | |
| </button> | |
| <button class="w-full bg-indigo-600 hover:bg-indigo-700 px-4 py-3 rounded-lg transition-colors flex items-center space-x-2 justify-center game-mode-btn" data-mode="multiplayer"> | |
| <i data-feather="users"></i> | |
| <span>Live Multiplayer</span> | |
| </button> | |
| <button class="w-full bg-gray-600 hover:bg-gray-700 px-4 py-3 rounded-lg transition-colors flex items-center space-x-2 justify-center game-mode-btn" data-mode="local"> | |
| <i data-feather="user"></i> | |
| <span>Local Play</span> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="bg-gray-800/50 backdrop-blur-sm rounded-xl p-6 border border-gray-700"> | |
| <h2 class="text-xl font-bold mb-4 flex items-center space-x-2"> | |
| <i data-feather="users"></i> | |
| <span>Game Info</span> | |
| </h2> | |
| <div class="space-y-3"> | |
| <div class="flex justify-between"> | |
| <span class="text-gray-400">Mode:</span> | |
| <span class="font-semibold text-white" id="currentMode">Local Play</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span class="text-gray-400">Player:</span> | |
| <span class="font-semibold text-white">White</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span class="text-gray-400">Opponent:</span> | |
| <span class="font-semibold text-gray-300">Black</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span class="text-gray-400">Turn:</span> | |
| <span class="font-semibold text-green-400">White to Move</span> | |
| </div> | |
| <div class="flex justify-between" id="aiStatus" style="display: none;"> | |
| <span class="text-gray-400">AI Status:</span> | |
| <span class="font-semibold text-yellow-400">Ready</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-800/50 backdrop-blur-sm rounded-xl p-6 border border-gray-700"> | |
| <h2 class="text-xl font-bold mb-4 flex items-center space-x-2"> | |
| <i data-feather="activity"></i> | |
| <span>Statistics</span> | |
| </h2> | |
| <div class="space-y-3"> | |
| <div class="flex justify-between"> | |
| <span class="text-gray-400">Moves:</span> | |
| <span class="font-semibold">0</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span class="text-gray-400">Captures:</span> | |
| <span class="font-semibold">0</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span class="text-gray-400">Time:</span> | |
| <span class="font-semibold">00:00</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Chess Board --> | |
| <div class="flex flex-col items-center justify-center"> | |
| <div class="chess-board" id="chessBoard"> | |
| <!-- Chess board squares will be generated by JavaScript --> | |
| </div> | |
| <div class="mt-6 flex space-x-4"> | |
| <button class="bg-red-600 hover:bg-red-700 px-6 py-3 rounded-lg transition-colors flex items-center space-x-2"> | |
| <i data-feather="flag"></i> | |
| <span>Resign</span> | |
| </button> | |
| <button class="bg-yellow-600 hover:bg-yellow-700 px-6 py-3 rounded-lg transition-colors flex items-center space-x-2"> | |
| <i data-feather="rotate-ccw"></i> | |
| <span>Undo Move</span> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Right Sidebar --> | |
| <div class="space-y-6"> | |
| <div class="bg-gray-800/50 backdrop-blur-sm rounded-xl p-6 border border-gray-700"> | |
| <h2 class="text-xl font-bold mb-4 flex items-center space-x-2"> | |
| <i data-feather="message-circle"></i> | |
| <span>Live Game Context</span> | |
| </h2> | |
| <div class="space-y-3 text-gray-300"> | |
| <div id="gameContext"> | |
| <p><strong>🎯 Current Mode: Local Play</strong></p> | |
| <p class="text-sm">Play against yourself or with a friend on the same device.</p> | |
| </div> | |
| </div> | |
| <div class="bg-gray-800/50 backdrop-blur-sm rounded-xl p-6 border border-gray-700" id="aiPanel" style="display: none;"> | |
| <h2 class="text-xl font-bold mb-4 flex items-center space-x-2"> | |
| <i data-feather="cpu"></i> | |
| <span>DeepSeek AI</span> | |
| </h2> | |
| <div class="space-y-3"> | |
| <div class="flex justify-between"> | |
| <span class="text-gray-400">AI Level:</span> | |
| <select class="bg-gray-700 text-white rounded px-2 py-1" id="aiLevel"> | |
| <option value="beginner">Beginner</option> | |
| <option value="intermediate" selected>Intermediate</option> | |
| <option value="advanced">Advanced</option> | |
| <option value="expert">Expert</option> | |
| </select> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span class="text-gray-400">Thinking:</span> | |
| <span class="font-semibold text-yellow-400" id="aiThinking">No</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-800/50 backdrop-blur-sm rounded-xl p-6 border border-gray-700" id="multiplayerPanel" style="display: none;"> | |
| <h2 class="text-xl font-bold mb-4 flex items-center space-x-2"> | |
| <i data-feather="globe"></i> | |
| <span>Live Multiplayer</span> | |
| </h2> | |
| <div class="space-y-3"> | |
| <button class="w-full bg-green-600 hover:bg-green-700 px-4 py-3 rounded-lg transition-colors flex items-center space-x-2 justify-center" id="createGameBtn"> | |
| <i data-feather="plus"></i> | |
| <span>Create Game Room</span> | |
| </button> | |
| <div class="flex space-x-2"> | |
| <input type="text" placeholder="Room ID" class="flex-1 bg-gray-700 text-white rounded px-3 py-2" id="roomIdInput"> | |
| <button class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded transition-colors"> | |
| <i data-feather="log-in"></i> | |
| </button> | |
| </div> | |
| <div class="text-center text-sm text-gray-400" id="roomStatus"> | |
| No active room | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-800/50 backdrop-blur-sm rounded-xl p-6 border border-gray-700"> | |
| <h2 class="text-xl font-bold mb-4 flex items-center space-x-2"> | |
| <i data-feather="clock"></i> | |
| <span>Move History</span> | |
| </h2> | |
| <div class="space-y-2 max-h-48 overflow-y-auto"> | |
| <div class="text-center text-gray-400 py-4"> | |
| No moves yet. Make your first move! | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="bg-black/50 backdrop-blur-sm border-t border-gray-700 py-6 mt-12"> | |
| <div class="container mx-auto px-4 text-center text-gray-400"> | |
| <p>ChessVision Pro ♟️ - The ultimate chess experience with 64 squares of strategic possibilities</p> | |
| </div> | |
| </footer> | |
| <script> | |
| // Initialize chess pieces | |
| const pieceSymbols = { | |
| 'white': { | |
| 'king': '♔', | |
| 'queen': '♕', | |
| 'rook': '♖', | |
| 'bishop': '♗', | |
| 'knight': '♘', | |
| 'pawn': '♙' | |
| }, | |
| 'black': { | |
| 'king': '♚', | |
| 'queen': '♛', | |
| 'rook': '♜', | |
| 'bishop': '♝', | |
| 'knight': '♞', | |
| 'pawn': '♟' | |
| } | |
| }; | |
| // Initial board setup | |
| const initialBoard = [ | |
| ['black-rook', 'black-knight', 'black-bishop', 'black-queen', 'black-king', 'black-bishop', 'black-knight', 'black-rook'], | |
| ['black-pawn', 'black-pawn', 'black-pawn', 'black-pawn', 'black-pawn', 'black-pawn', 'black-pawn', 'black-pawn'], | |
| ['', '', '', '', '', '', '', ''], | |
| ['', '', '', '', '', '', '', ''], | |
| ['', '', '', '', '', '', '', ''], | |
| ['', '', '', '', '', '', '', ''], | |
| ['white-pawn', 'white-pawn', 'white-pawn', 'white-pawn', 'white-pawn', 'white-pawn', 'white-pawn', 'white-pawn'], | |
| ['white-rook', 'white-knight', 'white-bishop', 'white-queen', 'white-king', 'white-bishop', 'white-knight', 'white-rook'] | |
| ]; | |
| let selectedSquare = null; | |
| let currentTurn = 'white'; | |
| let gameMode = 'local'; | |
| let gameRoom = null; | |
| let isPlayerWhite = true; | |
| // Create chess board | |
| function createChessBoard() { | |
| const board = document.getElementById('chessBoard'); | |
| board.innerHTML = ''; | |
| for (let row = 0; row < 8; row++) { | |
| for (let col = 0; col < 8; col++) { | |
| const square = document.createElement('div'); | |
| square.className = `chess-square ${(row + col) % 2 === 0 ? 'white-square' : 'black-square'}`; | |
| square.dataset.row = row; | |
| square.dataset.col = col; | |
| // Add piece if exists | |
| const piece = initialBoard[row][col]; | |
| if (piece) { | |
| const [color, type] = piece.split('-'); | |
| const pieceElement = document.createElement('div'); | |
| pieceElement.className = 'piece'; | |
| pieceElement.textContent = pieceSymbols[color][type]; | |
| pieceElement.dataset.color = color; | |
| pieceElement.dataset.type = type; | |
| square.appendChild(pieceElement); | |
| } | |
| square.addEventListener('click', handleSquareClick); | |
| board.appendChild(square); | |
| } | |
| } | |
| } | |
| // Handle square clicks | |
| function handleSquareClick(event) { | |
| const square = event.currentTarget; | |
| const row = parseInt(square.dataset.row); | |
| const col = parseInt(square.dataset.col); | |
| const piece = square.querySelector('.piece'); | |
| // Check if it's player's turn based on game mode | |
| if (gameMode === 'ai' && currentTurn === 'black') return; | |
| if (gameMode === 'multiplayer' && ((isPlayerWhite && currentTurn === 'black') || (!isPlayerWhite && currentTurn === 'white'))) return; | |
| // If no piece selected and clicked on own piece | |
| if (!selectedSquare && piece && piece.dataset.color === currentTurn) { | |
| selectSquare(square); | |
| return; | |
| } | |
| // If piece already selected | |
| if (selectedSquare) { | |
| // If clicking on same square, deselect | |
| if (selectedSquare === square) { | |
| deselectSquare(); | |
| return; | |
| } | |
| // If clicking on own piece, select that piece instead | |
| if (piece && piece.dataset.color === currentTurn) { | |
| deselectSquare(); | |
| selectSquare(square); | |
| return; | |
| } | |
| // Attempt to move piece | |
| movePiece(selectedSquare, square); | |
| // If playing against AI and it's AI's turn | |
| if (gameMode === 'ai' && currentTurn === 'black') { | |
| setTimeout(makeAIMove, 1000); | |
| } | |
| } | |
| } | |
| // Select square | |
| function selectSquare(square) { | |
| deselectSquare(); // Clear any previous selection | |
| selectedSquare = square; | |
| square.classList.add('selected'); | |
| // Show possible moves (simplified for demo) | |
| const piece = square.querySelector('.piece'); | |
| if (piece) { | |
| showPossibleMoves(square, piece); | |
| } | |
| } | |
| // Deselect square | |
| function deselectSquare() { | |
| if (selectedSquare) { | |
| selectedSquare.classList.remove('selected'); | |
| clearPossibleMoves(); | |
| selectedSquare = null; | |
| } | |
| } | |
| // Show possible moves (simplified) | |
| function showPossibleMoves(square, piece) { | |
| const row = parseInt(square.dataset.row); | |
| const col = parseInt(square.dataset.col); | |
| const color = piece.dataset.color; | |
| const type = piece.dataset.type; | |
| // Basic movement patterns for demo | |
| const moves = []; | |
| if (type === 'pawn') { | |
| const direction = color === 'white' ? -1 : 1; | |
| moves.push({ row: row + direction, col: col }); | |
| // Capture moves | |
| moves.push({ row: row + direction, col: col - 1 }); | |
| moves.push({ row: row + direction, col: col + 1 }); | |
| } else if (type === 'knight') { | |
| moves.push({ row: row - 2, col: col - 1 }); | |
| moves.push({ row: row - 2, col: col + 1 }); | |
| moves.push({ row: row - 1, col: col - 2 }); | |
| moves.push({ row: row - 1, col: col + 2 }); | |
| moves.push({ row: row + 1, col: col - 2 }); | |
| moves.push({ row: row + 1, col: col + 2 }); | |
| moves.push({ row: row + 2, col: col - 1 }); | |
| moves.push({ row: row + 2, col: col + 1 }); | |
| } | |
| // Highlight possible moves | |
| moves.forEach(move => { | |
| if (move.row >= 0 && move.row < 8 && move.col >= 0 && move.col < 8) { | |
| const targetSquare = document.querySelector(`[data-row="${move.row}"][data-col="${move.col}"]`); | |
| if (targetSquare) { | |
| targetSquare.classList.add('possible-move'); | |
| } | |
| }); | |
| } | |
| // Clear possible moves | |
| function clearPossibleMoves() { | |
| document.querySelectorAll('.possible-move').forEach(square => { | |
| square.classList.remove('possible-move'); | |
| }); | |
| } | |
| // Move piece | |
| function movePiece(fromSquare, toSquare) { | |
| const piece = fromSquare.querySelector('.piece'); | |
| if (piece) { | |
| // Add moving animation | |
| piece.classList.add('moving'); | |
| setTimeout(() => { | |
| toSquare.appendChild(piece); | |
| piece.classList.remove('moving'); | |
| // Switch turns | |
| currentTurn = currentTurn === 'white' ? 'black' : 'white'; | |
| updateTurnDisplay(); | |
| // If multiplayer, send move to server | |
| if (gameMode === 'multiplayer' && gameRoom) { | |
| sendMoveToServer(fromSquare, toSquare); | |
| } | |
| deselectSquare(); | |
| }, 150); | |
| } | |
| } | |
| // Make AI move (simulated) | |
| function makeAIMove() { | |
| if (gameMode !== 'ai' || currentTurn !== 'black') return; | |
| // Show AI thinking status | |
| document.getElementById('aiThinking').textContent = 'Yes'; | |
| setTimeout(() => { | |
| // Find all possible moves for black pieces | |
| const blackPieces = document.querySelectorAll('.piece[data-color="black"]'); | |
| const possibleMoves = []; | |
| blackPieces.forEach(piece => { | |
| const square = piece.parentElement; | |
| const row = parseInt(square.dataset.row); | |
| const col = parseInt(square.dataset.col); | |
| // Simple AI logic - move random piece to random valid position | |
| const pieceType = piece.dataset.type; | |
| let moves = []; | |
| if (pieceType === 'pawn') { | |
| moves.push({ row: row + 1, col: col }); | |
| moves.push({ row: row + 1, col: col - 1 }); | |
| moves.push({ row: row + 1, col: col + 1 }); | |
| } else if (pieceType === 'knight') { | |
| moves.push({ row: row - 2, col: col - 1 }); | |
| moves.push({ row: row - 2, col: col + 1 }); | |
| moves.push({ row: row - 1, col: col - 2 }); | |
| moves.push({ row: row - 1, col: col + 2 }); | |
| moves.push({ row: row + 1, col: col - 2 }); | |
| moves.push({ row: row + 1, col: col + 2 }); | |
| moves.push({ row: row + 2, col: col - 1 }); | |
| moves.push({ row: row + 2, col: col + 1 }); | |
| } | |
| // Filter valid moves | |
| moves = moves.filter(move => | |
| move.row >= 0 && move.row < 8 && move.col >= 0 && move.col < 8 | |
| ); | |
| moves.forEach(move => { | |
| const targetSquare = document.querySelector(`[data-row="${move.row}"][data-col="${move.col}"]'); | |
| if (targetSquare && (!targetSquare.querySelector('.piece') || targetSquare.querySelector('.piece[data-color="white"]'))) { | |
| possibleMoves.push({ from: square, to: targetSquare }); | |
| } | |
| }); | |
| }); | |
| // Make a random move if available | |
| if (possibleMoves.length > 0) { | |
| const randomMove = possibleMoves[Math.floor(Math.random() * possibleMoves.length)]; | |
| movePiece(randomMove.from, randomMove.to); | |
| } | |
| document.getElementById('aiThinking').textContent = 'No'; | |
| }, 1500); | |
| } | |
| // Game mode selection | |
| function setGameMode(mode) { | |
| gameMode = mode; | |
| document.getElementById('currentMode').textContent = | |
| mode === 'ai' ? 'AI (DeepSeek)' : | |
| mode === 'multiplayer' ? 'Live Multiplayer' : 'Local Play'; | |
| // Update UI based on mode | |
| document.getElementById('aiStatus').style.display = mode === 'ai' ? 'flex' : 'none'; | |
| document.getElementById('aiPanel').style.display = mode === 'ai' ? 'block' : 'none'; | |
| document.getElementById('multiplayerPanel').style.display = mode === 'multiplayer' ? 'block' : 'none'; | |
| // Update game context | |
| const context = document.getElementById('gameContext'); | |
| if (mode === 'ai') { | |
| context.innerHTML = ` | |
| <p><strong>🤖 Playing vs AI</strong></p> | |
| <p class="text-sm">Challenge DeepSeek AI with adjustable difficulty levels.</p> | |
| <ul class="list-disc list-inside space-y-1 ml-2 text-sm"> | |
| <li>Smart move prediction</li> | |
| <li>Multiple difficulty levels</li> | |
| <li>Real-time analysis</li> | |
| </ul> | |
| `; | |
| } else if (mode === 'multiplayer') { | |
| context.innerHTML = ` | |
| <p><strong>🌐 Live Multiplayer</strong></p> | |
| <p class="text-sm">Play against real opponents worldwide in real-time.</p> | |
| <ul class="list-disc list-inside space-y-1 ml-2 text-sm"> | |
| <li>Real-time game synchronization</li> | |
| <li>Chat with opponents</li> | |
| <li>Elo rating system</li> | |
| </ul> | |
| `; | |
| } else { | |
| context.innerHTML = ` | |
| <p><strong>🎯 Current Mode: Local Play</strong></p> | |
| <p class="text-sm">Play against yourself or with a friend on the same device.</p> | |
| `; | |
| } | |
| // Reset game state for new mode | |
| createChessBoard(); | |
| currentTurn = 'white'; | |
| updateTurnDisplay(); | |
| } | |
| // Send move to multiplayer server (simulated) | |
| function sendMoveToServer(fromSquare, toSquare) { | |
| console.log('Sending move to server:', { | |
| from: { row: fromSquare.dataset.row, col: fromSquare.dataset.col }, | |
| to: { row: toSquare.dataset.row, col: toSquare.dataset.col } | |
| }); | |
| // Simulate server response | |
| setTimeout(() => { | |
| document.getElementById('roomStatus').textContent = 'Move sent to opponent'; | |
| }, 500); | |
| } | |
| // Initialize game mode buttons | |
| function initGameModes() { | |
| document.querySelectorAll('.game-mode-btn').forEach(btn => { | |
| btn.addEventListener('click', () => { | |
| setGameMode(btn.dataset.mode); | |
| }); | |
| }); | |
| // Multiplayer buttons | |
| document.getElementById('createGameBtn').addEventListener('click', () => { | |
| const roomId = Math.random().toString(36).substring(2, 8).toUpperCase(); | |
| document.getElementById('roomIdInput').value = roomId; | |
| gameRoom = roomId; | |
| document.getElementById('roomStatus').textContent = `Room created: ${roomId}`; | |
| }); | |
| } | |
| // Update turn display | |
| function updateTurnDisplay() { | |
| const turnElements = document.querySelectorAll('[class*="turn"]'); | |
| turnElements.forEach(el => { | |
| el.textContent = `${currentTurn.charAt(0).toUpperCase() + currentTurn.slice(1)} to Move`; | |
| el.className = el.className.replace(/text-\w+-400/, ''); | |
| el.classList.add(currentTurn === 'white' ? 'text-green-400' : 'text-blue-400'); | |
| }); | |
| } | |
| // Initialize the board | |
| document.addEventListener('DOMContentLoaded', () => { | |
| createChessBoard(); | |
| initGameModes(); | |
| feather.replace(); | |
| }); | |
| // Add multiplayer functionality | |
| document.getElementById('createGameBtn').addEventListener('click', function() { | |
| const roomId = Math.random().toString(36).substring(2, 8).toUpperCase(); | |
| document.getElementById('roomIdInput').value = roomId; | |
| gameRoom = roomId; | |
| document.getElementById('roomStatus').textContent = `Room created: ${roomId}`; | |
| }); | |
| </script> | |
| </body> | |
| </html> | |