// Legend of grid case const legend = { empty: 0, laser: 1, coloredLaser: 2, mirror: 3, door: 4, button: 5, wall: 6, demiWall: 7, target: 8, ligthLaser: 9, } // Grid test let level1 = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ] // Player position let playerX = 0; let playerY = 0; // Function to save initial orientation of mirrors let laserDirection = { dx: 0, dy: 0 }; let mirrorOrientations = {}; function initializeMirrorOrientations() { mirrorOrientations = {}; // Reset for (let y = 0; y < level1.length; y++) { for (let x = 0; x < level1[y].length; x++) { if (level1[y][x] === legend.mirror) { mirrorOrientations[`${y},${x}`] = 0; // Default angle } } } } // Function to print grid let mirrorCoordinates = []; function loadGrid() { const mapDiv = document.getElementById("map"); // Div with map in DOM mapDiv.innerHTML = ""; for (let y = 0; y < level1.length; y++) { const lign = document.createElement("div"); lign.classList.add("lign"); for (let x = 0; x < level1[y].length; x++) { const cell = document.createElement("div"); cell.classList.add("cell"); switch (level1[y][x]) { case legend.empty: cell.classList.add("empty"); break; case legend.laser: cell.classList.add("laser"); break; case legend.coloredLaser: cell.classList.add("colored-laser"); break; case legend.mirror: const currentAngle = mirrorOrientations[`${y},${x}`] || 0; const btnMirror = document.createElement("button"); btnMirror.classList.add("btn-mirror"); btnMirror.style.transform = `rotate(${currentAngle}deg)`; btnMirror.style.width = "100%"; cell.appendChild(btnMirror); cell.classList.add("mirror"); break; case legend.door: cell.classList.add("door"); break; case legend.button: cell.classList.add("button"); break; case legend.wall: cell.classList.add("wall"); break; case legend.demiWall: cell.classList.add("demi-wall"); break; case legend.target: cell.classList.add("target"); break; case legend.ligthLaser: cell.classList.add("light-laser"); if (laserDirection.dx === 0) { cell.classList.add("laser-vertical"); } else { cell.classList.add("laser-horizontal"); } break; } if (x === playerX && y === playerY) { cell.classList.add("player-cursor"); } lign.appendChild(cell); } mapDiv.appendChild(lign); } } loadGrid(); // Function to rotate mirror function rotateMirror(x, y) { const coordKey = `${y},${x}`; // See if it's a mirror if (level1[y][x] !== legend.mirror) { return }; let currentAngle = mirrorOrientations[coordKey] || 0; // Rotation currentAngle = (currentAngle + 45) % 360; // Save mirrorOrientations[coordKey] = currentAngle; // Print laser light traceLaser(true); } // Function to trace let isLevelFinished = false; function traceLaser() { // Reset light laser from previous trace for (let y = 0; y < level1.length; y++) { for (let x = 0; x < level1[y].length; x++) { if (level1[y][x] === legend.ligthLaser) { level1[y][x] = legend.empty; } } } let startLaserX; let startLaserY; // Search laser for (let y = 0; y < level1.length; y++) { for (let x = 0; x < level1[y].length; x++) { if (level1[y][x] === legend.laser) { startLaserX = x; startLaserY = y; laserDirection = { dx: 1, dy: 0 }; break; } } if (startLaserX !== undefined) break; } // If laser not found -> return if (startLaserX === undefined) { return; } let currentX = startLaserX; let currentY = startLaserY; let laserActive = true; const maxIterations = 1000; // Prevent infinite loops let iterations = 0; while (laserActive && iterations < maxIterations) { iterations++; currentX += laserDirection.dx; currentY += laserDirection.dy; // Out of bounds if (currentX < 0 || currentX >= level1[0].length || currentY < 0 || currentY >= level1.length) { laserActive = false; break; } const cellType = level1[currentY][currentX]; switch (cellType) { case legend.laser: case legend.coloredLaser: laserActive = false; break; case legend.empty: level1[currentY][currentX] = legend.ligthLaser; break; case legend.target: level1[currentY][currentX] = legend.ligthLaser; laserActive = false; isLevelFinished = true; break; case legend.mirror: const mirrorAngle = mirrorOrientations[`${currentY},${currentX}`] || 0; if (mirrorAngle === 0 || mirrorAngle === 180) { laserDirection.dy = -laserDirection.dy; } else { if (mirrorAngle === 90 || mirrorAngle === 270) { laserDirection.dx = -laserDirection.dx; } if (mirrorAngle === 45 || mirrorAngle === 225) { const tempDx = laserDirection.dx; laserDirection.dx = laserDirection.dy; laserDirection.dy = tempDx; } if (mirrorAngle === 135 || mirrorAngle === 315) { const tempDx = laserDirection.dx; laserDirection.dx = -laserDirection.dy; laserDirection.dy = -tempDx; } } break; case legend.wall: laserActive = false; break; case legend.demiWall: laserActive = false; break; case legend.door: laserActive = false; break; case legend.button: level1[currentY][currentX] = legend.ligthLaser; laserActive = false; break; default: level1[currentY][currentX] = legend.ligthLaser; break; } } loadGrid(); if (isLevelFinished) { finish(); } } traceLaser(); // If level finishh -> call this function function finish() { setTimeout(() => { alert("Réussi !"); }, 100); } // Get player inputs arrows, qwerty and azerty document.addEventListener("keydown", (e) => { // If level finish -> don't move if (isLevelFinished === true) { return; } switch (e.key) { case "ArrowUp": movePlayer(0, -1); break; case "w": movePlayer(0, -1); break; case "z": movePlayer(0, -1); break; case "ArrowDown": movePlayer(0, 1); break; case "s": movePlayer(0, 1); break; case "ArrowLeft": movePlayer(-1, 0); break; case "a": movePlayer(-1, 0); break; case "q": movePlayer(-1, 0); break; case "ArrowRight": movePlayer(1, 0); break; case "d": movePlayer(1, 0); break; case "Enter": rotateMirror(playerX, playerY); break; } }); // Player move function movePlayer(x, y) { const newX = playerX + x; const newY = playerY + y; if (newX < 0 || newX >= level1[0].length) { return }; if (newY < 0 || newY >= level1.length) { return }; playerX = newX; playerY = newY; loadGrid(); }