HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinorCanonical

2048 (game) solver 2.0

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
solvergame2048

Problem

Follow-up of 2048 (game) solver

I improved the script, using standard search methods like expectimax. Now it goes easily to 2048, but not really further, the difference with the highly efficient answer is that they represent the whole board in an integer, then they can go to further depth in the search (10 million of moves, likely they can go to depth=5). While I can't go above depth=3 (~104 moves) it's already deadly slow with depth=3. I use it only when there is 2 or less free tiles left, and depth=2 with 6 or less free tiles, otherwise, depth=1.



var n = 4, M=new MatrixTransform(n);

var ai = { weights: [1, 1], depth: 1};// depth=1 by default, but we adjust it on every prediction according to the number of free tiles

initialize(ai)

function run(ai) {
var p;
while ((p = predict(ai)) != null) {
move(p, ai);
}
//console.log(ai.grid , maxValue(ai.grid))
ai.maxValue = maxValue(ai.grid)
console.log(ai)
}

function initialize(ai) {
ai.grid = [];
for (var i = 0; i 4?1:(free>2?2:3);
var root = { path: [], prob:1, grid: ai.grid, score: -Infinity, children:[]};
var x=expandMove(root, ai)
//console.log("number of leaves", x)
//console.log("number of leaves2", countLeaves(root))
if (!root.children.length)
return null
var values = root.children.map(expectimax);
var mx = max(values);
return root.children[mx[1]].path[0]

}

function countLeaves(node){
var x=0;
if (!node.children.length) return 1;
for(var n of node.children)
x+=countLeaves(n);
return x;
}

function expectimax(node){
if (!node.children.length){
return node.score
}else{
var values = node.children.map(expectimax);
if(node.prob){ //we are at a max node
return Math.max.apply(null, values)
}else{ // we are at a random node
var avg=0;
for(var i=0;i min.score)
min = node;
}
return min;
}

function mv(k, grid) {
var tgrid = M.itransform(k, grid);
for (var i = 0; i
table, th, td {
border: 1px solid black;
}
td {
width: 35px;
height: 35px;

Solution

First, your algorithm looks a little better, but it still can be improved. It appears that it weights the higher values so they always drift to the left side of the board instead of wrapping around in a snake pattern:

Second, you should always have spaces around your operators, not just sometimes.

Third, you should use the correct levels of indentation, usually 4 spaces per level:

function freeCells(grid) {
  return grid.reduce(function(v, a) {
return v + a.reduce(function(t, x) {
  return t + (x==0)
}, 0)
  }, 0)
}


This should be:

function freeCells(grid) {
    return grid.reduce(function(v, a) {
        return v + a.reduce(function(t, x) {
            return t + (x == 0)
        }, 0)
    }, 0)
}


Fourth, when you attempt to get a hint after the game is over, it still returns "undefined".

Fifth, when I was playing it with my keyboard, sometimes when I would press down to merge some numbers and there was a space between them, the numbers would just stack next to each other instead of merging. I'm not sure why this happens.

Code Snippets

function freeCells(grid) {
  return grid.reduce(function(v, a) {
return v + a.reduce(function(t, x) {
  return t + (x==0)
}, 0)
  }, 0)
}
function freeCells(grid) {
    return grid.reduce(function(v, a) {
        return v + a.reduce(function(t, x) {
            return t + (x == 0)
        }, 0)
    }, 0)
}

Context

StackExchange Code Review Q#82174, answer score: 5

Revisions (0)

No revisions yet.