--- 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() { }
+