378 return cache[i].weight; |
378 return cache[i].weight; |
379 } |
379 } |
380 } else { |
380 } else { |
381 this.cache[depth] = []; |
381 this.cache[depth] = []; |
382 } |
382 } |
383 var weight = 0; |
383 var wMin = +Infinity; |
384 var free = 0; |
|
385 for (var i = 0; i < 3; i++) { |
384 for (var i = 0; i < 3; i++) { |
386 for (var j = 0; j < 3; j++) { |
385 for (var j = 0; j < 3; j++) { |
387 if (brd.get(i, j) === 0) { |
386 if (brd.get(i, j) === 0) { |
388 var randBoard = brd.copy(); |
387 var randBoard = brd.copy(); |
389 randBoard.set(i, j, 1); |
388 randBoard.set(i, j, 1); |
390 var nextBrd = new this.brdEngine(); |
389 var nextBrd = new this.brdEngine(); |
391 var n = 0, w = 0; |
390 var wMax2 = 0; |
392 for (var diri = 0; diri < ai.dirs.length; diri++) { |
391 for (var diri = 0; diri < ai.dirs.length; diri++) { |
393 if (randBoard[ai.dirs[diri]](nextBrd)) { |
392 if (randBoard[ai.dirs[diri]](nextBrd)) |
394 w += this.evalFn(nextBrd, depth+1); |
393 wMax2 = Math.max(wMax2, this.evalFn(nextBrd, depth+1)); |
395 n++; |
|
396 } |
|
397 } |
394 } |
398 if (n > 0) |
395 var wMax4 = 0; |
399 w = w / n; |
|
400 weight += this.cfg.balance * w; |
|
401 if (this.cfg.balance < 1) { |
396 if (this.cfg.balance < 1) { |
402 randBoard.set(i, j, 2); |
397 randBoard.set(i, j, 2); |
403 var n = 0, w = 0; |
|
404 for (var diri = 0; diri < ai.dirs.length; diri++) { |
398 for (var diri = 0; diri < ai.dirs.length; diri++) { |
405 if (randBoard[ai.dirs[diri]](nextBrd)) { |
399 if (randBoard[ai.dirs[diri]](nextBrd)) |
406 w += this.evalFn(nextBrd, depth+1); |
400 wMax4 = Math.max(wMax4, this.evalFn(nextBrd, depth+1)); |
407 n++; |
|
408 } |
|
409 } |
401 } |
410 if (n > 0) |
402 var balance = this.cfg.balance; |
411 w = w / n; |
|
412 weight += this.cfg.balance * w; |
|
413 } |
403 } |
414 free++; |
404 wMin = Math.min(wMin, balance * wMax2 + (1 - balance) * wMax4); |
415 } |
405 } |
416 } |
406 } |
417 } |
407 } |
418 if (free > 0) |
408 this.cache[depth].push({brd: brd, weight: wMin}); |
419 weight = weight / free; |
409 return wMin; |
420 this.cache[depth].push({brd: brd, weight: weight}); |
|
421 return weight; |
|
422 } |
410 } |
423 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */ |
411 /* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */ |
424 ai.expectimax.prototype.cleanup = function() { |
412 ai.expectimax.prototype.cleanup = function() { |
425 this.cache = []; |
413 this.cache = []; |
426 } |
414 } |