|
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(); |
|
|
|
}); |