class Game { #colorsBank = ['black','silver','gray','maroon','red','purple','fuchsia','green','lime','olive','yellow','navy','blue','teal','aqua']; constructor(nbTubes, tubeLevel) { this.tubes = []; this.selectedTube = null; for (let i = 0; i < nbTubes; i++) { this.tubes.push(new Tube(tubeLevel)); } this.initializeColorTubes(tubeLevel); } /* The goal is to have each tube filled with its own color. Thus, there is (tubes minus one) different colors divided in (tubeLevel) layers mixed in the tubes. One tube is empty to allow movement. */ initializeColorTubes(tubeLevel) { let nbColors = this.tubes.length - 1; let allColors = []; for (let coloridx = 0; coloridx < nbColors; coloridx++) { for (let times = 0; times < tubeLevel; times++) { allColors.push(this.#colorsBank[coloridx]); } } for (let i = allColors.length - 1; i > 0; i--) { let j = Math.floor(Math.random() * (i + 1)); let temp = allColors[i]; allColors[i] = allColors[j]; allColors[j] = temp; } for (let index = 0; index < allColors.length; index++) { this.tubes[Math.floor(index/tubeLevel)].addColor(allColors[index]); } } selectTube(tubeId) { let newSelectedTube = this.tubes[tubeId]; if (this.selectedTube == null && newSelectedTube.isEmpty()) return; if(this.selectedTube == null && !newSelectedTube.isEmpty()) { this.selectedTube = newSelectedTube; } else if (this.selectedTube == newSelectedTube) { this.selectedTube = null; } else if (newSelectedTube.isEmpty() || this.selectedTube.peekTopColor() == newSelectedTube.peekTopColor()) { this.pourColorInto(this.selectedTube, newSelectedTube); } } pourColorInto(sourceTube, targetTube) { if (sourceTube.isEmpty()) return; let pouringColor = sourceTube.peekTopColor(); while (sourceTube.peekTopColor() == pouringColor && !targetTube.isFull()) { targetTube.addColor(sourceTube.removeColorLayer()); } } }