From 82f96040433b56f6135022039fb796942f01c9a0 Mon Sep 17 00:00:00 2001 From: Ben Burlingham Date: Sat, 23 May 2020 17:35:27 -0700 Subject: [PATCH] Features: Wall regeneration and robot repositioning. --- client/board.js | 10 ++++++ client/controls.js | 38 ++++++++++++++++++---- index.css | 18 +++++++---- index.html | 38 ++++++++++++++++++---- server.js | 19 ++++++++--- server/game.js | 80 ++++++++++++++++++++++++++++++++++++++-------- 6 files changed, 165 insertions(+), 38 deletions(-) diff --git a/client/board.js b/client/board.js index 2abd102..8ff7b44 100644 --- a/client/board.js +++ b/client/board.js @@ -123,6 +123,16 @@ Board.prototype.drawSquares = function() { Board.prototype.drawWalls = function(edges) { this.walls = {}; + while (this.parent.getElementsByClassName('content-wall-x').length) { + const child = this.parent.getElementsByClassName('content-wall-x')[0]; + child.parentNode.removeChild(child); + } + + while (this.parent.getElementsByClassName('content-wall-y').length) { + const child = this.parent.getElementsByClassName('content-wall-y')[0]; + child.parentNode.removeChild(child); + } + edges.forEach(edge => { this.walls[edge] = true; diff --git a/client/controls.js b/client/controls.js index 41903a6..eddaf1f 100644 --- a/client/controls.js +++ b/client/controls.js @@ -1,9 +1,13 @@ -const Controls = function(connection) { - this.connection = connection; +const Controls = function() { this.moves = 0; document.addEventListener('move-increment', this.onMoveIncrement.bind(this)); + document.getElementById('controls-moves-reset').addEventListener('click', this.onMoveReset.bind(this)); + document.getElementById('controls-next-round').addEventListener('click', this.onStartNextGame.bind(this)); + document.getElementById('controls-regenerate-walls').addEventListener('click', this.onRegenWalls.bind(this)); + document.getElementById('controls-reposition-robots').addEventListener('click', this.onRepositionRobots.bind(this)); + // document.getElementById('controls-timer-skip').addEventListener('click', this.onSkipTimer.bind(this)); } // guessBuild: = function() { @@ -25,12 +29,17 @@ const Controls = function(connection) { // }, Controls.prototype.playerAdd = function() { - const rawInput = prompt("What is your name?"); - this.connection.send(JSON.stringify({ head: { type: 'playerAdd' }, body: rawInput })) + const names = ["Biff", "Morty", "Herb", "Chester", "Lyle", "Cap", "Dale", "Ned", "Mindy"] + const r = Math.floor(Math.random() * names.length); + + const rawInput = names[r] //prompt("What is your name?"); + + const evt = new CustomEvent('playerAdd', { detail: rawInput }); + document.dispatchEvent(evt); }; Controls.prototype.playerRemove = function(rawInput) { - this.connection.send(JSON.stringify({ head: { type: 'playerRemove' }, body: rawInput })) + alert('nope') }; Controls.prototype.playersUpdate = function(names) { @@ -72,6 +81,21 @@ Controls.prototype.onMoveReset = function() { this.moves = 0; document.getElementById('controls-moves').innerHTML = this.moves; - var event = new Event('board-reset'); + const event = new Event('board-reset'); document.dispatchEvent(event); -}; \ No newline at end of file +}; + +Controls.prototype.onStartNextGame = function() { + const evt = new Event('board-reset'); + document.dispatchEvent(evt); +} + +Controls.prototype.onRegenWalls = function() { + const evt = new Event('regenerateWalls'); + document.dispatchEvent(evt); +} + +Controls.prototype.onRepositionRobots = function() { + const evt = new Event('repositionRobots'); + document.dispatchEvent(evt); +} \ No newline at end of file diff --git a/index.css b/index.css index fff9602..21c9a50 100644 --- a/index.css +++ b/index.css @@ -16,8 +16,8 @@ body { #controls-container { background: #e7e7e7; - border: solid #c7c7c7; - border-width: 0 1px; + border: solid #e7e7e7; + border-width: 0 10px; bottom: 0; left: 20px; position: absolute; @@ -38,6 +38,7 @@ body { .controls-subtitle { background-color: #4D3243; + background-image: linear-gradient(90deg, #4D3243, #3C2132); color: #fff; padding: 12px; margin: 24px 0 12px 0; @@ -59,19 +60,22 @@ body { .controls-button { background: none; border: 1px solid #888; - color: #666; + color: #444; cursor: pointer; font-size: 12px; padding: 4px 8px; } .controls-button:hover { - background: #ddd; - border-color: #444; - color: #222; + background: #639699; + border-color: #639699; + color: #fff; } -#controls-room { +#controls-start { + display: block; + margin: 0 auto; + padding: 4px 8px; } .controls-room-error { diff --git a/index.html b/index.html index 58f552b..7c87e5f 100644 --- a/index.html +++ b/index.html @@ -13,10 +13,8 @@
-
Puzzle Robots
- -
-
Room
+
+
Manage
Room ID
@@ -26,7 +24,23 @@
- +
+
Start Next Round
+
 
+
Do It
+
+ +
+
Move Robots
+
 
+
Reposition
+
+ +
+
Move Walls
+
 
+
Regenerate
+
@@ -66,7 +80,19 @@ const controls = new Controls(connection); const board = new Board({ parent: document.getElementById('content-container'), squares }); - // connection.onopen = controls.playerAdd.bind(controls); + connection.onopen = controls.playerAdd.bind(controls); + + document.addEventListener('repositionRobots', () => { + connection.send(JSON.stringify({ head: { type: 'repositionRobots' }})); + }); + + document.addEventListener('regenerateWalls', () => { + connection.send(JSON.stringify({ head: { type: 'regenerateWalls' }})); + }); + + document.addEventListener('playerAdd', (evt) => { + connection.send(JSON.stringify({ head: { type: 'playerAdd' }, rawBody: evt.detail })); + }); connection.onerror = (err) => { console.error(err); diff --git a/server.js b/server.js index 040c520..1337cad 100644 --- a/server.js +++ b/server.js @@ -52,8 +52,8 @@ const Server = { ws.on('close', Server.onDisconnect.bind(null, ws)) Server.messageAll({ head: { type: 'connect' }, body: { id: ws.id }}); - Server.messageAll({ head: { type: 'walls' }, body: G.getWalls()}) - Server.messageAll({ head: { type: 'robots' }, body: G.getRobots()}) + Server.messageAll({ head: { type: 'walls' }, body: G.getWalls()}); + Server.messageAll({ head: { type: 'robots' }, body: G.getRobots()}); }, onMessage: (ws, json) => { @@ -62,7 +62,7 @@ const Server = { DEBUG && console.log('Received message: '); DEBUG && console.log(message); - if (!message.head || !message.body) { + if (!message.head) { DEBUG && console.warn("Unprocessable message: ") DEBUG && console.warn(message); return; @@ -72,13 +72,22 @@ const Server = { case 'playerAdd': DEBUG && console.log('Adding player: '); DEBUG && console.log(ws.id); - DEBUG && console.log(message.body); - const santizedName = message.body.replace(/[^\w ]/g, ''); + DEBUG && console.log(message.rawBody); + + const santizedName = message.rawBody.replace(/[^\w ]/g, ''); G.addPlayer(ws.id, santizedName); Server.messageAll({ head: { type: 'players' }, body: G.getPlayers() }); break; case 'playerRemove': break; + case 'repositionRobots': + Server.messageAll({ head: { type: 'robots' }, body: G.getRobots()}); + break; + case 'regenerateWalls': + Server.messageAll({ head: { type: 'walls' }, body: G.getWalls()}); + break; + case 'newRound': + break; default: console.warn("Unknown message type: ", message.head.type) } diff --git a/server/game.js b/server/game.js index 2cf9e48..586548d 100644 --- a/server/game.js +++ b/server/game.js @@ -22,23 +22,77 @@ Game.prototype.getPlayers = function() { } Game.prototype.getRobots = function() { - return [ - {i: 9, j: 9, color: '#E00000' }, - {i: 18, j: 9, color: '#00C000' }, - {i: 1, j: 9, color: '#0000FF' }, - {i: 9, j: 18, color: '#00C0C0' }, - {i: 9, j: 1, color: '#F000F0' }, - ]; + const robots = ['#E00000', '#00C000', '#0000FF', '#00C0C0', '#F000F0']; + const squaresPerSide = 20; + const gen = () => Math.floor(Math.random() * squaresPerSide); + + // Leave here for testing. + // return [ + // {i: 9, j: 9, color: '#E00000' }, + // {i: 18, j: 9, color: '#00C000' }, + // {i: 1, j: 9, color: '#0000FF' }, + // {i: 9, j: 18, color: '#00C0C0' }, + // {i: 9, j: 1, color: '#F000F0' }, + // ]; + + return robots.map(color => ({ i: gen(), j: gen(), color })); } Game.prototype.getWalls = function() { // Edge IDs are of the form [i1-j1-i2-j2]. Top left is 0, 0. - return [ - "1-9-1-10", - "9-1-10-1", - "9-19-10-19", - "19-9-19-10" - ]; + + // Leave here for testing. + // return [ + // "1-9-1-10", + // "9-1-10-1", + // "9-19-10-19", + // "19-9-19-10" + // ]; + + console.log("Generating walls."); + + // Squares per side has quadratic relationship with wall/corner requirements. + const squaresPerSide = 20; + const numberOfCorners = Math.ceil(Math.pow((squaresPerSide / 10), 2)); + const numberOfWalls = Math.ceil(Math.pow((squaresPerSide / 5), 2)); + + const gen = () => Math.floor(Math.random() * squaresPerSide + 1); + const edges = []; + + // DO NUMBER OF CORNERS FIRST AFTER TESTING + for (let n = 0; n < numberOfWalls; n++) { + const ri = gen(); + const rj = gen(); + + const isHorizontal = Math.random() < 0.5; + const isBackward = Math.random() < 0.5; + + let i1, j1, i2, j2; + + if (isHorizontal) { + i1 = isBackward ? ri - 1 : ri; + i2 = isBackward ? ri : ri + 1; + + j1 = rj; + j2 = rj; + } else { + i1 = ri; + i2 = ri; + + j1 = isBackward ? rj - 1 : rj; + j2 = isBackward ? rj : rj + 1; + } + + const edge = `${i1}-${j1}-${i2}-${j2}`; + + if (edges.includes(edge)) { + n--; + } else { + edges.push(edge); + } + } + + return edges; }; module.exports = Game; \ No newline at end of file