Spaces:
Running
Running
| document.addEventListener('DOMContentLoaded', () => { | |
| // Game state | |
| const gameState = { | |
| boardSize: 10, | |
| cells: [], | |
| startPos: null, | |
| endPos: null, | |
| walls: [], | |
| mode: 'draw', // 'draw', 'start', 'end', 'wall' | |
| isSolving: false, | |
| solutionPath: [] | |
| }; | |
| // Initialize the game | |
| function initGame() { | |
| createBoard(); | |
| setupEventListeners(); | |
| } | |
| // Create the game board | |
| function createBoard() { | |
| const gameBoard = document.querySelector('custom-game-board'); | |
| gameBoard.shadowRoot.innerHTML = ` | |
| <style> | |
| .game-board { | |
| display: grid; | |
| gap: 0; | |
| grid-template-columns: repeat(${gameState.boardSize}, 1fr); | |
| } | |
| </style> | |
| <div class="game-board bg-gray-800 p-2 rounded-lg shadow-xl"></div> | |
| `; | |
| const boardElement = gameBoard.shadowRoot.querySelector('.game-board'); | |
| boardElement.innerHTML = ''; | |
| gameState.cells = []; | |
| for (let y = 0; y < gameState.boardSize; y++) { | |
| for (let x = 0; x < gameState.boardSize; x++) { | |
| const cell = document.createElement('div'); | |
| cell.className = 'cell'; | |
| cell.dataset.x = x; | |
| cell.dataset.y = y; | |
| boardElement.appendChild(cell); | |
| gameState.cells.push({ x, y, element: cell }); | |
| } | |
| } | |
| } | |
| // Setup event listeners | |
| function setupEventListeners() { | |
| const gameBoard = document.querySelector('custom-game-board'); | |
| gameBoard.shadowRoot.querySelector('.game-board').addEventListener('click', handleCellClick); | |
| const controls = document.querySelector('custom-controls'); | |
| controls.shadowRoot.querySelector('#solve-btn').addEventListener('click', solvePuzzle); | |
| controls.shadowRoot.querySelector('#reset-btn').addEventListener('click', resetBoard); | |
| controls.shadowRoot.querySelector('#mode-select').addEventListener('change', (e) => { | |
| gameState.mode = e.target.value; | |
| }); | |
| } | |
| // Handle cell clicks | |
| function handleCellClick(e) { | |
| if (gameState.isSolving) return; | |
| const cell = e.target.closest('.cell'); | |
| if (!cell) return; | |
| const x = parseInt(cell.dataset.x); | |
| const y = parseInt(cell.dataset.y); | |
| switch (gameState.mode) { | |
| case 'start': | |
| setStartPosition(x, y); | |
| break; | |
| case 'end': | |
| setEndPosition(x, y); | |
| break; | |
| case 'wall': | |
| toggleWall(x, y); | |
| break; | |
| default: | |
| // Do nothing | |
| break; | |
| } | |
| } | |
| // Set start position | |
| function setStartPosition(x, y) { | |
| // Clear previous start | |
| if (gameState.startPos) { | |
| const prevCell = document.querySelector(`.cell[data-x="${gameState.startPos.x}"][data-y="${gameState.startPos.y}"]`); | |
| prevCell?.classList.remove('start'); | |
| } | |
| // Set new start | |
| const cell = document.querySelector(`.cell[data-x="${x}"][data-y="${y}"]`); | |
| cell.classList.add('start'); | |
| gameState.startPos = { x, y }; | |
| } | |
| // Set end position | |
| function setEndPosition(x, y) { | |
| // Clear previous end | |
| if (gameState.endPos) { | |
| const prevCell = document.querySelector(`.cell[data-x="${gameState.endPos.x}"][data-y="${gameState.endPos.y}"]`); | |
| prevCell?.classList.remove('end'); | |
| } | |
| // Set new end | |
| const cell = document.querySelector(`.cell[data-x="${x}"][data-y="${y}"]`); | |
| cell.classList.add('end'); | |
| gameState.endPos = { x, y }; | |
| } | |
| // Toggle wall | |
| function toggleWall(x, y) { | |
| const cell = document.querySelector(`.cell[data-x="${x}"][data-y="${y}"]`); | |
| const isWall = cell.classList.contains('wall'); | |
| if (isWall) { | |
| cell.classList.remove('wall'); | |
| gameState.walls = gameState.walls.filter(wall => !(wall.x === x && wall.y === y)); | |
| } else { | |
| cell.classList.add('wall'); | |
| gameState.walls.push({ x, y }); | |
| } | |
| } | |
| // Solve the puzzle | |
| function solvePuzzle() { | |
| if (!gameState.startPos || !gameState.endPos) { | |
| alert('Please set both start and end positions!'); | |
| return; | |
| } | |
| gameState.isSolving = true; | |
| gameState.solutionPath = findPath(); | |
| animateSolution(); | |
| } | |
| // Find path (simplified for demo) | |
| function findPath() { | |
| // This is a simplified pathfinding algorithm | |
| // In a real implementation, you would use A* or similar | |
| const path = []; | |
| let current = { ...gameState.startPos }; | |
| while (current.x !== gameState.endPos.x || current.y !== gameState.endPos.y) { | |
| path.push({ ...current }); | |
| // Simple movement towards target | |
| if (current.x < gameState.endPos.x) current.x++; | |
| else if (current.x > gameState.endPos.x) current.x--; | |
| if (current.y < gameState.endPos.y) current.y++; | |
| else if (current.y > gameState.endPos.y) current.y--; | |
| // Prevent infinite loops | |
| if (path.length > gameState.boardSize * 2) break; | |
| } | |
| path.push({ ...gameState.endPos }); | |
| return path; | |
| } | |
| // Animate the solution | |
| function animateSolution() { | |
| if (gameState.solutionPath.length === 0) { | |
| gameState.isSolving = false; | |
| return; | |
| } | |
| const step = gameState.solutionPath.shift(); | |
| const cell = document.querySelector(`.cell[data-x="${step.x}"][data-y="${step.y}"]`); | |
| if (!cell.classList.contains('start') && !cell.classList.contains('end')) { | |
| cell.classList.add('path', 'trace-animation'); | |
| } | |
| setTimeout(animateSolution, 200); | |
| } | |
| // Reset the board | |
| function resetBoard() { | |
| gameState.startPos = null; | |
| gameState.endPos = null; | |
| gameState.walls = []; | |
| gameState.solutionPath = []; | |
| gameState.isSolving = false; | |
| document.querySelectorAll('.cell').forEach(cell => { | |
| cell.className = 'cell'; | |
| }); | |
| } | |
| // Initialize the game | |
| initGame(); | |
| }); |