merged
authorOleksandr Gavenko <gavenkoa@gmail.com>
Fri, 03 Jul 2015 22:31:58 -0500
changeset 169 5a17638f0dca
parent 166 cde69b258e85 (current diff)
parent 168 df8e645c3f36 (diff)
child 170 b2e6398d2b06
merged
2048.html
ai.js
--- a/2048.html	Fri Jul 03 22:21:05 2015 -0500
+++ b/2048.html	Fri Jul 03 22:31:58 2015 -0500
@@ -253,7 +253,7 @@
           <input type="text" name="freeBonus" class="positive" pattern="[0-9]*[.]?[0-9]*" value="10"/> free cell coefficient
         </div>
         <div class="option">
-          <input type="text" name="weightThreshold" class="positive" pattern="[0-9]*[.]?[0-9]*" value="10"/> score threshold
+          <input type="text" name="utilityThreshold" class="positive" pattern="[0-9]*[.]?[0-9]*" value="10"/> score threshold
         </div>
       </div>
       <div class="ai wide control" id="ai-expectimax">
--- a/ai.js	Fri Jul 03 22:21:05 2015 -0500
+++ b/ai.js	Fri Jul 03 22:31:58 2015 -0500
@@ -184,13 +184,13 @@
 
 
 ////////////////////////////////////////////////////////////////
-// 1 step deep with linear weight function on score, max value,
+// 1 step deep with linear utility function on score, max value,
 // bonuses for max value stay at corner or edge and bonuses
 // for each free field.
 ////////////////////////////////////////////////////////////////
 
 /**
- * Defines coefficient for linear resulted weight function.
+ * Defines coefficient for linear resulted utility function.
  * @name ai.OneStepAhead.cfg
  * @namespace
  * @property {number} scoreCoef    multiplicator for score
@@ -210,34 +210,34 @@
     ai.copyObj(cfg, this.cfg);
 }
 ai.OneStepAhead.bestCfg = {scoreCoef: 1, maxValCoef: 0, cornerBonus: 0, edgeBonus: 0, freeBonus: 0};
-ai.OneStepAhead.prototype.weight = function(brd) {
-    var weight = 0;
+ai.OneStepAhead.prototype.utility = function(brd) {
+    var utility = 0;
     if (this.cfg.scoreCoef > 0)
-        weight += this.cfg.scoreCoef * brd.score();
+        utility += this.cfg.scoreCoef * brd.score();
     var max = brd.maxVal();
     if (this.cfg.maxValCoef > 0)
-        weight += this.cfg.maxValCoef * max;
+        utility += this.cfg.maxValCoef * max;
     if (this.cfg.cornerBonus > 0 && brd.atCorner(max))
-        weight += this.cfg.cornerBonus;
+        utility += this.cfg.cornerBonus;
     if (this.cfg.edgeBonus > 0 && brd.atEdge(max))
-        weight += this.cfg.edgeBonus;
+        utility += this.cfg.edgeBonus;
     if (this.cfg.freeBonus > 0)
-        weight += this.cfg.freeBonus * brd.freeCnt();
-    return weight;
+        utility += this.cfg.freeBonus * brd.freeCnt();
+    return utility;
 }
 /** Select best direction for next step. */
 ai.OneStepAhead.prototype.analyse = function(brd2d) {
     var origBrd = new this.brd(brd2d);
     var nextBrd = new this.brd();
-    var maxWeight = -1;
+    var maxUtility = -1;
     var bestDir;
     for (var i = 0; i < ai.dirs.length; i++) {
         var dir = ai.dirs[i];
         if (origBrd[dir](nextBrd)) {
-            var weight = this.weight(nextBrd);
-            if (maxWeight < weight) {
+            var utility = this.utility(nextBrd);
+            if (maxUtility < utility) {
                 bestDir = dir;
-                maxWeight = weight;
+                maxUtility = utility;
             }
         }
     }
@@ -253,7 +253,7 @@
 ////////////////////////////////////////////////////////////////
 
 /**
- * Defines coefficient for linear resulted weight function.
+ * Defines coefficient for linear resulted utility function.
  * @name ai.StaticDeepMerges.cfg
  * @namespace
  * @property {number} scoreCoef    multiplicator for score
@@ -272,41 +272,41 @@
     this.cfg = ai.copyObj(ai.OneStepAhead.bestCfg);
     ai.copyObj(cfg, this.cfg);
 }
-ai.StaticDeepMerges.bestCfg = {scoreCoef: 1, maxValCoef: 0, cornerBonus: 0, edgeBonus: 0, freeBonus: 0, weightThreshold: 10};
-ai.StaticDeepMerges.prototype.weight = function(brd) {
-    var weight = 0;
+ai.StaticDeepMerges.bestCfg = {scoreCoef: 1, maxValCoef: 0, cornerBonus: 0, edgeBonus: 0, freeBonus: 0, utilityThreshold: 10};
+ai.StaticDeepMerges.prototype.utility = function(brd) {
+    var utility = 0;
     if (this.cfg.scoreCoef > 0)
-        weight += this.cfg.scoreCoef * brd.score();
+        utility += this.cfg.scoreCoef * brd.score();
     var max = brd.maxVal();
     if (this.cfg.maxValCoef > 0)
-        weight += this.cfg.maxValCoef * max;
+        utility += this.cfg.maxValCoef * max;
     if (this.cfg.cornerBonus > 0 && brd.atCorner(max))
-        weight += this.cfg.cornerBonus;
+        utility += this.cfg.cornerBonus;
     if (this.cfg.edgeBonus > 0 && brd.atEdge(max))
-        weight += this.cfg.edgeBonus;
+        utility += this.cfg.edgeBonus;
     if (this.cfg.freeBonus > 0)
-        weight += this.cfg.freeBonus * brd.freeCnt();
-    return weight;
+        utility += this.cfg.freeBonus * brd.freeCnt();
+    return utility;
 }
 /** Select best direction for next step. */
 ai.StaticDeepMerges.prototype.analyse = function(brd2d) {
     var origBrd = new this.brd(brd2d);
     var nextBrd = new this.brd();
     var prevScore = -1, nextScore = -1;
-    var maxWeight = -1;
+    var maxUtility = -1;
     var bestDir;
     for (var i = 0; i < ai.dirs.length; i++) {
         var dir = ai.dirs[i];
         if (origBrd[dir](nextBrd)) {
-            var weight = this.evalFn(nextBrd);
-            var ok = (weight - maxWeight) > this.cfg.weightThreshold;
-            if ( ! ok && maxWeight <= weight) {
-                nextScore = this.weight(nextBrd);
+            var utility = this.evalFn(nextBrd);
+            var ok = (utility - maxUtility) > this.cfg.utilityThreshold;
+            if ( ! ok && maxUtility <= utility) {
+                nextScore = this.utility(nextBrd);
                 ok = prevScore < nextScore;
             }
             if (ok) {
                 prevScore = nextScore;
-                maxWeight = weight;
+                maxUtility = utility;
                 bestDir = dir;
             }
         }
@@ -315,16 +315,16 @@
 }
 ai.StaticDeepMerges.prototype.evalFn = function(brd) {
     var currScore = brd.score();
-    var maxWeight = currScore;
+    var maxUtility = currScore;
     var nextBrd = new this.brd();
     for (var i = 0; i < ai.dirs.length; i++) {
         if (brd[ai.dirs[i]](nextBrd)) {
             var score = nextBrd.score();
             if (score > currScore)
-                maxWeight = Math.max(maxWeight, this.evalFn(nextBrd));
+                maxUtility = Math.max(maxUtility, this.evalFn(nextBrd));
         }
     }
-    return maxWeight;
+    return maxUtility;
 }
 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
 ai.StaticDeepMerges.prototype.cleanup = function() { }
@@ -336,7 +336,7 @@
 ////////////////////////////////////////////////////////////////
 
 /**
- * Defines coefficient for linear resulted weight function.
+ * Defines coefficient for linear resulted utility function.
  * @name ai.expectimax.cfg
  * @namespace
  * @property {number} scoreCoef    multiplicator for score
@@ -362,7 +362,7 @@
         this.cfg.depth = ai.expectimax.bestCfg.depth;
 }
 ai.expectimax.bestCfg = {balance: .9, depth: 5, scoreCoef: 1, maxValCoef: 0, cornerBonus: 0, edgeBonus: 0, freeBonus: 0};
-ai.expectimax.prototype.weight = function(brd) {
+ai.expectimax.prototype.utility = function(brd) {
     var score = 0;
     var cfg = this.cfg;
     if (cfg.scoreCoef > 0)
@@ -409,7 +409,7 @@
 }
 ai.expectimax.prototype.evalFn = function(brd, depth) {
     if (depth >= this.depthLimit)
-        return this.weight(brd);
+        return this.utility(brd);
     var wCached = this.brdCache.get(brd);
     if (wCached)
         return wCached;
@@ -453,7 +453,7 @@
 ////////////////////////////////////////////////////////////////
 
 /**
- * Defines coefficient for linear resulted weight function.
+ * Defines coefficient for linear resulted utility function.
  * @name ai.survive.cfg
  * @namespace
  * @property {number} scoreCoef    multiplicator for score
@@ -478,7 +478,7 @@
     this.cfg.altAI = new ai.StaticDeepMerges(brd, ai.survive.altAICfg);
 }
 ai.survive.bestCfg = {freeCells: 8, maxDepth: 5};
-ai.survive.altAICfg = {scoreCoef: 1, maxValCoef: 0, cornerBonus: 0, edgeBonus: 0, freeBonus: 0, weightThreshold: 0};
+ai.survive.altAICfg = {scoreCoef: 1, maxValCoef: 0, cornerBonus: 0, edgeBonus: 0, freeBonus: 0, utilityThreshold: 0};
 /** Select best direction for next step. */
 ai.survive.prototype.analyse = function(brd2d) {
     var origBrd = new this.brd(brd2d);
@@ -573,19 +573,19 @@
 ai.MonteCarlo.prototype.analyse = function(brd2d) {
     var origBrd = new this.brd(brd2d);
     var nextBrd = new this.brd();
-    var bestW = - this.cfg.simulations;
+    var bestUtility = - this.cfg.simulations;
     var bestDir;
     var freeCnt = origBrd.freeCnt();
     for (var i = 0; i < ai.dirs.length; i++) {
         var dir = ai.dirs[i];
         if (origBrd[dir](nextBrd)) {
-            var w = 0;
+            var utility = 0;
             for (var gameCnt = this.cfg.simulations; gameCnt > 0; gameCnt--) {
                 var tmpBrd = nextBrd.copy();
-                w += this.play(tmpBrd, this.cfg.maxDepth);
+                utility += this.play(tmpBrd, this.cfg.maxDepth);
             }
-            if (w > bestW) {
-                bestW = w;
+            if (utility > bestUtility) {
+                bestUtility = utility;
                 bestDir = dir;
             }
         }
@@ -608,17 +608,17 @@
     return -1;
 }
 ai.MonteCarlo.prototype.evalFn = function(brd) {
-    var w = 0;
+    var utility = 0;
     if (this.cfg.freeBonus > 0)
-        w += this.cfg.freeBonus * brd.freeCnt();
+        utility += this.cfg.freeBonus * brd.freeCnt();
     var max = brd.maxVal();
     if (max > 7) {
         if (this.cfg.cornerBonus > 0 && brd.atCorner(max))
-            w += this.cfg.cornerBonus;
+            utility += this.cfg.cornerBonus;
         if (this.cfg.edgeBonus > 0 && brd.atEdge(max))
-            w += this.cfg.edgeBonus;
+            utility += this.cfg.edgeBonus;
     }
-    return w;
+    return utility;
 }
 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
 ai.MonteCarlo.prototype.cleanup = function() {