ai.js
changeset 109 6d5a9d8b00be
parent 104 47d42234dd5c
child 110 e3a91b336976
equal deleted inserted replaced
108:5f4985c2a4d4 109:6d5a9d8b00be
   227     var bestDir;
   227     var bestDir;
   228     for (var i = 0; i < ai.dirs.length; i++) {
   228     for (var i = 0; i < ai.dirs.length; i++) {
   229         var dir = ai.dirs[i];
   229         var dir = ai.dirs[i];
   230         if (origBrd[dir](nextBrd)) {
   230         if (origBrd[dir](nextBrd)) {
   231             nextScore = nextBrd.score();
   231             nextScore = nextBrd.score();
   232             var score = this.bestScore(nextBrd);
   232             var score = this.evalFn(nextBrd);
   233             // console.log("dir: %o, prevScore: %o, nextScore: %o, maxScore: %o, score: %o", dir, prevScore, nextScore, maxScore, score);
   233             // console.log("dir: %o, prevScore: %o, nextScore: %o, maxScore: %o, score: %o", dir, prevScore, nextScore, maxScore, score);
   234             if (maxScore < score || (maxScore === score && prevScore < nextScore)) {
   234             if (maxScore < score || (maxScore === score && prevScore < nextScore)) {
   235                 prevScore = nextScore;
   235                 prevScore = nextScore;
   236                 maxScore = score;
   236                 maxScore = score;
   237                 bestDir = dir;
   237                 bestDir = dir;
   238             }
   238             }
   239         }
   239         }
   240     }
   240     }
   241     return bestDir;
   241     return bestDir;
   242 }
   242 }
   243 ai.DeepMaxScore.prototype.bestScore = function(brd, seenBrds) {
   243 ai.DeepMaxScore.prototype.evalFn = function(brd, seenBrds) {
   244     if (seenBrds) {
   244     if (seenBrds) {
   245         for (var i = 0; i < seenBrds.length; i++)
   245         for (var i = 0; i < seenBrds.length; i++)
   246             if (brd.equals(seenBrds[i]))
   246             if (brd.equals(seenBrds[i]))
   247                 return 0;
   247                 return 0;
   248     } else {
   248     } else {
   254     var nextBrd = new this.brdEngine();
   254     var nextBrd = new this.brdEngine();
   255     for (var i = 0; i < ai.dirs.length; i++) {
   255     for (var i = 0; i < ai.dirs.length; i++) {
   256         if (brd[ai.dirs[i]](nextBrd)) {
   256         if (brd[ai.dirs[i]](nextBrd)) {
   257             var score = nextBrd.score();
   257             var score = nextBrd.score();
   258             if (score > currScore)
   258             if (score > currScore)
   259                 maxScore = Math.max(maxScore, this.bestScore(nextBrd, seenBrds));
   259                 maxScore = Math.max(maxScore, this.evalFn(nextBrd, seenBrds));
   260         }
   260         }
   261     }
   261     }
   262     return maxScore;
   262     return maxScore;
   263 }
   263 }
   264 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
   264 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
   319     var bestDir;
   319     var bestDir;
   320     for (var i = 0; i < ai.dirs.length; i++) {
   320     for (var i = 0; i < ai.dirs.length; i++) {
   321         var dir = ai.dirs[i];
   321         var dir = ai.dirs[i];
   322         if (origBrd[dir](nextBrd)) {
   322         if (origBrd[dir](nextBrd)) {
   323             nextScore = this.scoreCorner(nextBrd);
   323             nextScore = this.scoreCorner(nextBrd);
   324             var score = this.bestScore(nextBrd);
   324             var score = this.evalFn(nextBrd);
   325             // console.log("dir: %o, prevScore: %o, nextScore: %o, maxScore: %o, score: %o", dir, prevScore, nextScore, maxScore, score);
   325             // console.log("dir: %o, prevScore: %o, nextScore: %o, maxScore: %o, score: %o", dir, prevScore, nextScore, maxScore, score);
   326             if (maxScore < score || (maxScore === score && prevScore < nextScore)) {
   326             if (maxScore < score || (maxScore === score && prevScore < nextScore)) {
   327                 prevScore = nextScore;
   327                 prevScore = nextScore;
   328                 maxScore = score;
   328                 maxScore = score;
   329                 bestDir = dir;
   329                 bestDir = dir;
   330             }
   330             }
   331         }
   331         }
   332     }
   332     }
   333     return bestDir;
   333     return bestDir;
   334 }
   334 }
   335 ai.DeepMaxScoreCorner.prototype.bestScore = function(brd, seenBrds) {
   335 ai.DeepMaxScoreCorner.prototype.evalFn = function(brd, seenBrds) {
   336     if (seenBrds) {
   336     if (seenBrds) {
   337         for (var i = 0; i < seenBrds.length; i++)
   337         for (var i = 0; i < seenBrds.length; i++)
   338             if (brd.equals(seenBrds[i]))
   338             if (brd.equals(seenBrds[i]))
   339                 return 0;
   339                 return 0;
   340     } else {
   340     } else {
   346     var nextBrd = new this.brdEngine();
   346     var nextBrd = new this.brdEngine();
   347     for (var i = 0; i < ai.dirs.length; i++) {
   347     for (var i = 0; i < ai.dirs.length; i++) {
   348         if (brd[ai.dirs[i]](nextBrd)) {
   348         if (brd[ai.dirs[i]](nextBrd)) {
   349             var score = this.scoreEdge(nextBrd);
   349             var score = this.scoreEdge(nextBrd);
   350             if (score > currScore)
   350             if (score > currScore)
   351                 maxScore = Math.max(maxScore, this.bestScore(nextBrd, seenBrds));
   351                 maxScore = Math.max(maxScore, this.evalFn(nextBrd, seenBrds));
   352         }
   352         }
   353     }
   353     }
   354     return maxScore;
   354     return maxScore;
   355 }
   355 }
   356 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
   356 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
   413     var bestDir;
   413     var bestDir;
   414     this.cleanup();
   414     this.cleanup();
   415     for (var i = 0; i < ai.dirs.length; i++) {
   415     for (var i = 0; i < ai.dirs.length; i++) {
   416         var dir = ai.dirs[i];
   416         var dir = ai.dirs[i];
   417         if (origBrd[dir](nextBrd)) {
   417         if (origBrd[dir](nextBrd)) {
   418             var weight = this.recWeight(nextBrd, 1);
   418             var weight = this.evalFn(nextBrd, 1);
   419             var ok = (weight - maxWeight) > this.cfg.weightPriority;
   419             var ok = (weight - maxWeight) > this.cfg.weightPriority;
   420             if ( ! ok && maxWeight <= weight) {
   420             if ( ! ok && maxWeight <= weight) {
   421                 nextScore = this.weight(nextBrd);
   421                 nextScore = this.weight(nextBrd);
   422                 ok = prevScore < nextScore;
   422                 ok = prevScore < nextScore;
   423             }
   423             }
   429         }
   429         }
   430     }
   430     }
   431     this.cleanup();
   431     this.cleanup();
   432     return bestDir;
   432     return bestDir;
   433 }
   433 }
   434 ai.expectimax.prototype.recWeight = function(brd, depth) {
   434 ai.expectimax.prototype.evalFn = function(brd, depth) {
   435     if (depth >= this.cfg.depth)
   435     if (depth >= this.cfg.depth)
   436         return this.weight(brd);
   436         return this.weight(brd);
   437     if (this.cache[depth]) {
   437     if (this.cache[depth]) {
   438         var cache = this.cache[depth];
   438         var cache = this.cache[depth];
   439         for (var i = cache.length-1; i >= 0; i--) {
   439         for (var i = cache.length-1; i >= 0; i--) {
   452                 randBoard.set(i, j, 1);
   452                 randBoard.set(i, j, 1);
   453                 var nextBrd = new this.brdEngine();
   453                 var nextBrd = new this.brdEngine();
   454                 var n = 0, w = 0;
   454                 var n = 0, w = 0;
   455                 for (var diri = 0; diri < ai.dirs.length; diri++) {
   455                 for (var diri = 0; diri < ai.dirs.length; diri++) {
   456                     if (randBoard[ai.dirs[diri]](nextBrd)) {
   456                     if (randBoard[ai.dirs[diri]](nextBrd)) {
   457                         w += this.recWeight(nextBrd, depth+1);
   457                         w += this.evalFn(nextBrd, depth+1);
   458                         n++;
   458                         n++;
   459                     }
   459                     }
   460                 }
   460                 }
   461                 if (n > 0)
   461                 if (n > 0)
   462                     w = w / n;
   462                     w = w / n;
   464                 if (this.cfg.balance < 1) {
   464                 if (this.cfg.balance < 1) {
   465                     randBoard.set(i, j, 2);
   465                     randBoard.set(i, j, 2);
   466                     var n = 0, w = 0;
   466                     var n = 0, w = 0;
   467                     for (var diri = 0; diri < ai.dirs.length; diri++) {
   467                     for (var diri = 0; diri < ai.dirs.length; diri++) {
   468                         if (randBoard[ai.dirs[diri]](nextBrd)) {
   468                         if (randBoard[ai.dirs[diri]](nextBrd)) {
   469                             w += this.recWeight(nextBrd, depth+1);
   469                             w += this.evalFn(nextBrd, depth+1);
   470                             n++;
   470                             n++;
   471                         }
   471                         }
   472                     }
   472                     }
   473                     if (n > 0)
   473                     if (n > 0)
   474                         w = w / n;
   474                         w = w / n;