ai.js
changeset 19 94a4201d27a3
parent 18 42d62e5123b2
child 20 ab294e8db00c
equal deleted inserted replaced
18:42d62e5123b2 19:94a4201d27a3
     1 "use strict";
     1 "use strict";
     2 
     2 
     3 var ai = {};
     3 var ai = {};
       
     4 ai.dirs = ["up", "down", "left", "right"];
     4 
     5 
     5 // Each strategy is a function that except current board position as 2d array and context from
     6 // Each strategy is a function that except current board position as 2d array and context from
     6 // previous call to share state/precomputed values between calls.
     7 // previous call to share state/precomputed values between calls.
     7 
     8 
     8 
     9 
    36 }
    37 }
    37 ai.nextMaxScore.prototype.analyse = function(brd) {
    38 ai.nextMaxScore.prototype.analyse = function(brd) {
    38     var origBrd = new this.brdEngine(brd);
    39     var origBrd = new this.brdEngine(brd);
    39     var nextBrd = new this.brdEngine();
    40     var nextBrd = new this.brdEngine();
    40     var maxScore = -1;
    41     var maxScore = -1;
    41     var action;
    42     var bestDir;
    42     if (origBrd.up(nextBrd)) {
    43     for (var i = 0; i < ai.dirs.length; i++) {
    43         maxScore = nextBrd.score();
    44         var dir = ai.dirs[i];
    44         action = "up";
    45         if (origBrd[dir](nextBrd)) {
    45     }
    46             var score = nextBrd.score();
    46     if (origBrd.left(nextBrd)) {
    47             if (maxScore < score) {
    47         var score = nextBrd.score();
    48                 bestDir = dir;
    48         if (maxScore < score) {
    49                 maxScore = score;
    49             action = "left";
    50             }
    50             maxScore = score;
       
    51         }
    51         }
    52     }
    52     }
    53     if (origBrd.down(nextBrd)) {
    53     return bestDir;
    54         var score = nextBrd.score();
       
    55         if (maxScore < score) {
       
    56             action = "down";
       
    57             maxScore = score;
       
    58         }
       
    59     }
       
    60     if (origBrd.right(nextBrd)) {
       
    61         var score = nextBrd.score();
       
    62         if (maxScore < score) {
       
    63             action = "right";
       
    64             maxScore = score;
       
    65         }
       
    66     }
       
    67     return action;
       
    68 }
    54 }
    69 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
    55 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
    70 ai.nextMaxScore.prototype.cleanup = function() { }
    56 ai.nextMaxScore.prototype.cleanup = function() { }
    71 
    57 
    72 
    58 
    80 }
    66 }
    81 ai.nextMaxValue.prototype.analyse = function(brd) {
    67 ai.nextMaxValue.prototype.analyse = function(brd) {
    82     var origBrd = new this.brdEngine(brd);
    68     var origBrd = new this.brdEngine(brd);
    83     var nextBrd = new this.brdEngine();
    69     var nextBrd = new this.brdEngine();
    84     var maxMax = -1;
    70     var maxMax = -1;
    85     var action;
    71     var bestDir;
    86     if (origBrd.up(nextBrd)) {
    72     for (var i = 0; i < ai.dirs.length; i++) {
    87         maxMax = nextBrd.max();
    73         var dir = ai.dirs[i];
    88         action = "up";
    74         if (origBrd[dir](nextBrd)) {
    89     }
    75             var max = nextBrd.score();
    90     if (origBrd.left(nextBrd)) {
    76             if (maxMax < max) {
    91         var max = nextBrd.score();
    77                 maxMax = max;
    92         if (maxMax < max) {
    78                 bestDir = dir;
    93             action = "left";
    79             }
    94             maxMax = max;
       
    95         }
    80         }
    96     }
    81     }
    97     if (origBrd.down(nextBrd)) {
    82     return bestDir;
    98         var max = nextBrd.max();
       
    99         if (maxMax < max) {
       
   100             action = "down";
       
   101             maxMax = max;
       
   102         }
       
   103     }
       
   104     if (origBrd.right(nextBrd)) {
       
   105         var max = nextBrd.max();
       
   106         if (maxMax < max) {
       
   107             action = "right";
       
   108             maxMax = max;
       
   109         }
       
   110     }
       
   111     return action;
       
   112 }
    83 }
   113 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
    84 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
   114 ai.nextMaxScore.prototype.cleanup = function() { }
    85 ai.nextMaxScore.prototype.cleanup = function() { }
   115 
    86 
   116 
    87 
   119 ////////////////////////////////////////////////////////////////
    90 ////////////////////////////////////////////////////////////////
   120 
    91 
   121 ai.deepMaxScore = function(brdEngine) {
    92 ai.deepMaxScore = function(brdEngine) {
   122     this.brdEngine = brdEngine;
    93     this.brdEngine = brdEngine;
   123 }
    94 }
   124 ai.deepMaxScore.dirs = ["up", "down", "left", "right"];
       
   125 ai.deepMaxScore.prototype.analyse = function(brd) {
    95 ai.deepMaxScore.prototype.analyse = function(brd) {
   126     var origBrd = new this.brdEngine(brd);
    96     var origBrd = new this.brdEngine(brd);
   127     var nextBrd = new this.brdEngine();
    97     var nextBrd = new this.brdEngine();
   128     var prevScore = -1, nextScore = -1;
    98     var prevScore = -1, nextScore = -1;
   129     var maxScore = -1;
    99     var maxScore = -1;
   130     var bestDir;
   100     var bestDir;
   131     for (var i = 0; i < ai.deepMaxScore.dirs.length; i++) {
   101     for (var i = 0; i < ai.dirs.length; i++) {
   132         var dir = ai.deepMaxScore.dirs[i];
   102         var dir = ai.dirs[i];
   133         if (origBrd[dir](nextBrd)) {
   103         if (origBrd[dir](nextBrd)) {
   134             nextScore = nextBrd.score();
   104             nextScore = nextBrd.score();
   135             var score = this.bestScore(nextBrd);
   105             var score = this.bestScore(nextBrd);
   136             // console.log("dir: %o, prevScore: %o, nextScore: %o, maxScore: %o, score: %o", dir, prevScore, nextScore, maxScore, score);
   106             // console.log("dir: %o, prevScore: %o, nextScore: %o, maxScore: %o, score: %o", dir, prevScore, nextScore, maxScore, score);
   137             if (maxScore < score || (maxScore === score && prevScore < nextScore)) {
   107             if (maxScore < score || (maxScore === score && prevScore < nextScore)) {
   153     }
   123     }
   154     seenBrds.push(brd);
   124     seenBrds.push(brd);
   155     var currScore = brd.score();
   125     var currScore = brd.score();
   156     var maxScore = currScore;
   126     var maxScore = currScore;
   157     var nextBrd = new this.brdEngine();
   127     var nextBrd = new this.brdEngine();
   158     for (var i = 0; i < ai.deepMaxScore.dirs.length; i++) {
   128     for (var i = 0; i < ai.dirs.length; i++) {
   159         if (brd[ai.deepMaxScore.dirs[i]](nextBrd)) {
   129         if (brd[ai.dirs[i]](nextBrd)) {
   160             var score = nextBrd.score();
   130             var score = nextBrd.score();
   161             if (score > currScore)
   131             if (score > currScore)
   162                 maxScore = Math.max(maxScore, this.bestScore(nextBrd, seenBrds));
   132                 maxScore = Math.max(maxScore, this.bestScore(nextBrd, seenBrds));
   163         }
   133         }
   164     }
   134     }
   165     return maxScore;
   135     return maxScore;
   166 }
   136 }
       
   137 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
       
   138 ai.deepMaxScore.prototype.cleanup = function() { }
   167 
   139