Path Recall Game

Level: 1 | Score: 0
import random import asyncio from js import document CELL_SIZE = 80 GRID_SIZE = 5 LEVEL = 1 score = 0 path = [] showing = True def update_stats(): stats = document.getElementById("stats") stats.innerText = f"Level: {LEVEL} | Score: {score}" async def reveal_sequence(): global showing showing = True for r, c in path: cell = document.getElementById(f"c-{r}-{c}") cell.classList.add('show') await asyncio.sleep(1) cell.classList.remove('show') showing = False def create_path(): global path start = (random.randint(0, GRID_SIZE-1), random.randint(0, GRID_SIZE-1)) path = [start] dirs = [(1,0),(0,1),(-1,0),(0,-1)] for _ in range(LEVEL-1): x, y = path[-1] valids = [(dx,dy) for dx,dy in dirs if 0 <= x+dx < GRID_SIZE and 0 <= y+dy < GRID_SIZE] path.append((x+random.choice(valids)[0], y+random.choice(valids)[1])) async def start_level(): create_path() update_stats() await reveal_sequence() async def handle_click(evt): global score, LEVEL if showing: return elem = evt.target r, c = map(int, elem.id.split('-')[1:]) # Determine next expected index clicked = len([cell for cell in path if document.getElementById(f"c-{cell[0]}-{cell[1]}").classList.contains('correct')]) expected = path[clicked] if (r, c) == expected: elem.classList.add('correct') score += 1 update_stats() if score % LEVEL == 0: LEVEL += 1 await start_level() else: # Game over: show full path briefly for cell in document.getElementsByClassName('cell'): cell.classList.add('show') score, LEVEL = 0, 1 update_stats() await asyncio.sleep(2) for cell in document.getElementsByClassName('cell'): cell.classList.remove('show','correct') await start_level() # Build the grid grid = document.getElementById('game') for r in range(GRID_SIZE): for c in range(GRID_SIZE): cell = document.createElement('div') cell.id = f"c-{r}-{c}" cell.className = 'cell' cell.addEventListener('click', lambda e: asyncio.ensure_future(handle_click(e))) grid.appendChild(cell) # Launch the first level asyncio.ensure_future(start_level())