ai.js
changeset 20 ab294e8db00c
parent 19 94a4201d27a3
child 21 ed0292f0c7c6
--- a/ai.js	Mon Sep 08 02:04:16 2014 +0300
+++ b/ai.js	Mon Sep 08 17:43:10 2014 +0300
@@ -137,3 +137,81 @@
 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
 ai.deepMaxScore.prototype.cleanup = function() { }
 
+
+////////////////////////////////////////////////////////////////
+// N level deep on score value + max value prefer corner,
+// without random simulation.
+////////////////////////////////////////////////////////////////
+
+/* cfg.cornerBonus - value to add if max value at corner. */
+/* cfg.edgeBonus - value to add if max value at edge. */
+ai.deepMaxScoreCorner = function(brdEngine, cfg) {
+    this.brdEngine = brdEngine;
+    this.cfg = cfg || {};
+    this.cfg.cornerBonus = this.cfg.cornerBonus || 20000;
+    this.cfg.edgeBonus = this.cfg.edgeBonus || 100;
+    this.cfg.freeBonus = this.cfg.edgeBonus || 100;
+}
+ai.deepMaxScoreCorner.prototype.scoreCorner = function(brd) {
+    var score = brd.score();
+    var max = brd.max();
+    if (brd.atCorner(max))
+        score += this.cfg.cornerBonus;
+    else if (brd.atEdge(max))
+        score += this.cfg.edgeBonus;
+    score += brd.free() * this.cfg.freeBonus;
+    return score;
+}
+ai.deepMaxScoreCorner.prototype.scoreEdge = function(brd) {
+    var score = brd.score();
+    var max = brd.max();
+    if (brd.atEdge(max))
+        score += this.cfg.edgeBonus;
+    score += brd.free() * this.cfg.freeBonus;
+    return score;
+}
+ai.deepMaxScoreCorner.prototype.analyse = function(brd) {
+    var origBrd = new this.brdEngine(brd);
+    var nextBrd = new this.brdEngine();
+    var prevScore = -1, nextScore = -1;
+    var maxScore = -1;
+    var bestDir;
+    for (var i = 0; i < ai.dirs.length; i++) {
+        var dir = ai.dirs[i];
+        if (origBrd[dir](nextBrd)) {
+            nextScore = this.scoreCorner(nextBrd);
+            var score = this.bestScore(nextBrd);
+            // console.log("dir: %o, prevScore: %o, nextScore: %o, maxScore: %o, score: %o", dir, prevScore, nextScore, maxScore, score);
+            if (maxScore < score || (maxScore === score && prevScore < nextScore)) {
+                prevScore = nextScore;
+                maxScore = score;
+                bestDir = dir;
+            }
+        }
+    }
+    return bestDir;
+}
+ai.deepMaxScoreCorner.prototype.bestScore = function(brd, seenBrds) {
+    if (seenBrds) {
+        for (var i = 0; i < seenBrds.length; i++)
+            if (brd.equals(seenBrds[i]))
+                return 0;
+    } else {
+        seenBrds = [];
+    }
+    seenBrds.push(brd);
+    var currScore = this.scoreEdge(brd);
+    var maxScore = currScore;
+    var nextBrd = new this.brdEngine();
+    for (var i = 0; i < ai.dirs.length; i++) {
+        if (brd[ai.dirs[i]](nextBrd)) {
+            var score = this.scoreEdge(nextBrd);
+            if (score > currScore)
+                maxScore = Math.max(maxScore, this.bestScore(nextBrd, seenBrds));
+        }
+    }
+    return maxScore;
+}
+/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
+ai.deepMaxScoreCorner.prototype.cleanup = function() { }
+