--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rule.js Sun Sep 07 00:19:00 2014 +0300
@@ -0,0 +1,187 @@
+"use strict";
+
+var board = {};
+board.create = function() {
+ var brd = [];
+ for (var i = 0; i < 4; i++) {
+ brd[i] = [];
+ for (var j = 0; j < 4; j++) {
+ brd[i][j] = 0;
+ }
+ }
+ return brd;
+}
+board.copy = function(from, to) {
+ for (var i = 0; i < 4; i++) {
+ for (var j = 0; j < 4; j++) {
+ to[i][j] = from[i][j];
+ }
+ }
+}
+board.freeCnt = function(brd) {
+ var cnt = 0;
+ for (var i = 0; i < 4; i++) {
+ for (var j = 0; j < 4; j++) {
+ if (brd[i][j] === 0)
+ cnt++;
+ }
+ }
+ return cnt;
+}
+board.gameOver = function(brd) {
+ if (board.freeCnt(brd) > 0)
+ return false;
+ for (var i = 0; i < 4; i++) {
+ for (var j = 0; j < 3; j++) {
+ if (brd[i][j] === brd[i][j+1])
+ return false;
+ }
+ }
+ for (var j = 0; j < 4; j++) {
+ for (var i = 0; i < 3; i++) {
+ if (brd[i][j] === brd[i+1][j])
+ return false;
+ }
+ }
+ return true;
+}
+board.putRandom = function(brd) {
+ var cnt = board.freeCnt(brd);
+ cnt = Math.floor(Math.random() * cnt)+1;
+ for (var i = 0; i < 4 && cnt > 0; i++) {
+ for (var j = 0; j < 4 && cnt > 0; j++) {
+ if (brd[i][j] !== 0)
+ continue;
+ if (cnt === 1)
+ brd[i][j] = (Math.random() > .9) ? 2 : 1;
+ cnt--;
+ }
+ }
+}
+/* http://www.reddit.com/r/2048/comments/214njx/highest_possible_score_for_2048_warning_math */
+var boardScoreTbl = [0];
+for (var i = 1, exp = 2; i < 16; i++, exp *= 2) {
+ boardScoreTbl[i] = (i-1)*exp;
+}
+board.score = function(brd) {
+ var score = 0;
+ var max = 0;
+ for (var i = 0; i < 4; i++) {
+ for (var j = 0; j < 4; j++) {
+ var val = brd[i][j];
+ score += boardScoreTbl[val];
+ if (max < val)
+ max = val;
+ }
+ }
+ return {score: score, max: Math.pow(2, max)};
+}
+
+board.row = {};
+board.row.init = function() {
+ return {stack: [], curr: 0};
+}
+board.row.push = function(state, val) {
+ if (val === 0)
+ return;
+ if (state.curr === 0) {
+ state.curr = val;
+ return;
+ }
+ if (state.curr === val) {
+ state.stack.push(state.curr+1);
+ state.curr = 0;
+ } else {
+ state.stack.push(state.curr);
+ state.curr = val;
+ }
+}
+board.row.finish = function(state) {
+ if (state.curr !== 0)
+ state.stack.push(state.curr);
+}
+board.move = {};
+board.move.up = function(brd) {
+ var updated = false;
+ for (var j = 0; j < 4; j++) {
+ var state = board.row.init();
+ for (var i = 0; i < 4; i++) {
+ board.row.push(state, brd[i][j]);
+ }
+ board.row.finish(state);
+ for (var i = 0; i < state.stack.length; i++) {
+ if (brd[i][j] !== state.stack[i])
+ updated = true;
+ brd[i][j] = state.stack[i];
+ }
+ for (; i < 4; i++) {
+ if (brd[i][j] !== 0)
+ updated = true;
+ brd[i][j] = 0;
+ }
+ }
+ return updated;
+};
+board.move.down = function(brd) {
+ var updated = false;
+ for (var j = 0; j < 4; j++) {
+ var state = board.row.init();
+ for (var i = 3; i >= 0; i--) {
+ board.row.push(state, brd[i][j]);
+ }
+ board.row.finish(state);
+ for (var i = 0; i < state.stack.length; i++) {
+ if (brd[3-i][j] !== state.stack[i])
+ updated = true;
+ brd[3-i][j] = state.stack[i];
+ }
+ for (; i < 4; i++) {
+ if (brd[3-i][j] !== 0)
+ updated = true;
+ brd[3-i][j] = 0;
+ }
+ }
+ return updated;
+};
+board.move.left = function(brd) {
+ var updated = false;
+ for (var i = 0; i < 4; i++) {
+ var state = board.row.init();
+ for (var j = 0; j < 4; j++) {
+ board.row.push(state, brd[i][j]);
+ }
+ board.row.finish(state);
+ for (var j = 0; j < state.stack.length; j++) {
+ if (brd[i][j] !== state.stack[j])
+ updated = true;
+ brd[i][j] = state.stack[j];
+ }
+ for (; j < 4; j++) {
+ if (brd[i][j] !== 0)
+ updated = true;
+ brd[i][j] = 0;
+ }
+ }
+ return updated;
+};
+board.move.right = function(brd) {
+ var updated = false;
+ for (var i = 0; i < 4; i++) {
+ var state = board.row.init();
+ for (var j = 3; j >= 0; j--) {
+ board.row.push(state, brd[i][j]);
+ }
+ board.row.finish(state);
+ for (var j = 0; j < state.stack.length; j++) {
+ if (brd[i][3-j] !== state.stack[j])
+ updated = true;
+ brd[i][3-j] = state.stack[j];
+ }
+ for (; j < 4; j++) {
+ if (brd[i][3-j] !== 0)
+ updated = true;
+ brd[i][3-j] = 0;
+ }
+ }
+ return updated;
+};