//===== Constructor const Controls = function() { this.names = {}; // this.starts = []; // this.timers = {}; // // "Local" and "Global" messages document.addEventListener('L-conn-error', this.msgConnectionError.bind(this)); document.addEventListener('L-stack', this.msgStack.bind(this)); // document.addEventListener('L-reset', this.msgReset.bind(this)); // document.addEventListener('L-undo', this.msgUndo.bind(this)); // document.addEventListener('G-guess', this.msgGuess.bind(this)); document.addEventListener('G-connected', this.msgCountdown.bind(this)); document.addEventListener('G-countdown', this.msgConnected.bind(this)); document.addEventListener('G-players', this.msgPlayers.bind(this)); // document.addEventListener('G-skip', this.msgSkip.bind(this)); // document.addEventListener('G-start', this.msgStart.bind(this)); document.addEventListener('G-state', this.msgState.bind(this)); // document.addEventListener('G-stop', this.msgStop.bind(this)); // Click handlers // document.getElementById('controls-reset').addEventListener('click', this.onClickReset.bind(this)); // document.getElementById('controls-robots').addEventListener('click', this.onClickRobots.bind(this)); // document.getElementById('controls-skip').addEventListener('click', this.onClickSkip.bind(this)); // document.getElementById('controls-start').addEventListener('click', this.onClickStart.bind(this)); // document.getElementById('controls-stop').addEventListener('click', this.onClickStop.bind(this)); // document.getElementById('controls-submit').addEventListener('click', this.onClickSubmit.bind(this)); // document.getElementById('controls-undo').addEventListener('click', this.onClickUndo.bind(this)); // document.getElementById('controls-walls').addEventListener('click', this.onClickWalls.bind(this)); this.setState('CONNECTING'); } //===== Countdown // Controls.prototype.countdownStart = function(seconds) { // clearTimeout(this.timers.countdown); // this.timers.countdown = this.countdownTick.bind(this); // const countdown = document.getElementById('controls-countdown'); // countdown.dataset.tick = seconds; // this.countdownTick(); // }; // Controls.prototype.countdownTick = function() { // const countdown = document.getElementById('controls-countdown'); // const tick = countdown.dataset.tick * 1; // countdown.dataset.tick = tick - 1; // const s = (tick !== 1) ? 's' : ''; // countdown.innerHTML = `${tick} second${s}!`; // if (tick === 0) { // this.countdownComplete(); // return; // } // this.timers.countdown = setTimeout(this.countdownTick.bind(this), 1000); // }; // Controls.prototype.countdownComplete = function() { // document.getElementById('controls-countdown').dataset.tick = 0; // }; //===== UI // Controls.prototype.showWaiting = function() { // document.getElementById('controls-start').parentNode.style.display = ''; // document.getElementById('controls-walls').parentNode.style.display = ''; // document.getElementById('controls-robots').parentNode.style.display = ''; // document.getElementById('controls-stop').parentNode.style.display = 'none'; // // document.getElementById('controls-moves-reset').parentNode.style.display = 'none'; // document.getElementById('controls-guesses').style.display = 'none'; // document.getElementById('controls-panic').style.display = 'none'; // }; // Controls.prototype.showPanic = function() { // this.showGuessing(); // document.getElementById('controls-panic').style.display = ''; // }; Controls.prototype.setState = function(state) { const blocks = [ 'controls-connection', 'controls-countdown', 'controls-moves', 'controls-options', 'controls-players', 'controls-solution', ]; blocks.forEach(id => document.getElementById(id).style.display = 'none'); // IDs to show for each state. const STATE = { CONNECTING: ['controls-connection'], PLAY: ['controls-players', 'controls-moves', 'controls-options'], COUNTDOWN: ['controls-players', 'controls-moves', 'controls-countdown'], SOLUTION: ['controls-players', 'controls-solution'] }; (STATE[state] || []).forEach(id => document.getElementById(id).style.display = 'block'); }; //===== Message handlers Controls.prototype.msgConnected = function() { }; Controls.prototype.msgConnectionError = function() { this.setState('CONNECTING'); }; Controls.prototype.msgCountdown = function(evt) { }; Controls.prototype.msgStack = function(evt) { const robots = evt.detail.reduce((acc, { id }) => acc.has(id) ? acc : acc.add(id), new Set()); const moveCount = evt.detail.length - robots.size; // document.getElementById('controls-moves').innerHTML = moveCount; // document.getElementById('controls-undo').style.display = moveCount > 0 ? 'block' : 'none'; }; Controls.prototype.msgPlayers = function(evt) { this.names = evt.detail.body; const container = document.getElementById('controls-players'); container.querySelectorAll('.controls-player').forEach(el => { container.removeChild(el); }); const keys = Object.keys(this.names); if (keys.length > 1) { keys.forEach(connectionId => { const n = document.createElement('div'); n.innerHTML = this.names[connectionId]; n.className = 'controls-player'; container.appendChild(n) }); } const msg = container.querySelector('.controls-message'); msg.innerHTML = (keys.length > 1 ? '' : 'Nobody is in the game yet.'); msg.style.display = (keys.length > 1 ? 'none' : 'block'); }; Controls.prototype.msgSkip = function() { // this.coundownComplete(); }; Controls.prototype.msgState = function(evt) { // this.setState(evt.detail.body); this.setState('SOLUTION') }; Controls.prototype.msgStop = function() { // } //===== Click handlers Controls.prototype.dispatch = function(evt, data) { const e = (data ? new CustomEvent(evt, { detail: data }) : new Event(evt)); document.dispatchEvent(e); }; Controls.prototype.onClickReset = function() { this.dispatch('L-reset'); }; Controls.prototype.onClickRobots = function() { this.dispatch('L-robots'); }; Controls.prototype.onClickSkip = function() { this.dispatch('L-skip'); }; Controls.prototype.onClickStart = function() { this.dispatch('L-start'); }; Controls.prototype.onClickStop = function() { this.dispatch('L-stop'); }; Controls.prototype.onClickSubmit = function() { this.dispatch('L-submit'); }; Controls.prototype.onClickUndo = function() { this.dispatch('L-undo'); }; Controls.prototype.onClickWalls = function() { this.dispatch('L-walls'); }; //===== THE TRASH BIN OF HISTORY // Controls.prototype.msgRobots = function(evt) { // this.starts = []; // this.moves = []; // evt.detail.body.forEach(({ id, i, j}) => { // this.starts.push({ id, i, j }); // this.moves.push({ id, i, j }); // }); // }; // Controls.prototype.msgGuess = function(evt) { // const blurbs = [ " has a solution: ", " can do it in ", " says, maybe ", " wagers ", // " reckons ", " is pretty sure it's ", ", confidently: ", " wants it to be ", // " says ", " hazards ", " guesses ", " thinks it might be "]; // const blurb = blurbs[Math.floor(Math.random() * blurbs.length)]; // const msg = evt.detail; // const guess = msg.guess; // this.currentWinningGuess = guess; // document.getElementById('controls-panic').querySelector('.controls-alert-urgent').innerHTML = (`${this.names[msg.id]}${blurb}${guess} moves.`); // this.showPanic(); // this.countdownStart(5); // } // Controls.prototype.msgReset = function() { // // Broadcast starting locations. // this.moves = []; // this.starts.forEach(move => { // const evtMove = new CustomEvent('L-move', { detail: move }); // document.dispatchEvent(evtMove); // }); // }; // Controls.prototype.msgUndo = function(evt) { // if (this.moves.length <= this.starts.length) { // return; // } // const { id } = this.moves.pop(); // const indexOfPreviousMove = this.moves.reduce((acc, v, i) => (v.id === id ? i : acc), -1); // const previousMove = this.moves.splice(indexOfPreviousMove, 1); // const evtMove = new CustomEvent('L-move', { detail: previousMove[0] }); // document.dispatchEvent(evtMove); // }; // Controls.prototype.msgAttempt = function() { // alert("Ready for winning attempt!"); // };