grid.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /**
  2. * @constructor
  3. **/
  4. function Definition(data) {
  5. /** @type {Array.<string>} */
  6. this.text = data["text"];
  7. /** @type {number} */
  8. this.direction = data["pos"];
  9. /** @type {Array.<Array.<number>>|null} */
  10. this.word = null;
  11. }
  12. /** @const */
  13. Definition.RIGHT_HORIZONTAL = 1;
  14. /** @const */
  15. Definition.RIGHT_VERTICAL = 2;
  16. /** @const */
  17. Definition.BOTTOM_HORIZONTAL = 3;
  18. /** @const */
  19. Definition.BOTTOM_VERTICAL = 4;
  20. /**
  21. * @constructor
  22. **/
  23. function Cell() {
  24. /** @type {boolean} */
  25. this.isBlack = false;
  26. /** @type {Array.<Definition>} */
  27. this.definitions = null;
  28. /** @type {Player|null} */
  29. this.found = null;
  30. /** @type {string|null} */
  31. this.letter = null;
  32. }
  33. /**
  34. * @param {*} data
  35. * @param {Object.<string, Player>} players
  36. **/
  37. Cell.prototype.update = function(data, players) {
  38. if (data["type"] === null) {
  39. this.isBlack = true;
  40. } else if (data["definitions"] !== undefined) {
  41. this.definitions = [];
  42. data["definitions"].forEach(function(definition) {
  43. this.definitions.push(new Definition(definition));
  44. }.bind(this));
  45. } else if (data["letter"]) {
  46. this.letter = data["letter"];
  47. this.found = players[data["found"]];
  48. return data["v"];
  49. }
  50. return 0;
  51. };
  52. /** @constructor */
  53. function Player(data) {
  54. /** @const @type {string} */
  55. this.id = data["name"];
  56. /** @const @type {string} */
  57. this.idEncoded = encodeURIComponent(data["name"]);
  58. /** @type {number} */
  59. this.score = data["score"];
  60. var pos = data["name"].indexOf('|');
  61. /** @const @type {string} */
  62. this.name = data["name"].substr(0, pos);
  63. /** @const @type {string} */
  64. this.color = '#' +data["name"].substr(pos +1);
  65. console.log(this);
  66. }
  67. Player.prototype.update = function(data) {
  68. this.score = data["score"];
  69. return data["v"];
  70. };
  71. /**
  72. * @constructor
  73. **/
  74. function Grid(data) {
  75. /** @type {string} */
  76. this.title = data["title"] || "";
  77. /** @type {number} */
  78. this.difficulty = data["difficulty"];
  79. /** @type {number} */
  80. this.width = data["w"];
  81. /** @type {number} */
  82. this.height = data["h"];
  83. /** @type {Object.<string, Player>} */
  84. this.players = {};
  85. /** @type {Player|null} */
  86. this.playerSelf = null;
  87. this.words = [];
  88. this.grid = [];
  89. for (var i =0; i < this.width; i++) {
  90. this.grid[i] = [];
  91. for (var j =0; j < this.height; j++) {
  92. this.grid[i][j] = new Cell();
  93. }
  94. }
  95. }
  96. Grid.prototype.computeWord = function(x, y, dx, dy) {
  97. 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) {
  98. return [[x, y]];
  99. }
  100. var word = this.computeWord(x +dx, y +dy, dx, dy);
  101. word.unshift([x, y]);
  102. return word;
  103. };
  104. Grid.prototype.getWord = function(x, y) {
  105. var words = [];
  106. this.words.forEach(function(word) {
  107. for (var i =0, nbLetters =word.length; i < nbLetters; i++) {
  108. if (word[i][0] == x && word[i][1] == y) {
  109. words.push(word);
  110. break;
  111. }
  112. }
  113. });
  114. return words;
  115. };
  116. Grid.prototype.updatePlayers = function(playerData) {
  117. var maxVersion = 0;
  118. playerData.forEach(function(player) {
  119. var localPlayer = this.players[player["name"]];
  120. if (!localPlayer)
  121. localPlayer = this.players[player["name"]] = new Player(player);
  122. maxVersion = Math.max(maxVersion, localPlayer.update(player));
  123. }.bind(this));
  124. return maxVersion;
  125. };
  126. /**
  127. * @return {number|null}
  128. **/
  129. Grid.prototype.update = function(data) {
  130. var maxVersion = null
  131. ,topologyUpdated = false;
  132. data.forEach(function(cellData) {
  133. var updateResult = this.grid[cellData["x"]][cellData["y"]].update(cellData, this.players);
  134. maxVersion = Math.max(maxVersion || 0, updateResult);
  135. if (updateResult === 0) {
  136. topologyUpdated = true;
  137. }
  138. }.bind(this));
  139. if (topologyUpdated) {
  140. var words = [];
  141. for (var i =0; i < this.width; i++) {
  142. for (var j =0; j < this.height; j++) {
  143. if (this.grid[i][j].definitions) {
  144. this.grid[i][j].definitions.forEach(function(definition) {
  145. var word;
  146. switch (definition.direction) {
  147. case Definition.RIGHT_VERTICAL:
  148. word = this.computeWord(i +1, j, 0, 1);
  149. break;
  150. case Definition.RIGHT_HORIZONTAL:
  151. word = this.computeWord(i +1, j, 1, 0);
  152. break;
  153. case Definition.BOTTOM_VERTICAL:
  154. word = this.computeWord(i, j +1, 0, 1);
  155. break;
  156. case Definition.BOTTOM_HORIZONTAL:
  157. word = this.computeWord(i, j +1, 1, 0);
  158. break;
  159. }
  160. words.push(word);
  161. definition.word = word;
  162. }.bind(this));
  163. }
  164. }
  165. }
  166. this.words = words;
  167. }
  168. return maxVersion;
  169. };