extract the grid to its own class
extract the grid to its own class

file:a/index.html -> file:b/index.html
--- a/index.html
+++ b/index.html
@@ -7,6 +7,7 @@
   <link href="style/main.css" rel="stylesheet" type="text/css">
 
   <script src="js/html_actuator.js"></script>
+  <script src="js/grid.js"></script>
   <script src="js/tile.js"></script>
   <script src="js/game_manager.js"></script>
   <script src="js/application.js"></script>

--- a/js/game_manager.js
+++ b/js/game_manager.js
@@ -3,82 +3,41 @@
   this.actuator   = actuator;
 
   this.startTiles = 2;
-  this.grid       = [];
+  this.grid       = new Grid(this.size);
 
   this.setup();
 }
 
 // Set up the game
 GameManager.prototype.setup = function () {
-  this.buildGrid();
   this.addStartTiles();
 
   // Update the actuator
-  this.update();
-};
-
-// Build a grid of the specified size
-GameManager.prototype.buildGrid = function () {
-  for (var y = 0; y < this.size; y++) {
-    this.grid[y] = [];
-    for (var x = 0; x < this.size; x++) {
-      this.grid[y].push(null);
-    }
-  }
+  this.actuate();
 };
 
 // Set up the initial tiles to start the game with
 GameManager.prototype.addStartTiles = function () {
   for (var i = 0; i < this.startTiles; i++) {
-    this.addTile();
+    this.addRandomTile();
   }
 };
 
 // Adds a tile in a random position
-GameManager.prototype.addTile = function () {
-  this.insertTile(new Tile(this.randomCell()));
-};
-
-// Find the first available random position
-GameManager.prototype.randomCell = function () {
-  // TODO: build a map of available positions and choose from it
-  var self = this;
-
-  var position;
-
-  function randomPosition() {
-    return Math.floor(Math.random() * self.size);
-  }
-
-  do {
-    position = {
-      x: randomPosition(),
-      y: randomPosition()
-    };
-  } while (this.cellOccupied(position));
-
-  return position;
-};
-
-// Check if the specified cell is taken
-GameManager.prototype.cellOccupied = function (cell) {
-  return !!this.grid[cell.x][cell.y];
-};
-
-// Insert a tile at the specified position
-GameManager.prototype.insertTile = function (tile) {
-  this.grid[tile.x][tile.y] = tile;
+GameManager.prototype.addRandomTile = function () {
+  var tile = new Tile(this.grid.randomAvailableCell());
+  this.grid.insertTile(tile);
 };
 
 // Sends the updated grid to the actuator
-GameManager.prototype.update = function () {
-  this.actuator.update(this.grid);
+GameManager.prototype.actuate = function () {
+  this.actuator.actuate(this.grid);
 };
 
 // Move the grid in the specified direction
 GameManager.prototype.move = function (direction) {
   // 0: up, 1: right, 2:down, 3: left
 
-  this.update();
+  this.actuate();
 };
 

file:b/js/grid.js (new)
--- /dev/null
+++ b/js/grid.js
@@ -1,1 +1,58 @@
+function Grid(size) {
+  this.size = size;
 
+  this.cells = [];
+
+  this.build();
+}
+
+// Build a grid of the specified size
+Grid.prototype.build = function () {
+  for (var x = 0; x < this.size; x++) {
+    var row = this.cells[x] = [];
+
+    for (var y = 0; y < this.size; y++) {
+      row.push(null);
+    }
+  }
+};
+
+// Find the first available random position
+Grid.prototype.randomAvailableCell = function () {
+  var cells = this.availableCells();
+
+  if (cells.length) {
+    return cells[Math.floor(Math.random() * cells.length)];
+  }
+};
+
+Grid.prototype.availableCells = function () {
+  var cells = [];
+
+  for (var x = 0; x < this.size; x++) {
+    for (var y = 0; y < this.size; y++) {
+      var cell = { x: x, y: y };
+
+      if (this.cellAvailable(cell)) {
+        cells.push(cell);
+      }
+    }
+  }
+
+  return cells;
+};
+
+// Check if the specified cell is taken
+Grid.prototype.cellAvailable = function (cell) {
+  return !this.cellOccupied(cell);
+};
+
+Grid.prototype.cellOccupied = function (cell) {
+  return !!this.cells[cell.x][cell.y];
+};
+
+// Inserts a tile at its position
+Grid.prototype.insertTile = function (tile) {
+  this.cells[tile.x][tile.y] = tile;
+};
+

--- a/js/html_actuator.js
+++ b/js/html_actuator.js
@@ -2,9 +2,9 @@
 
 }
 
-HTMLActuator.prototype.update = function (grid) {
+HTMLActuator.prototype.actuate = function (grid) {
   // Temporary debug visualizer
-  grid.forEach(function (row) {
+  grid.cells.forEach(function (row) {
     var mapped = row.map(function (tile) {
       return tile ? tile.value : " ";
     }).join(" | ");

comments