WIM/WIM4.1/tp/tp1/ex1/script.js

320 lines
6.4 KiB
JavaScript
Raw Permalink Normal View History

2022-04-08 17:31:34 +02:00
const ANTUP = 0
const ANTRIGHT = 1
const ANTDOWN = 2
const ANTLEFT = 3
class Ant {
x = 0
y = 0
direction = ANTRIGHT
moveForward(width, height) {
switch(this.direction) {
case ANTUP : {
this.y = (this.y - 1 +height)%height
break
}
case ANTLEFT : {
this.x = (this.x - 1 +width)%width
break
}
case ANTRIGHT : {
this.x = (this.x + 1 +width)%width
break
}
case ANTDOWN : {
this.y = (this.y + 1 +height)%height
break
}
}
}
rotateRight() {
switch(this.direction) {
case ANTUP : {
this.direction = ANTRIGHT
break
}
case ANTLEFT : {
this.direction = ANTUP
break
}
case ANTRIGHT : {
this.direction = ANTDOWN
break
}
case ANTDOWN : {
this.direction = ANTLEFT
break
}
}
}
rotateLeft() {
switch(this.direction) {
case ANTUP : {
this.direction = ANTLEFT
break
}
case ANTLEFT : {
this.direction = ANTDOWN
break
}
case ANTRIGHT : {
this.direction = ANTUP
break
}
case ANTDOWN : {
this.direction = ANTRIGHT
break
}
}
}
}
class GridManager {
ACTIVE_COLOR = 'black';
INACTIVE_COLOR = 'white';
gridContainerId;
gridSize;
grid = [];
ant; // la fourmi
constructor(gridSize, gridContainerId,ant) {
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.ant = ant
this.ant.x = this.ant.y = gridSize/2
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;
}
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(';'));
}
}
// -----------------------------------------------------------------------------------------------------------------
const INITIAL_STATE = ''
const STEP_INTERVAL = 5
const DIV_CONTAINER_ID = 'container'
const BTN_AUTOPLAY_ID = 'autoplay'
const BTN_NEXT_MOVE_ID = 'next-move'
const MOVE_VAL_ID = 'move-value'
const GRID_SIZE_VAL_ID = 'grid-size-value'
const BTN_PLUS_100_ID = 'plus-100'
const BTN_RESTART = "restart"
const BTN_NEW_TAILLE = "new_taille"
function computeNextPosition(gridManager)
{
// TODO
let ant = gridManager.ant // fourmi
ant.moveForward(gridManager.gridSize, gridManager.gridSize) // avance la fourmi
if(gridManager.isActiveCell(ant.x, ant.y)) { // si la case est noire
gridManager.deactiveCell(ant.x, ant.y) // met la case blanche
ant.rotateLeft() // tourne à gauche
}
else{
gridManager.activeCell(ant.x, ant.y) // met la case noir
ant.rotateRight() // tourne à droite
}
document.getElementById(MOVE_VAL_ID).innerText++
}
// Fonction principale de la simulation
function main() {
let autoplayInterval
let gridSize = 60
let generation = 0
let nbMove = 0
let ant = new Ant()
let gridManager = new GridManager(gridSize, DIV_CONTAINER_ID,ant)
gridManager.setInitialState(INITIAL_STATE);
document.getElementById(MOVE_VAL_ID).innerText = 0
// Lorsqu'un utilisateur clique sur 'Auto Play'
document.getElementById(BTN_AUTOPLAY_ID).addEventListener('click', () => {
if (autoplayInterval) {
clearInterval(autoplayInterval)
autoplayInterval = false
return
}
autoplayInterval = setInterval(() => {
computeNextPosition(gridManager);
}, STEP_INTERVAL);
})
// Lorsqu'un utilisateur clique sur 'Next'
document.getElementById(BTN_NEXT_MOVE_ID).addEventListener('click', () => {
if (autoplayInterval) {
clearInterval(autoplayInterval)
autoplayInterval = false
}
computeNextPosition(gridManager)
})
// Lorsqu'un utilisateur clique sur 'Next'
document.getElementById(BTN_PLUS_100_ID).addEventListener('click', () => {
if (autoplayInterval) {
clearInterval(autoplayInterval)
autoplayInterval = false
}
for(let i=0; i<100; i++) {
computeNextPosition(gridManager)
}
})
// Lorsqu'un utilisateur clique sur 'Next'
document.getElementById(BTN_RESTART).addEventListener('click', () => {
if (autoplayInterval) {
clearInterval(autoplayInterval)
autoplayInterval = false
}
gridManager.destroyGrid()
gridManager.createGrid()
gridManager.setInitialState(INITIAL_STATE)
document.getElementById(MOVE_VAL_ID).innerText = 0
})
// Lorsqu'un utilisateur clique sur 'Next'
document.getElementById(BTN_NEW_TAILLE).addEventListener('click', () => {
if (autoplayInterval) {
clearInterval(autoplayInterval)
autoplayInterval = false
}
let taille = prompt("Veuillez renseigner une nouvelle taille", gridManager.gridSize)
gridManager.destroyGrid()
gridManager.gridSize = taille
gridManager.createGrid()
gridManager.setInitialState(INITIAL_STATE)
document.getElementById(MOVE_VAL_ID).innerText = 0
})
}
// La simulation est démarrée ici
main()