diff --git a/README.txt b/README.txt index b4ca448..dbc0e69 100644 --- a/README.txt +++ b/README.txt @@ -10,11 +10,9 @@ Any movement, including initial locations, is represented by pushing or popping A victory state can be stored by taking a snapshot of the current stack. ## TODO -- be able to undo in a move sequence - robot shadow starting spot - robot icons with personality add credit to readmee - countdown skip -- reset - restore state on join - win declare/add/remove diff --git a/client/controls.js b/client/controls.js index 1b098e6..745674a 100644 --- a/client/controls.js +++ b/client/controls.js @@ -1,36 +1,34 @@ // //===== Constructor const Controls = function() { -// this.moves = []; -// this.names = {}; + this.names = {}; // this.starts = []; // this.timers = {}; // // "Local" and "Global" messages // document.addEventListener('L-connected', this.msgConnected.bind(this)); -// document.addEventListener('L-move', this.msgMove.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-attempt', this.msgAttempt.bind(this)); // document.addEventListener('G-guess', this.msgGuess.bind(this)); -// document.addEventListener('G-players', this.msgPlayers.bind(this)); -// document.addEventListener('G-robots', this.msgRobots.bind(this)); -// document.addEventListener('G-skip', this.msgSkip.bind(this)); -// document.addEventListener('G-start', this.msgStart.bind(this)); -// document.addEventListener('G-stop', this.msgStop.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-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-undo').addEventListener('click', this.onClickUndo.bind(this)); -// document.getElementById('controls-walls').addEventListener('click', this.onClickWalls.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-undo').addEventListener('click', this.onClickUndo.bind(this)); + document.getElementById('controls-walls').addEventListener('click', this.onClickWalls.bind(this)); } -// //===== UI +//===== Countdown // Controls.prototype.countdownStart = function(seconds) { // clearTimeout(this.timers.countdown); @@ -62,6 +60,7 @@ const Controls = 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 = ''; @@ -78,36 +77,12 @@ const Controls = function() { // document.getElementById('controls-panic').style.display = ''; // }; -// Controls.prototype.updateMoves = function() { -// // Initial robot placement is first move, to allow undo, but doesn't count as a move. -// const moves = this.moves.length - this.starts.length; - -// document.getElementById('controls-moves').innerHTML = moves; -// document.getElementById('controls-undo').style.display = moves > 0 ? 'block' : 'none'; -// }; - // //===== Message handlers // Controls.prototype.msgAttempt = function() { // alert("Ready for winning attempt!"); // }; -// 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.msgConnected = function() { // this.showWaiting(); // }; @@ -126,44 +101,46 @@ const Controls = function() { // document.dispatchEvent(evtMove); // }; -// Controls.prototype.msgMove = function(evt) { -// this.moves.push(evt.detail); -// this.updateMoves(); -// }; - -// Controls.prototype.msgPlayers = function(evt) { -// const container = document.getElementById('controls-players'); -// const names = evt.detail.body; -// const keys = Object.keys(names); +Controls.prototype.msgStack = function(evt) { + const moveCount = evt.detail.length; -// if (keys.length > 0) { -// const nobody = document.getElementById('controls-players-nobody'); -// nobody && nobody.parentNode.removeChild(nobody); -// } - -// keys.forEach(connectionId => { -// const id = `player-${connectionId}`; - -// if (document.getElementById(id)) { -// return; -// } - -// const n = document.createElement('div'); -// n.id = id; -// n.innerHTML = names[connectionId]; -// n.className = 'controls-player'; -// container.appendChild(n) -// }); + document.getElementById('controls-moves').innerHTML = moveCount; + document.getElementById('controls-undo').style.display = moveCount > 0 ? 'block' : 'none'; +}; -// this.names = names; +Controls.prototype.msgPlayers = function(evt) { + const container = document.getElementById('controls-players'); + const names = evt.detail.body; + const keys = Object.keys(names); -// container.querySelectorAll('.controls-player').forEach(el => { -// const id = el.id.split('player-').pop(); -// if (!this.names[id]) { -// container.removeChild(el); -// } -// }); -// }; + if (keys.length > 0) { + const nobody = document.getElementById('controls-players-nobody'); + nobody && nobody.parentNode.removeChild(nobody); + } + + keys.forEach(connectionId => { + const id = `player-${connectionId}`; + + if (document.getElementById(id)) { + return; + } + + const n = document.createElement('div'); + n.id = id; + n.innerHTML = names[connectionId]; + n.className = 'controls-player'; + container.appendChild(n) + }); + + this.names = names; + + container.querySelectorAll('.controls-player').forEach(el => { + const id = el.id.split('player-').pop(); + if (!this.names[id]) { + container.removeChild(el); + } + }); +}; // Controls.prototype.msgReset = function() { // // Broadcast starting locations. @@ -174,77 +151,76 @@ const Controls = function() { // }); // }; -// Controls.prototype.msgRobots = function(evt) { -// this.starts = []; -// this.moves = []; +Controls.prototype.msgSkip = function() { + // this.coundownComplete(); +}; -// evt.detail.body.forEach(({ id, i, j}) => { -// this.starts.push({ id, i, j }); -// this.moves.push({ id, i, j }); -// }); -// }; +Controls.prototype.msgStart = function() { + // +}; -// Controls.prototype.msgSkip = function() { -// this.coundownComplete(); -// }; +Controls.prototype.msgStop = function() { + // +} -// Controls.prototype.msgStart = function() { -// // Trim moves array to last position of each robot. -// // Set robots array to these new initial positions. -// const mostRecentPositions = {}; +//===== Click handlers -// this.moves.forEach(({ id, i, j }) => { -// mostRecentPositions[id] = { id, i, j }; -// }); +Controls.prototype.dispatch = function(evt, data) { + const e = (data ? new CustomEvent(evt, { detail: data }) : new Event(evt)); + document.dispatchEvent(e); +}; -// this.starts = []; -// Object.values(mostRecentPositions).forEach(robot => { -// this.starts.push(robot); -// }); +Controls.prototype.onClickReset = function() { + this.dispatch('L-reset'); +}; -// // Broadcast starting locations. -// this.moves = []; -// this.starts.forEach(move => { -// const evtMove = new CustomEvent('L-move', { detail: move }); -// document.dispatchEvent(evtMove); -// }); -// }; +Controls.prototype.onClickRobots = function() { + this.dispatch('L-robots'); +}; -// Controls.prototype.msgStop = function() { -// // this.showWaiting(); -// } +Controls.prototype.onClickSkip = function() { + this.dispatch('L-skip'); +}; -// //===== Click handlers +Controls.prototype.onClickStart = function() { + this.dispatch('L-start'); +}; -// Controls.prototype.dispatch = function(evt, data) { -// const e = (data ? new CustomEvent(evt, { detail: data }) : new Event(evt)); -// document.dispatchEvent(e); -// }; +Controls.prototype.onClickStop = function() { + this.dispatch('L-stop'); +}; -// Controls.prototype.onClickReset = function() { -// this.dispatch('L-reset'); -// }; +Controls.prototype.onClickUndo = function() { + this.dispatch('L-undo'); +}; -// Controls.prototype.onClickRobots = function() { -// this.dispatch('L-robots'); -// }; +Controls.prototype.onClickWalls = function() { + this.dispatch('L-walls'); +}; -// Controls.prototype.onClickSkip = function() { -// this.dispatch('L-skip'); -// }; +//===== THE TRASH BIN OF HISTORY +// Controls.prototype.msgRobots = function(evt) { +// this.starts = []; +// this.moves = []; -// Controls.prototype.onClickStart = function() { -// this.dispatch('L-start'); +// evt.detail.body.forEach(({ id, i, j}) => { +// this.starts.push({ id, i, j }); +// this.moves.push({ id, i, j }); +// }); // }; -// Controls.prototype.onClickStop = function() { -// this.dispatch('L-stop'); -// }; +// 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)]; -// Controls.prototype.onClickUndo = function() { -// this.dispatch('L-undo'); -// }; +// const msg = evt.detail; +// const guess = msg.guess; -// Controls.prototype.onClickWalls = function() { -// this.dispatch('L-walls'); -// }; +// this.currentWinningGuess = guess; + +// document.getElementById('controls-panic').querySelector('.controls-alert-urgent').innerHTML = (`${this.names[msg.id]}${blurb}${guess} moves.`); +// this.showPanic(); +// this.countdownStart(5); +// } \ No newline at end of file diff --git a/client/stack.js b/client/stack.js index 247596f..a295de2 100644 --- a/client/stack.js +++ b/client/stack.js @@ -5,9 +5,23 @@ const Stack = function() { this.moves = []; document.addEventListener('L-arrow', this.msgArrow.bind(this)); + document.addEventListener('L-undo', this.msgUndo.bind(this)); + document.addEventListener('L-reset', this.msgReset.bind(this)); document.addEventListener('G-robots', this.msgRobots.bind(this)); }; +Stack.prototype.getInitialPositions = function() { + const moves = this.moves.reduce((acc, move) => { + if (!acc[move.id]) { + acc[move.id] = move; + } + + return acc; + }, {}); + + return Object.values(moves); +}; + Stack.prototype.msgRobots = function(evt) { this.moves = evt.detail.body.map(({ id, i, j }) => ({ id, i, j })); @@ -22,10 +36,18 @@ Stack.prototype.msgArrow = function(evt) { document.dispatchEvent(evtStack); }; +Stack.prototype.msgReset = function() { + this.moves = this.getInitialPositions(); + + console.log(this.moves) + + const evtStack = new CustomEvent('L-stack', { detail: this.moves }); + document.dispatchEvent(evtStack); +}; + +Stack.prototype.msgUndo = function() { + this.moves.pop(); -// reset destroys stack -// undo decrements from stack -// store chops stack -// moves is stack length -// replay shares stack -// starting spot is present in stack \ No newline at end of file + const evtStack = new CustomEvent('L-stack', { detail: this.moves }); + document.dispatchEvent(evtStack); +}; \ No newline at end of file