ai.js
changeset 139 4dde63ac0bb4
parent 136 4a143572b9d2
child 140 438fd8c3c3ca
equal deleted inserted replaced
138:23cd36180bf9 139:4dde63ac0bb4
    18     for (var attr in from) {
    18     for (var attr in from) {
    19         if (from.hasOwnProperty(attr))
    19         if (from.hasOwnProperty(attr))
    20             to[attr] = from[attr];
    20             to[attr] = from[attr];
    21     }
    21     }
    22     return to;
    22     return to;
       
    23 }
       
    24 
       
    25 ai.brdCache = function() {
       
    26     this.cache = [];
       
    27 }
       
    28 ai.brdCache.prototype.get = function(brd) {
       
    29     var compr = brd.compress();
       
    30     var subCache = this.cache[compr[0]];
       
    31     if (subCache) {
       
    32         return subCache[compr[1]];
       
    33     }
       
    34     return undefined;
       
    35 }
       
    36 ai.brdCache.prototype.put = function(brd, val) {
       
    37     var compr = brd.compress();
       
    38     var subCache = this.cache[compr[0]];
       
    39     if (subCache) {
       
    40         subCache[compr[1]] = val;
       
    41     } else {
       
    42         this.cache[compr[0]] = [];
       
    43         this.cache[compr[0]][compr[1]] = val;
       
    44     }
    23 }
    45 }
    24 
    46 
    25 // Each strategy is a function that except current board position as 2d array and context from
    47 // Each strategy is a function that except current board position as 2d array and context from
    26 // previous call to share state/precomputed values between calls.
    48 // previous call to share state/precomputed values between calls.
    27 
    49 
   341     if (cfg.freeBonus > 0)
   363     if (cfg.freeBonus > 0)
   342         score += cfg.freeBonus * brd.free();
   364         score += cfg.freeBonus * brd.free();
   343     return score;
   365     return score;
   344 }
   366 }
   345 ai.expectimax.prototype.analyse = function(brd) {
   367 ai.expectimax.prototype.analyse = function(brd) {
       
   368     this.brdCache = new ai.brdCache();
   346     var origBrd = new this.brdEngine(brd);
   369     var origBrd = new this.brdEngine(brd);
   347     var nextBrd = new this.brdEngine();
   370     var nextBrd = new this.brdEngine();
   348     var maxW = -1;
   371     var maxW = -1;
   349     var bestDir;
   372     var bestDir;
   350     this.cleanup();
   373     this.cleanup();
   366     return bestDir;
   389     return bestDir;
   367 }
   390 }
   368 ai.expectimax.prototype.evalFn = function(brd, depth) {
   391 ai.expectimax.prototype.evalFn = function(brd, depth) {
   369     if (depth >= this.depthLimit)
   392     if (depth >= this.depthLimit)
   370         return this.weight(brd);
   393         return this.weight(brd);
   371     if (this.cache[depth]) {
   394     var wCached = this.brdCache.get(brd);
   372         var cache = this.cache[depth];
   395     if (wCached)
   373         for (var i = cache.length-1; i >= 0; i--) {
   396         return wCached;
   374             if (brd.equals(cache[i].brd))
       
   375                 return cache[i].weight;
       
   376         }
       
   377     } else {
       
   378         this.cache[depth] = [];
       
   379     }
       
   380     var wMin = +Infinity;
   397     var wMin = +Infinity;
   381     for (var i = 0; i < 3; i++) {
   398     for (var i = 0; i < 3; i++) {
   382         for (var j = 0; j < 3; j++) {
   399         for (var j = 0; j < 3; j++) {
   383             if (brd.get(i, j) === 0) {
   400             if (brd.get(i, j) === 0) {
   384                 var randBoard = brd.copy();
   401                 var randBoard = brd.copy();
   400                 }
   417                 }
   401                 wMin = Math.min(wMin, balance * wMax2 + (1 - balance) * wMax4);
   418                 wMin = Math.min(wMin, balance * wMax2 + (1 - balance) * wMax4);
   402             }
   419             }
   403         }
   420         }
   404     }
   421     }
   405     this.cache[depth].push({brd: brd, weight: wMin});
   422     this.brdCache.put(brd, wMin);
   406     return wMin;
   423     return wMin;
   407 }
   424 }
   408 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
   425 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
   409 ai.expectimax.prototype.cleanup = function() {
   426 ai.expectimax.prototype.cleanup = function() {
   410     this.cache = [];
   427 }
   411 }
   428 
   412