--- 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 = [];
}