/** * @constructor **/ function Definition(data) { /** @type {Array.} */ this.text = data["text"]; /** @type {number} */ this.direction = data["pos"]; /** @type {Array.>|null} */ this.word = null; } /** @const */ Definition.RIGHT_HORIZONTAL = 1; /** @const */ Definition.RIGHT_VERTICAL = 2; /** @const */ Definition.BOTTOM_HORIZONTAL = 3; /** @const */ Definition.BOTTOM_VERTICAL = 4; /** * @constructor **/ function Cell() { /** @type {boolean} */ this.isBlack = false; /** @type {Array.} */ this.definitions = null; /** @type {Player|null} */ this.found = null; /** @type {string|null} */ this.letter = null; } /** * @param {*} data * @param {Object.} players **/ Cell.prototype.update = function(data, players) { if (data["type"] === null) { this.isBlack = true; } else if (data["definitions"] !== undefined) { this.definitions = []; data["definitions"].forEach(function(definition) { this.definitions.push(new Definition(definition)); }.bind(this)); } else if (data["letter"]) { this.letter = data["letter"]; this.found = players[data["found"]]; return data["v"]; } return 0; }; /** @constructor */ function Player(data) { /** @const @type {string} */ this.id = data["name"]; /** @const @type {string} */ this.idEncoded = encodeURIComponent(data["name"]); /** @type {number} */ this.score = data["score"]; var pos = data["name"].indexOf('|'); /** @const @type {string} */ this.name = data["name"].substr(0, pos); /** @const @type {string} */ this.color = '#' +data["name"].substr(pos +1); console.log(this); } Player.prototype.update = function(data) { this.score = data["score"]; return data["v"]; }; /** * @constructor **/ function Grid(data) { /** @type {string} */ this.title = data["title"] || ""; /** @type {number} */ this.difficulty = data["difficulty"]; /** @type {number} */ this.width = data["w"]; /** @type {number} */ this.height = data["h"]; /** @type {Object.} */ this.players = {}; /** @type {Player|null} */ this.playerSelf = null; this.words = []; this.grid = []; for (var i =0; i < this.width; i++) { this.grid[i] = []; for (var j =0; j < this.height; j++) { this.grid[i][j] = new Cell(); } } } Grid.prototype.computeWord = function(x, y, dx, dy) { if (!this.grid[x +dx] || !this.grid[x +dx][y +dy] || this.grid[x +dx][y +dy].definitions || this.grid[x +dx][y +dy].isBlack) { return [[x, y]]; } var word = this.computeWord(x +dx, y +dy, dx, dy); word.unshift([x, y]); return word; }; Grid.prototype.getWord = function(x, y) { var words = []; this.words.forEach(function(word) { for (var i =0, nbLetters =word.length; i < nbLetters; i++) { if (word[i][0] == x && word[i][1] == y) { words.push(word); break; } } }); return words; }; Grid.prototype.updatePlayers = function(playerData) { var maxVersion = 0; playerData.forEach(function(player) { var localPlayer = this.players[player["name"]]; if (!localPlayer) localPlayer = this.players[player["name"]] = new Player(player); maxVersion = Math.max(maxVersion, localPlayer.update(player)); }.bind(this)); return maxVersion; }; /** * @return {number|null} **/ Grid.prototype.update = function(data) { var maxVersion = null ,topologyUpdated = false; data.forEach(function(cellData) { var updateResult = this.grid[cellData["x"]][cellData["y"]].update(cellData, this.players); maxVersion = Math.max(maxVersion || 0, updateResult); if (updateResult === 0) { topologyUpdated = true; } }.bind(this)); if (topologyUpdated) { var words = []; for (var i =0; i < this.width; i++) { for (var j =0; j < this.height; j++) { if (this.grid[i][j].definitions) { this.grid[i][j].definitions.forEach(function(definition) { var word; switch (definition.direction) { case Definition.RIGHT_VERTICAL: word = this.computeWord(i +1, j, 0, 1); break; case Definition.RIGHT_HORIZONTAL: word = this.computeWord(i +1, j, 1, 0); break; case Definition.BOTTOM_VERTICAL: word = this.computeWord(i, j +1, 0, 1); break; case Definition.BOTTOM_HORIZONTAL: word = this.computeWord(i, j +1, 1, 0); break; } words.push(word); definition.word = word; }.bind(this)); } } } this.words = words; } return maxVersion; };