grid.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. function Grid(size, previousState) {
  2. this.size = size;
  3. this.cells = previousState ? this.fromState(previousState) : this.empty();
  4. }
  5. // Build a grid of the specified size
  6. Grid.prototype.empty = function () {
  7. var cells = [];
  8. for (var x = 0; x < this.size; x++) {
  9. var row = cells[x] = [];
  10. for (var y = 0; y < this.size; y++) {
  11. row.push(null);
  12. }
  13. }
  14. return cells;
  15. };
  16. Grid.prototype.fromState = function (state) {
  17. var cells = [];
  18. for (var x = 0; x < this.size; x++) {
  19. var row = cells[x] = [];
  20. for (var y = 0; y < this.size; y++) {
  21. var tile = state[x][y];
  22. row.push(tile ? new Tile(tile.position, tile.value) : null);
  23. }
  24. }
  25. return cells;
  26. };
  27. // Find the first available random position
  28. Grid.prototype.randomAvailableCell = function () {
  29. var cells = this.availableCells();
  30. if (cells.length) {
  31. return cells[Math.floor(Math.random() * cells.length)];
  32. }
  33. };
  34. Grid.prototype.availableCells = function () {
  35. var cells = [];
  36. this.eachCell(function (x, y, tile) {
  37. if (!tile) {
  38. cells.push({ x: x, y: y });
  39. }
  40. });
  41. return cells;
  42. };
  43. // Call callback for every cell
  44. Grid.prototype.eachCell = function (callback) {
  45. for (var x = 0; x < this.size; x++) {
  46. for (var y = 0; y < this.size; y++) {
  47. callback(x, y, this.cells[x][y]);
  48. }
  49. }
  50. };
  51. // Check if there are any cells available
  52. Grid.prototype.cellsAvailable = function () {
  53. return !!this.availableCells().length;
  54. };
  55. // Check if the specified cell is taken
  56. Grid.prototype.cellAvailable = function (cell) {
  57. return !this.cellOccupied(cell);
  58. };
  59. Grid.prototype.cellOccupied = function (cell) {
  60. return !!this.cellContent(cell);
  61. };
  62. Grid.prototype.cellContent = function (cell) {
  63. if (this.withinBounds(cell)) {
  64. return this.cells[cell.x][cell.y];
  65. } else {
  66. return null;
  67. }
  68. };
  69. // Inserts a tile at its position
  70. Grid.prototype.insertTile = function (tile) {
  71. this.cells[tile.x][tile.y] = tile;
  72. };
  73. Grid.prototype.removeTile = function (tile) {
  74. this.cells[tile.x][tile.y] = null;
  75. };
  76. Grid.prototype.withinBounds = function (position) {
  77. return position.x >= 0 && position.x < this.size &&
  78. position.y >= 0 && position.y < this.size;
  79. };
  80. Grid.prototype.serialize = function () {
  81. var cellState = [];
  82. for (var x = 0; x < this.size; x++) {
  83. var row = cellState[x] = [];
  84. for (var y = 0; y < this.size; y++) {
  85. row.push(this.cells[x][y] ? this.cells[x][y].serialize() : null);
  86. }
  87. }
  88. return {
  89. size: this.size,
  90. cells: cellState
  91. };
  92. };