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

file:b/.jshintrc (new)
--- /dev/null
+++ b/.jshintrc
@@ -1,1 +1,20 @@
+{
+    "esnext": true,
+    "indent": 2,
+    "maxlen": 80,
+    "freeze": true,
+    "camelcase": true,
+    "unused": true,
+    "eqnull": true,
+    "proto": true,
+    "supernew": true,
+    "noyield": true,
+    "evil": true,
+    "node": true,
+    "boss": true,
+    "expr": true,
+    "loopfunc": true,
+    "white": true,
+    "maxdepth": 4
+}
 

file:a/index.html -> file:b/index.html
--- a/index.html
+++ b/index.html
@@ -5,6 +5,12 @@
   <title>2048</title>
 
   <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>
 </head>
 <body>
   <div class="container">

file:b/js/application.js (new)
--- /dev/null
+++ b/js/application.js
@@ -1,1 +1,5 @@
+document.addEventListener("DOMContentLoaded", function () {
+  var actuator = new HTMLActuator;
+  var manager  = new GameManager(4, actuator);
+});
 

--- /dev/null
+++ b/js/game_manager.js
@@ -1,1 +1,43 @@
+function GameManager(size, actuator) {
+  this.size       = size; // Grid size
+  this.actuator   = actuator;
 
+  this.startTiles = 2;
+  this.grid       = new Grid(this.size);
+
+  this.setup();
+}
+
+// Set up the game
+GameManager.prototype.setup = function () {
+  this.addStartTiles();
+
+  // Update the actuator
+  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.addRandomTile();
+  }
+};
+
+// Adds a tile in a random position
+GameManager.prototype.addRandomTile = function () {
+  var tile = new Tile(this.grid.randomAvailableCell());
+  this.grid.insertTile(tile);
+};
+
+// Sends the updated grid to the actuator
+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.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;
+};
+

--- /dev/null
+++ b/js/html_actuator.js
@@ -1,1 +1,14 @@
+function HTMLActuator() {
 
+}
+
+HTMLActuator.prototype.actuate = function (grid) {
+  // Temporary debug visualizer
+  grid.cells.forEach(function (row) {
+    var mapped = row.map(function (tile) {
+      return tile ? tile.value : " ";
+    }).join(" | ");
+    console.log(mapped);
+  });
+};
+

file:b/js/tile.js (new)
--- /dev/null
+++ b/js/tile.js
@@ -1,1 +1,8 @@
+function Tile(position, value) {
+  this.x                = position.x;
+  this.y                = position.y;
+  this.value            = value || 2;
 
+  this.previousPosition = null;
+}
+

comments