Guest User

2048 bot

a guest
Feb 28th, 2015
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /////////////////////
  2. // Key press Logic //
  3. /////////////////////
  4.  
  5. var code_map = {
  6.     "L" : 37,
  7.     "U" : 38,
  8.     "R" : 39,
  9.     "D" : 40
  10. };
  11.  
  12. function press(key) {
  13.     var code = code_map[key];
  14.     var eventObj = document.createEvent("Events");
  15.     eventObj.initEvent("keydown", true, true);
  16.     eventObj.which = code;
  17.     document.body.dispatchEvent(eventObj);
  18. }
  19.  
  20. ///////////////
  21. // Board ADT //
  22. ///////////////
  23.  
  24. var length = 4;
  25.  
  26. // The Board class
  27. var Board = function () {
  28.     var i, j;
  29.     this.table = new Array(length);
  30.     for (i = 0; i < length; i++) {
  31.         this.table[i] = new Array(length);
  32.         for (j = 0; j < length; j++) {
  33.             this.table[i][j] = 0;
  34.         }
  35.     }
  36.     this.score = 0;
  37. };
  38.  
  39. Board.prototype.clone = function() {
  40.     var i, j, newBoard = new Board();
  41.     for (i = 0; i < length; i++) {
  42.     for (j = 0; j < length; j++) {
  43.         newBoard.table[i][j] = this.table[i][j];
  44.     }
  45.     }
  46.     newBoard.score = this.score;
  47.     return newBoard;
  48. }
  49.  
  50. Board.prototype.print = function () {
  51.     var i, j, result;
  52.     for (i = 0; i < length; i++) {
  53.         result = "";
  54.         for (j = 0; j < length; j++) {
  55.             result += this.table[j][i] + " ";
  56.         }
  57.        // console.log(result);
  58.     }
  59. };
  60.  
  61. Board.prototype.get = function(x, y) {
  62.     if (x >= 0 && x < length && y >= 0 && y < length) {
  63.     return this.table[x][y];
  64.     }
  65. }
  66.  
  67. Board.prototype.addPiece = function(x, y, value) {
  68.     if (this.table[x][y] !== 0) {
  69.         this.print();
  70.         throw "Added new piece to non-empty square " + x + "," + y;
  71.     }
  72.     this.table[x][y] = value;
  73. };
  74.  
  75. Board.prototype.movePiece = function(oldx, oldy, newx, newy) {
  76.     this.table[newx][newy] = this.table[oldx][oldy];
  77.     this.table[oldx][oldy] = 0;
  78. };
  79.  
  80. Board.prototype.playMove = function(direction) {
  81.     var newBoard, start, step, end, i, j, freePos, merged, change = false;
  82.     newBoard = new Board();
  83.     newBoard.score = this.score;
  84.     var is_horizontal = (direction === "L" || direction === "R");
  85.     if (direction === "U" || direction === "L") {
  86.         start = 0;
  87.         end = length;
  88.         step = 1;
  89.     } else {
  90.         start = length - 1;
  91.         end = -1;
  92.         step = -1;
  93.     }
  94.  
  95.     for (i = 0; i < length; i++) {
  96.         freePos = start;
  97.         merged = false;
  98.         for (j = start; j !== end; j += step) {
  99.             if (is_horizontal) {
  100.                 if (this.table[j][i] !== 0) {
  101.                     if (freePos !== start && this.table[j][i] === this.table[freePos - step][i] && !merged) {
  102.                         change = true;
  103.                         merged = true;
  104.                         newBoard.table[freePos - step][i] *= 2;
  105.             newBoard.score += newBoard.table[freePos - step][i];
  106.                     } else {
  107.                         if (freePos !== j) {
  108.                             change = true;
  109.                         }
  110.                         merged = false;
  111.                         newBoard.addPiece(freePos, i, this.table[j][i]);
  112.                         freePos += step;
  113.                     }
  114.                 }
  115.             } else {
  116.                 if (this.table[i][j] !== 0) {
  117.                     if (freePos !== start && this.table[i][j] === this.table[i][freePos - step] && !merged) {
  118.                         change = true;
  119.                         merged = true;
  120.                         newBoard.table[i][freePos - step] *= 2;
  121.                     } else {
  122.                         if (freePos !== j) {
  123.                             change = true;
  124.                         }
  125.                         merged = false;
  126.                         newBoard.addPiece(i, freePos, this.table[i][j]);
  127.                         freePos += step;
  128.                     }
  129.                 }
  130.             }
  131.         }
  132.     }
  133.     if (change) {
  134.         return newBoard;
  135.     }
  136. };
  137.  
  138. /////////////////////
  139. // Reading the DOM //
  140. /////////////////////
  141.  
  142. // board must be a newly created, empty board.
  143. function read_board(board) {
  144.     var tiles, properties, value, position, x, y, scoreDiv;
  145.     tiles = document.getElementsByClassName("tile");
  146.     for (var i = 0; i < tiles.length; i++) {
  147.         properties = tiles[i].className.split(" ");
  148.         value = parseInt(properties[1].split("-")[1]);
  149.         position = properties[2].split("-");
  150.         x = parseInt(position[2]) - 1;
  151.         y = parseInt(position[3]) - 1;
  152.     // There could be multiple tiles with the same position, but
  153.     // the last one is the one that matters.
  154.         board.table[x][y] = value;
  155.     }
  156.     scoreDiv = document.getElementsByClassName("score-container")[0]
  157.     board.score = parseInt(scoreDiv.innerHTML)
  158. }
  159.  
  160. ////////////////
  161. // Expectimax //
  162. ////////////////
  163.  
  164. var SCORE_FACTOR = 2;
  165. var SAME_TILE_FACTOR = 10;
  166. // var NEXT_TILE_FACTOR = 3;
  167. var EMPTY_FACTOR = 20;
  168. var CORNER_FACTOR = 5;
  169. var EDGE_FACTOR = 1;
  170. var SMOOTHNESS_FACTOR = 3;
  171. var MONOTONICITY_FACTOR = 1;
  172.  
  173. var LOSE_SCORE = -999999999;
  174. var DEPTH = 2;
  175. var actions = ["L", "U", "R", "D"];
  176.  
  177. function choose_action(board) {
  178.     var i, bestAction, bestScore = LOSE_SCORE - 1;
  179.     for (i = 0; i < actions.length; i++) {
  180.     nextBoard = board.playMove(actions[i]);
  181.         if (nextBoard === undefined) {
  182.             continue;
  183.         }
  184.     nextScore = expectizer(nextBoard, DEPTH);
  185.     delete nextBoard;
  186.     if (nextScore > bestScore) {
  187.         bestScore = nextScore;
  188.         bestAction = actions[i];
  189.     }
  190.     }
  191.     return bestAction;
  192. }
  193.  
  194. function maximizer(board, depth) {
  195.     var i, nextBoard, bestScore = LOSE_SCORE + board.score;
  196.     for (i = 0; i < actions.length; i++) {
  197.         nextBoard = board.playMove(actions[i]);
  198.         if (nextBoard === undefined) {
  199.             continue;
  200.         }
  201.         bestScore = Math.max(bestScore, expectizer(nextBoard, depth - 1));
  202.     delete nextBoard;
  203.     }
  204.     return bestScore;
  205. }
  206.  
  207. function expectizer(board, depth) {
  208.     var i, j, nextBoard, score = 0, numMoves = 0;
  209.     if (depth == 0) {
  210.     return evaluate(board);
  211.     }
  212.     for (i = 0; i < length; i++) {
  213.     for (j = 0; j < length; j++) {
  214.         if (board.table[i][j] === 0) {
  215.         numMoves++;
  216.         nextBoard = board.clone();
  217.         nextBoard.table[i][j] = 2;
  218.         score += 0.9 * maximizer(nextBoard, depth);
  219.         nextBoard.table[i][j] = 4;
  220.         score += 0.1 * maximizer(nextBoard, depth);
  221.         delete nextBoard;
  222.         }
  223.     }
  224.     }
  225.     return score / numMoves;
  226. }
  227.  
  228. function evaluate(board) {
  229.     var i, j, x, y, corners, tileMap, value, tile, numEmpty = 0, maxCorner = -1, maxTile = 2;
  230.     value = SCORE_FACTOR * board.score;
  231.  
  232.     for (i = 0; i < length; i++) {
  233.         for (j = 0; j < length; j++) {
  234.             tile = board.table[i][j];
  235.             if (tile === 0) {
  236.         numEmpty++;
  237.             continue;
  238.             }
  239.             maxTile = Math.max(maxTile, tile);
  240.             var m, n, neighbor;
  241.             for (m = i - 1; m <= i + 1; m += 2) {
  242.             for (n = j - 1; n <= j + 1; n += 2) {
  243.                 neighbor = board.get(m, n);
  244.                 if (neighbor === tile) {
  245.                 value += SAME_TILE_FACTOR;
  246.                 }
  247.             }
  248.             }
  249.         }
  250.     }
  251.  
  252.     var prev_row, prev_col, curr_row, curr_col, monotonicity = 0;
  253.     for (i = 0; i < length; i++) {
  254.     prev_row = board.table[0][i] < board.table[1][i];
  255.     prev_col = board.table[i][0] < board.table[i][1];
  256.  
  257.     for (j = 2; j < length; j++) {
  258.         curr_row = board.table[j-1][i] < board.table[j][i];
  259.         if (prev_row !== curr_row) {
  260.         monotonicity += Math.max(board.table[j-2][i], board.table[j-1][i], board.table[j][i]);
  261.         }
  262.         prev_row = curr_row;
  263.  
  264.         curr_col = board.table[i][j-1] < board.table[i][j];
  265.         if (prev_col !== curr_col) {
  266.         monotonicity += Math.max(board.table[i][j-2], board.table[i][j-1], board.table[i][j]);
  267.         }
  268.         prev_col = curr_col;
  269.     }
  270.     }
  271.  
  272.     value -= MONOTONICITY_FACTOR * monotonicity;
  273.  
  274.     value += EMPTY_FACTOR * numEmpty;
  275.  
  276.     x = 0;
  277.     y = 0;
  278.     for (i = 0; i < length; i += length - 1) {
  279.     for (j = 0; j < length; j += length - 1) {
  280.         if (board.table[i][j] > maxCorner) {
  281.         maxCorner = board.table[i][j];
  282.         x = i;
  283.         y = j;
  284.         }
  285.     }
  286.     }
  287.  
  288.     if (board.table[x][y] === maxTile) {
  289.         value += CORNER_FACTOR * maxTile;
  290.     }
  291.  
  292.     for (i = 0; i < length; i++) {
  293.         value += EDGE_FACTOR * board.table[0][i];
  294.         value += EDGE_FACTOR * board.table[i][0];
  295.         value += EDGE_FACTOR * board.table[length-1][i];
  296.         value += EDGE_FACTOR * board.table[i][length-1];
  297.     }
  298.  
  299.     // Smoothness
  300.     var smoothness = 0;
  301.     for (i = 0; i < length; i++) {
  302.     for (j = 1; j < length; j++) {
  303.         smoothness += Math.abs(board.table[i][j] - board.table[i][j-1]);
  304.         smoothness += Math.abs(board.table[j][i] - board.table[j-1][i]);
  305.     }
  306.     }
  307.     value -= SMOOTHNESS_FACTOR * smoothness;
  308.  
  309.     return value;
  310. }
  311.  
  312. ///////////////
  313. // Main Loop //
  314. ///////////////
  315. function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
  316. var max, min;
  317. var interval, interval2;
  318.  
  319. function start()
  320. {
  321.  
  322.         var action, board = new Board();
  323.         read_board(board);
  324.         action = choose_action(board);
  325.  
  326.         delete board;
  327.         if (action !== undefined) {
  328.         press(action);
  329.        }
  330. }
  331.  
  332. function start2()
  333. {
  334.     if (document.getElementsByClassName("game-over").length > 0)
  335.     {
  336.          document.getElementsByClassName("restart-button")[0].click();
  337.     }
  338.     else if (document.getElementsByClassName("game-won").length > 0)
  339.     {
  340.         if (document.getElementsByClassName("keep-playing-button").length > 0)
  341.         {
  342.              document.getElementsByClassName("keep-playing-button")[0].click();
  343.         }else{
  344.                  clearInterval(interval);
  345.         }
  346.     }
  347. }
  348.  
  349. min = getRandomInt(350, 660);
  350. max = getRandomInt(661, 1206);
  351.  
  352. interval  = setInterval(start, getRandomInt(min, max));
  353. interval2 = setInterval(start2, 3000);
Advertisement
Add Comment
Please, Sign In to add comment