| | document.addEventListener('DOMContentLoaded', () => { |
| | |
| | const gridContainer = document.getElementById('grid-container'); |
| | const targetCoordsDisplay = document.getElementById('target-coords'); |
| | const feedbackDisplay = document.getElementById('feedback'); |
| | const itemNameDisplay = document.getElementById('item-name'); |
| | const yAxisLabelsContainer = document.getElementById('y-axis-labels'); |
| | const xAxisLabelsContainer = document.getElementById('x-axis-labels'); |
| | const xAxisContainer = document.getElementById('x-axis-container'); |
| | const scoreDisplay = document.getElementById('score-display'); |
| |
|
| | |
| | const gridSize = 8; |
| | const cellSize = 40; |
| |
|
| | |
| | const itemsToFind = [ |
| | { name: "a sparkling diamond", emoji: "π" }, { name: "a red apple", emoji: "π" }, |
| | { name: "a yummy pizza slice", emoji: "π" }, { name: "a fast rocket", emoji: "π" }, |
| | { name: "a cute puppy", emoji: "πΆ" }, { name: "a bright star", emoji: "β" }, |
| | { name: "a cool robot", emoji: "π€" }, { name: "a friendly ghost", emoji: "π»" }, |
| | { name: "a birthday cake", emoji: "π" }, { name: "a magical unicorn", emoji: "π¦" } |
| | ]; |
| | const totalItems = itemsToFind.length; |
| |
|
| | |
| | let targetX = -1, targetY = -1, currentItemIndex = 0, foundCurrent = false, score = 0; |
| |
|
| | |
| | function initializeGameArea() { |
| | gridContainer.innerHTML = ''; |
| | xAxisLabelsContainer.innerHTML = ''; |
| | yAxisLabelsContainer.innerHTML = ''; |
| | score = 0; |
| | currentItemIndex = 0; |
| | updateScoreDisplay(); |
| |
|
| | document.documentElement.style.setProperty('--cell-size', `${cellSize}px`); |
| |
|
| | const gridTotalSize = gridSize * cellSize; |
| | const yAxisWidth = 20; |
| | const yAxisMargin = 5; |
| |
|
| | |
| | gridContainer.style.width = `${gridTotalSize}px`; |
| | gridContainer.style.height = `${gridTotalSize}px`; |
| | gridContainer.style.display = 'grid'; |
| | gridContainer.style.gridTemplateColumns = `repeat(${gridSize}, ${cellSize}px)`; |
| | gridContainer.style.gridTemplateRows = `repeat(${gridSize}, ${cellSize}px)`; |
| |
|
| | |
| | yAxisLabelsContainer.style.height = `${gridTotalSize}px`; |
| | xAxisLabelsContainer.style.width = `${gridTotalSize}px`; |
| | xAxisContainer.style.width = `${yAxisWidth + yAxisMargin + gridTotalSize}px`; |
| | xAxisLabelsContainer.style.marginLeft = `${yAxisWidth + yAxisMargin}px`; |
| |
|
| | |
| | for (let y = 1; y <= gridSize; y++) { |
| | const label = document.createElement('div'); |
| | label.classList.add('axis-label', 'y-axis-label'); |
| | label.textContent = y; |
| | label.style.height = `${cellSize}px`; |
| | yAxisLabelsContainer.appendChild(label); |
| | } |
| |
|
| | |
| | for (let x = 1; x <= gridSize; x++) { |
| | const label = document.createElement('div'); |
| | label.classList.add('axis-label', 'x-axis-label'); |
| | label.textContent = x; |
| | label.style.width = `${cellSize}px`; |
| | xAxisLabelsContainer.appendChild(label); |
| | } |
| |
|
| | |
| | for (let y = gridSize; y >= 1; y--) { |
| | for (let x = 1; x <= gridSize; x++) { |
| | const cell = document.createElement('div'); |
| | cell.classList.add('grid-cell'); |
| | cell.dataset.x = x; cell.dataset.y = y; |
| | cell.style.width = `${cellSize}px`; cell.style.height = `${cellSize}px`; |
| | cell.addEventListener('click', handleCellClick); |
| | gridContainer.appendChild(cell); |
| | } |
| | } |
| | console.log(`Grid (${gridSize}x${gridSize}), Axes, and Score Initialized.`); |
| | } |
| |
|
| | |
| | function updateScoreDisplay() { |
| | scoreDisplay.textContent = `Score: ${score} / ${totalItems}`; |
| | } |
| |
|
| | |
| | function setNewTarget() { |
| | foundCurrent = false; |
| | if (currentItemIndex >= totalItems) { |
| | let finalMessage = `All done! Your final score: ${score} / ${totalItems}! π`; |
| | if (score === totalItems) finalMessage += " Perfect score! π₯³"; |
| | else if (score >= totalItems * 0.7) finalMessage += " Great job! π"; |
| | feedbackDisplay.textContent = finalMessage; |
| | feedbackDisplay.className = 'correct-feedback'; |
| | targetCoordsDisplay.textContent = "(β,β)"; |
| | itemNameDisplay.textContent = 'all the items'; |
| | return; |
| | } |
| | const currentItem = itemsToFind[currentItemIndex]; |
| | let newTargetFound = false, attempts = 0; |
| | const maxAttempts = gridSize * gridSize * 2; |
| | while (!newTargetFound && attempts < maxAttempts) { |
| | targetX = Math.floor(Math.random() * gridSize) + 1; |
| | targetY = Math.floor(Math.random() * gridSize) + 1; |
| | const potentialCell = gridContainer.querySelector(`.grid-cell[data-x="${targetX}"][data-y="${targetY}"]`); |
| | if (potentialCell && potentialCell.textContent.trim() === '') { newTargetFound = true; } |
| | attempts++; |
| | if(attempts >= maxAttempts){ |
| | let allFilled = true; |
| | gridContainer.querySelectorAll('.grid-cell').forEach(cell => { if(cell.textContent === '') allFilled = false; }); |
| | if(allFilled) { console.warn("Grid appears full!"); break; } |
| | else { attempts = 0; } |
| | } |
| | } |
| | if (!newTargetFound) { |
| | console.error("Could not find an empty cell!"); |
| | feedbackDisplay.textContent = "Uh oh, map is full! Refresh maybe?"; |
| | return; |
| | } |
| | itemNameDisplay.textContent = currentItem.name; |
| | targetCoordsDisplay.textContent = `(${targetX}, ${targetY})`; |
| | feedbackDisplay.textContent = `Where is ${currentItem.name}? (${currentItemIndex + 1}/${totalItems})`; |
| | feedbackDisplay.className = ''; |
| | document.querySelectorAll('.grid-cell').forEach(cell => { |
| | cell.classList.remove('just-found', 'incorrect'); |
| | }); |
| | console.log(`Round ${currentItemIndex + 1}: Find ${currentItem.name} at (${targetX}, ${targetY})`); |
| | } |
| |
|
| | |
| | function handleCellClick(event) { |
| | if (foundCurrent || currentItemIndex >= totalItems) return; |
| | const clickedCell = event.target; |
| | if (clickedCell.classList.contains('found-item')) return; |
| |
|
| | const clickedX = parseInt(clickedCell.dataset.x); |
| | const clickedY = parseInt(clickedCell.dataset.y); |
| | document.querySelectorAll('.grid-cell.incorrect').forEach(cell => { cell.classList.remove('incorrect'); }); |
| |
|
| | if (clickedX === targetX && clickedY === targetY) { |
| | foundCurrent = true; score++; updateScoreDisplay(); |
| | const currentItem = itemsToFind[currentItemIndex]; |
| | feedbackDisplay.textContent = `You found ${currentItem.name}! π`; |
| | feedbackDisplay.className = 'correct-feedback'; |
| | clickedCell.textContent = currentItem.emoji; |
| | clickedCell.classList.add('just-found'); |
| | setTimeout(() => { |
| | clickedCell.classList.remove('just-found'); |
| | clickedCell.classList.add('found-item'); |
| | }, 600); |
| | currentItemIndex++; |
| | setTimeout(setNewTarget, 1800); |
| | } else { |
| | feedbackDisplay.textContent = "Not quite! Try again. π€"; |
| | feedbackDisplay.className = 'incorrect-feedback'; |
| | clickedCell.classList.add('incorrect'); |
| | setTimeout(() => { |
| | if (clickedCell.classList.contains('incorrect')) { clickedCell.classList.remove('incorrect'); } |
| | }, 500); |
| | } |
| | } |
| |
|
| | |
| | initializeGameArea(); |
| | setNewTarget(); |
| |
|
| | }); |