# HG changeset patch # User Oleksandr Gavenko # Date 1411559482 -10800 # Node ID 4a2551dd179d6156664e489e3df908afd421939f # Parent fc6019d22a382deb839b21cf95336cc453bc01b9 Fix: expectimax select best move which lead to less danger among all worst. diff -r fc6019d22a38 -r 4a2551dd179d ai.js --- a/ai.js Wed Sep 24 02:56:41 2014 +0300 +++ b/ai.js Wed Sep 24 14:51:22 2014 +0300 @@ -380,45 +380,33 @@ } else { this.cache[depth] = []; } - var weight = 0; - var free = 0; + var wMin = +Infinity; for (var i = 0; i < 3; i++) { for (var j = 0; j < 3; j++) { if (brd.get(i, j) === 0) { var randBoard = brd.copy(); randBoard.set(i, j, 1); var nextBrd = new this.brdEngine(); - var n = 0, w = 0; + var wMax2 = 0; for (var diri = 0; diri < ai.dirs.length; diri++) { - if (randBoard[ai.dirs[diri]](nextBrd)) { - w += this.evalFn(nextBrd, depth+1); - n++; - } + if (randBoard[ai.dirs[diri]](nextBrd)) + wMax2 = Math.max(wMax2, this.evalFn(nextBrd, depth+1)); } - if (n > 0) - w = w / n; - weight += this.cfg.balance * w; + var wMax4 = 0; if (this.cfg.balance < 1) { randBoard.set(i, j, 2); - var n = 0, w = 0; for (var diri = 0; diri < ai.dirs.length; diri++) { - if (randBoard[ai.dirs[diri]](nextBrd)) { - w += this.evalFn(nextBrd, depth+1); - n++; - } + if (randBoard[ai.dirs[diri]](nextBrd)) + wMax4 = Math.max(wMax4, this.evalFn(nextBrd, depth+1)); } - if (n > 0) - w = w / n; - weight += this.cfg.balance * w; + var balance = this.cfg.balance; } - free++; + wMin = Math.min(wMin, balance * wMax2 + (1 - balance) * wMax4); } } } - if (free > 0) - weight = weight / free; - this.cache[depth].push({brd: brd, weight: weight}); - return weight; + this.cache[depth].push({brd: brd, weight: wMin}); + return wMin; } /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */ ai.expectimax.prototype.cleanup = function() {