This Chat is read-only. Login to resume chatting.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Labyrinthe Interactif</title>
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
font-family: Arial, sans-serif;
background-color: #f0f0f0;
}
#maze-container {
position: relative;
width: 500px;
height: 500px;
border: 2px solid #333;
}
.cell {
width: 10px;
height: 10px;
border: 1px solid #ccc;
box-sizing: border-box;
}
.wall {
background-color: #333;
}
.path {
background-color: #fff;
}
.start {
background-color: #4caf50;
}
.end {
background-color: #f44336;
}
.solution {
background-color: #2196f3;
}
.current {
background-color: #ffeb3b;
}
button {
margin-top: 20px;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="maze-container"></div>
<button id="generate-btn">Générer un nouveau labyrinthe</button>
<button id="solve-btn">Résoudre le labyrinthe</button>
<script>
const size = 50;
const mazeContainer = document.getElementById('maze-container');
let maze = [];
let start = { x: 0, y: 0 };
let end = { x: size - 1, y: size - 1 };
let currentPos = { ...start };
function createMaze() {
maze = Array.from({ length: size }, () => Array(size).fill(1));
generateMaze(start.x, start.y);
maze[start.x][start.y] = 0;
maze[end.x][end.y] = 0;
renderMaze();
}
function generateMaze(x, y) {
const directions = [
{ x: 1, y: 0 },
{ x: -1, y: 0 },
{ x: 0, y: 1 },
{ x: 0, y: -1 }
];
shuffle(directions);
for (const dir of directions) {
const nx = x + dir.x * 2;
const ny = y + dir.y * 2;
if (nx >= 0 && ny >= 0 && nx < size && ny < size && maze[nx][ny] === 1) {
maze[nx][ny] = 0;
maze[x + dir.x][y + dir.y] = 0;
generateMaze(nx, ny);
}
}
}
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
function renderMaze() {
mazeContainer.innerHTML = '';
for (let x = 0; x < size; x++) {
for (let y = 0; y < size; y++) {
const cell = document.createElement('div');
cell.classList.add('cell', maze[x][y] === 1 ? 'wall' : 'path');
if (x === start.x && y === start.y) cell.classList.add('start');
if (x === end.x && y === end.y) cell.classList.add('end');
cell.style.left = `${y * 10}px`;
cell.style.top = `${x * 10}px`;
mazeContainer.appendChild(cell);
}
}
}
function solveMaze() {
const openSet = [{ ...start }];
const cameFrom = {};
const gScore = {};
const fScore = {};
for (let x = 0; x < size; x++) {
for (let y = 0; y < size; y++) {
gScore[`${x},${y}`] = Infinity;
fScore[`${x},${y}`] = Infinity;
}
}
gScore[`${start.x},${start.y}`] = 0;
fScore[`${start.x},${start.y}`] = heuristic(start, end);
while (openSet.length > 0) {
openSet.sort((a, b) => fScore[`${a.x},${a.y}`] - fScore[`${b.x},${b.y}`]);
const current = openSet.shift();
if (current.x === end.x && current.y === end.y) {
return reconstructPath(cameFrom, current);
}
const neighbors = getNeighbors(current);
for (const neighbor of neighbors) {
const tentativeGScore = gScore[`${current.x},${current.y}`] + 1;
if (tentativeGScore < gScore[`${neighbor.x},${neighbor.y}`]) {
cameFrom[`${neighbor.x},${neighbor.y}`] = current;
gScore[`${neighbor.x},${neighbor.y}`] = tentativeGScore;
fScore[`${neighbor.x},${neighbor.y}`] = tentativeGScore + heuristic(neighbor, end);
if (!openSet.some(node => node.x === neighbor.x && node.y === neighbor.y)) {
openSet.push(neighbor);
}
}
}
}
return [];
}
function heuristic(a, b) {
return Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
}
function getNeighbors(node) {
const neighbors = [];
const directions = [
{ x: 1, y: 0 },
{ x: -1, y: 0 },
{ x: 0, y: 1 },
{ x: 0, y: -1 }
];
for (const dir of directions) {
const nx = node.x + dir.x;
const ny = node.y + dir.y;
if (nx >= 0 && ny >= 0 && nx < size && ny < size && maze[nx][ny] === 0) {
neighbors.push({ x: nx, y: ny });
}
}
return neighbors;
}
function reconstructPath(cameFrom, current) {
const totalPath = [{ ...current }];
while (cameFrom[`${current.x},${current.y}`]) {
current = cameFrom[`${current.x},${current.y}`];
totalPath.unshift({ ...current });
}
return totalPath;
}
function highlightPath(path) {
path.forEach(({ x, y }) => {
const cell = mazeContainer.children[x * size + y];
cell.classList.add('solution');
});
}
function movePlayer(dx, dy) {
const nx = currentPos.x + dx;
const ny = currentPos.y + dy;
if (nx >= 0 && ny >= 0 && nx < size && ny < size && maze[nx][ny] === 0) {
const currentCell = mazeContainer.children[currentPos.x * size + currentPos.y];
currentCell.classList.remove('current');
currentPos.x = nx;
currentPos.y = ny;
const newCell = mazeContainer.children[currentPos.x * size + currentPos.y];
newCell.classList.add('current');
if (currentPos.x === end.x && currentPos.y === end.y) {
alert('Félicitations ! Vous avez atteint la sortie !');
}
}
}
document.getElementById('generate-btn').addEventListener('click', () => {
createMaze();
currentPos = { ...start };
mazeContainer.children[currentPos.x * size + currentPos.y].classList.add('current');
});
document.getElementById('solve-btn').addEventListener('click', () => {
const path = solveMaze();
highlightPath(path);
});
document.addEventListener('keydown', event => {
switch (event.key) {
case 'ArrowUp':
movePlayer(-1, 0);
break;
case 'ArrowDown':
movePlayer(1, 0);
break;
case 'ArrowLeft':
movePlayer(0, -1);
break;
case 'ArrowRight':
movePlayer(0, 1);
break;
}
});
createMaze();
mazeContainer.children[currentPos.x * size + currentPos.y].classList.add('current');
</script>
</body>
</html>