// ----------------------------------------------------------------------------------------------------------------- /** * Cette partie du code, vous n'avez pas besoin d'y toucher. Elle permet de gérer la grille et l'affichage des cellules */ class GridManager { ACTIVE_COLOR = 'black'; INACTIVE_COLOR = 'grey'; gridContainerId; gridSize; grid = []; constructor(gridSize, gridContainerId) { if (!gridSize || gridSize < 30) { throw new Error('The grid size must be at least 30'); } if (!gridContainerId) { throw new Error('gridContainerId must be set'); } this.gridSize = gridSize; this.gridContainerId = gridContainerId; this.createGrid(); } createGrid() { const container = document.getElementById(this.gridContainerId); for (let i = 0; i < this.gridSize; i++) { const row = document.createElement('div'); row.className = 'row'; const gridRow = []; for (let j = 0; j < this.gridSize; j++) { const cell = document.createElement('div'); cell.className = 'cell'; cell.style.backgroundColor = this.INACTIVE_COLOR; row.appendChild(cell); gridRow.push(cell); } container.appendChild(row); this.grid.push(gridRow); } } destroyGrid() { for (let x = 0; x < this.gridSize; x++) { for (let y = 0; y < this.gridSize; y++) { const node = this.grid[y][x]; node.parentNode.removeChild(node); } } const container = document.getElementById(this.gridContainerId); while (container.firstChild) { container.removeChild(container.lastChild); } this.grid = []; } setInitialState(initialState) { const coords = initialState.split(';').map(coord => coord.split(',')); coords.forEach((coord) => this.activeCell(+coord[0], +coord[1])); } isInGridRange(x, y) { return x >= 0 && x < this.gridSize && y >= 0 && y < this.gridSize; } isActiveCell(x, y) { return this.isInGridRange(x, y) && this.grid[y][x].style.backgroundColor === this.ACTIVE_COLOR; } activeCell(x, y) { if (!this.isInGridRange(x, y)) { return; } this.grid[y][x].style.backgroundColor = this.ACTIVE_COLOR; } deactiveCell(x, y) { if (!this.isInGridRange(x, y)) { return; } this.grid[y][x].style.backgroundColor = this.INACTIVE_COLOR; } getNumberActiveNeighbourCells(x, y) { const neighbours = [ [x-1, y-1], [x, y-1], [x+1, y-1], [x-1, y], [x+1, y], [x-1, y+1], [x, y+1], [x+1, y+1], ]; return neighbours.map(cell => this.isActiveCell(cell[0], cell[1])).filter(cell => cell === true).length; } logCurrentGridState() { const activeCells = []; for (let x = 0; x < this.gridSize; x++) { for (let y = 0; y < this.gridSize; y++) { if (this.isActiveCell(x, y)) { activeCells.push(`${x},${y}`); } } } console.log(activeCells.join(';')); } getCurrentGridState() { const activeCells = []; for (let x = 0; x < this.gridSize; x++) { for (let y = 0; y < this.gridSize; y++) { if (this.isActiveCell(x, y)) { activeCells.push(`${x},${y}`); } } } return activeCells.join(';'); } } // ----------------------------------------------------------------------------------------------------------------- const INITIAL_STATE = '11,1;12,1;10,2;9,3;9,4;9,5;10,6;11,7;12,7;2,4;1,5;2,5;18,28;17,28;19,27;20,26;20,25;20,24;19,23;18,22;17,22;27,25;28,24;27,24;11,28;12,28;10,27;9,26;9,25;9,24;10,23;11,22;12,22;2,25;1,24;2,24;18,1;17,1;19,2;20,3;20,4;20,5;19,6;18,7;17,7;27,4;28,5;27,5'; const GENERATION_INTERVAL = 1000; // 1 seconde const DIV_CONTAINER_ID = 'container'; const BTN_AUTOPLAY_ID = 'autoplay'; const BTN_NEXT_GEN_ID = 'next-gen'; const BTN_RESET_ID = 'reset'; const BTN_GRIDSIZE_ID = 'gridsize'; const BTN_SAVE_ID = 'save'; const BTN_LOAD_ID = 'load'; const GENERATION_VAL_ID = 'generation-value'; const GRID_SIZE_VAL_ID = 'grid-size-value'; function computeNextGeneration(gridManager, generation) { // incrémenter la valeur de la génération et l'afficher à côté de 'Génération numéro:' const nextGrid = []; for (let x = 0; x < gridManager.gridSize; x++) { const row = []; for (let y = 0; y < gridManager.gridSize; y++) { const isActive = gridManager.isActiveCell(x, y); const numberActiveNeighbourCells = gridManager.getNumberActiveNeighbourCells(x, y); if (!isActive) { row.push(numberActiveNeighbourCells === 3 ? true : false); } else { row.push(numberActiveNeighbourCells === 2 || numberActiveNeighbourCells === 3 ? true : false); } } nextGrid.push(row); } for (let x = 0; x < nextGrid.length; x++) { for (let y = 0; y < nextGrid[x].length; y++) { nextGrid[x][y] ? gridManager.activeCell(x,y) : gridManager.deactiveCell(x,y); } } generation++; document.getElementById(GENERATION_VAL_ID).textContent = generation; gridManager.logCurrentGridState(); return generation; } // Fonction principale du jeu function main() { let autoplayInterval; let gridSize = 30; let generation = 0; let generationInterval = GENERATION_INTERVAL; let gridManager = new GridManager(gridSize, DIV_CONTAINER_ID); gridManager.setInitialState(INITIAL_STATE); document.getElementById(GRID_SIZE_VAL_ID).textContent = gridSize; document.getElementById(GENERATION_VAL_ID).textContent = generation; document.getElementById(BTN_SAVE_ID).addEventListener('click', () => { if (gridManager) { gridState = gridManager.getCurrentGridState(); localStorage.setItem("gridState", gridState); localStorage.setItem("generation", generation); } }); document.getElementById(BTN_LOAD_ID).addEventListener('click', () => { if (gridManager) { gridState = localStorage.getItem("gridState"); if (gridState != null) { if (autoplayInterval) { clearInterval(autoplayInterval); autoplayInterval = null; } gridManager.destroyGrid(); gridManager = new GridManager(gridSize, DIV_CONTAINER_ID); gridManager.setInitialState(gridState); document.getElementById(GENERATION_VAL_ID).textContent = localStorage.getItem("generation"); } } }); // Lorsqu'un utilisateur clique sur 'Auto Play' document.getElementById(BTN_AUTOPLAY_ID).addEventListener('click', () => { if (autoplayInterval) { return; } autoplayInterval = setInterval(() => { generation = computeNextGeneration(gridManager, generation); }, generationInterval); }); // Lorsqu'un utilisateur clique sur 'Prochaine Génération' document.getElementById(BTN_NEXT_GEN_ID).addEventListener('click', () => { if (autoplayInterval) { clearInterval(autoplayInterval); autoplayInterval = null; } generation = computeNextGeneration(gridManager, generation); }); document.getElementById(BTN_RESET_ID).addEventListener('click', () => { if (autoplayInterval) { clearInterval(autoplayInterval); autoplayInterval = null; } generation = 0; document.getElementById(GENERATION_VAL_ID).textContent = generation; gridManager.destroyGrid(); gridManager = new GridManager(gridSize, DIV_CONTAINER_ID); gridManager.setInitialState(INITIAL_STATE); }); document.getElementById(BTN_GRIDSIZE_ID).addEventListener('click', () => { let new_size = prompt("Nouvelle taille :"); if (new_size != null) { let new_size_int = parseInt(new_size); if (new_size_int != NaN && new_size_int >= 30) { gridSize = new_size_int; document.getElementById(GRID_SIZE_VAL_ID).textContent = new_size_int; document.getElementById(BTN_RESET_ID).click(); } } }); document.getElementById("x1").addEventListener('click', () => { generationInterval = GENERATION_INTERVAL; if (autoplayInterval) { clearInterval(autoplayInterval); autoplayInterval = null; document.getElementById(BTN_AUTOPLAY_ID).click(); } }); document.getElementById("x2").addEventListener('click', () => { generationInterval = GENERATION_INTERVAL / 2; if (autoplayInterval) { clearInterval(autoplayInterval); autoplayInterval = null; document.getElementById(BTN_AUTOPLAY_ID).click(); } }); document.getElementById("x10").addEventListener('click', () => { generationInterval = GENERATION_INTERVAL / 10; if (autoplayInterval) { clearInterval(autoplayInterval); autoplayInterval = null; document.getElementById(BTN_AUTOPLAY_ID).click(); } }); document.getElementById("x100").addEventListener('click', () => { generationInterval = GENERATION_INTERVAL / 100; if (autoplayInterval) { clearInterval(autoplayInterval); autoplayInterval = null; document.getElementById(BTN_AUTOPLAY_ID).click(); } }); } // Le jeu est démarré ici main();