class Controller { #game; #drawer; #colorsBank = ['black','silver','gray','maroon','red','purple','fuchsia','green','lime','olive','yellow','navy','blue','teal','aqua']; #historyHandler; constructor() { this.initializeGame(); } drawer() { return this.#drawer } initializeGame() { let params = this.gatherMenuValues(); this.#game = new Game(params.TUBESNUMBERS, params.TUBESLEVELS); this.#drawer = new Drawer(params.PADDING, params.SCALE, this.#game); this.#historyHandler = new HistoryHandler(); this.ui = new UI(800, 600); this.lastTime = millis(); this.initializeColorTubes(params.TUBESLEVELS - 1); this.needUpdate = true; } gatherMenuValues() { let inputTubesNumbers = parseInt(document.getElementById("tbNumber").value); let inputTubesLevels = parseInt(document.getElementById("tbLevel").value); let inputScale = parseInt(document.getElementById("scale").value); let inputPadding = parseInt(document.getElementById("padding").value); return { TUBESNUMBERS: inputTubesNumbers, TUBESLEVELS: inputTubesLevels, SCALE: inputScale, PADDING: inputPadding }; } initializeColorTubes(LayersPerTube) { let nbTubes = this.#game.tubesNumber() - 1; let allColors = []; for (let i = 0; i < nbTubes; i++) { let coloridx = i % this.#colorsBank.length; for (let times = 0; times < LayersPerTube; times++) { allColors.push(this.#colorsBank[coloridx]); } } for (let index = allColors.length - 1; index >= 0; index--) { let randomIndex = Math.floor(Math.random() * (index + 1)); let tubeIndex = Math.floor(index / LayersPerTube); this.#game.tubeAt(tubeIndex).addColorLayer(allColors[randomIndex]); allColors[randomIndex] = allColors[index]; } } clickTube(tubeIndex) { let _clickedTube = this.#game.tubeAt(tubeIndex); let _selectedTube = this.#game.selectedTube(); if (_clickedTube == null) return; if (_clickedTube == _selectedTube) { this.#drawer.removeSelectedEffect(this.#game.selectedTubeIndex()); this.#game.unselectTube(); } else if (this.canPourInto(_selectedTube, _clickedTube)) { this.pourColorInto(_selectedTube, _clickedTube); this.#drawer.removeSelectedEffect(this.#game.selectedTubeIndex()); this.#game.unselectTube(); } else if (!_clickedTube.isEmpty()) { if (_selectedTube != null) this.#drawer.removeSelectedEffect(this.#game.selectedTubeIndex()); this.#drawer.applySelectedEffect(tubeIndex); this.#game.selectTubeAt(tubeIndex); } } canPourInto(sourceTube, targetTube) { return sourceTube != null && targetTube != null && sourceTube != targetTube && (targetTube.isEmpty() || sourceTube.peekTopColor() == targetTube.peekTopColor()) && !targetTube.isFull(); } pourColorInto(sourceTube, targetTube) { let times = 0; do { targetTube.addColorLayer(sourceTube.removeColorLayer()); times++; } while (this.canPourInto(sourceTube, targetTube) && !targetTube.isComplete()); this.#historyHandler.log(sourceTube, targetTube, times); //this.checkTubeCompletion(sourceTube); //this.checkTubeCompletion(targetTube); } checkTubeCompletion(tube) { if (tube.isComplete()) { //this.#game.removeTube(tube); this.checkGameCompletion(); } } checkGameCompletion() { if (this.#game.tubesNumber() == 1 && this.#game.tubeAt(0).isEmpty()) { this.#game.clean(); } } undoPreviousAction() { this.#historyHandler.restore(); } mousePressed(e) { let clickedTubeId = this.#drawer.getTubeIdAt(mouseX, mouseY); this.clickTube(clickedTubeId); this.needUpdate = true; } runLoop() { let timeDelta = millis() - this.lastTime; // peut-ĂȘtre pas nĂ©cessaire de limiter le framerate if (timeDelta < 1000 / 60) return; this.lastTime = millis(); const steps = [ (this.needUpdate || this.#game.isCompleted) && this.drawGame, this.#game.isComplete() && this.drawUI ] steps.forEach(step => step && step.call(this)); } drawGame() { this.#drawer.draw(); } drawUI() { this.ui.drawWinView(); } }