diff -r 23cd36180bf9 -r 4dde63ac0bb4 ai.js --- a/ai.js Thu Sep 25 01:10:01 2014 +0300 +++ b/ai.js Thu Sep 25 02:05:48 2014 +0300 @@ -22,6 +22,28 @@ return to; } +ai.brdCache = function() { + this.cache = []; +} +ai.brdCache.prototype.get = function(brd) { + var compr = brd.compress(); + var subCache = this.cache[compr[0]]; + if (subCache) { + return subCache[compr[1]]; + } + return undefined; +} +ai.brdCache.prototype.put = function(brd, val) { + var compr = brd.compress(); + var subCache = this.cache[compr[0]]; + if (subCache) { + subCache[compr[1]] = val; + } else { + this.cache[compr[0]] = []; + this.cache[compr[0]][compr[1]] = val; + } +} + // Each strategy is a function that except current board position as 2d array and context from // previous call to share state/precomputed values between calls. @@ -343,6 +365,7 @@ return score; } ai.expectimax.prototype.analyse = function(brd) { + this.brdCache = new ai.brdCache(); var origBrd = new this.brdEngine(brd); var nextBrd = new this.brdEngine(); var maxW = -1; @@ -368,15 +391,9 @@ ai.expectimax.prototype.evalFn = function(brd, depth) { if (depth >= this.depthLimit) return this.weight(brd); - if (this.cache[depth]) { - var cache = this.cache[depth]; - for (var i = cache.length-1; i >= 0; i--) { - if (brd.equals(cache[i].brd)) - return cache[i].weight; - } - } else { - this.cache[depth] = []; - } + var wCached = this.brdCache.get(brd); + if (wCached) + return wCached; var wMin = +Infinity; for (var i = 0; i < 3; i++) { for (var j = 0; j < 3; j++) { @@ -402,11 +419,10 @@ } } } - this.cache[depth].push({brd: brd, weight: wMin}); + this.brdCache.put(brd, wMin); return wMin; } /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */ ai.expectimax.prototype.cleanup = function() { - this.cache = []; }