ai.js
author Oleksandr Gavenko <gavenkoa@gmail.com>
Thu, 11 Sep 2014 19:22:04 +0300
changeset 53 ee53cd2cb69a
parent 36 a18fc2601ce8
child 54 2c389325d13b
permissions -rw-r--r--
Join all one step deep AIs into one with linear weight function.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
     1
"use strict";
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
     2
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
     3
var ai = {};
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
     4
ai.dirs = ["up", "right", "down", "left"];
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
     5
ai.canDirs = ["canUp", "canRight", "canDown", "canLeft"];
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
     6
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
     7
/* Create empty 'to' if argument missing. */
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
     8
ai.copyObj = function(from, to) {
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
     9
    if (to == null || typeof to !== "object")
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    10
        to = {};
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    11
    if (from == null || typeof obj !== "object")
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    12
        return to;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    13
    for (var attr in cfg) {
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    14
        if (from.hasOwnProperty(attr))
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    15
            to[attr] = from[attr];
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    16
    }
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    17
    return to;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    18
}
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    19
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    20
// Each strategy is a function that except current board position as 2d array and context from
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    21
// previous call to share state/precomputed values between calls.
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    22
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    23

10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    24
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    25
////////////////////////////////////////////////////////////////
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    26
// Blind random AI.
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    27
////////////////////////////////////////////////////////////////
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    28
35
3d56325d7002 Rename AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 29
diff changeset
    29
ai.blindRandom = function(brdEngine) {
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    30
    this.brdEngine = brdEngine;
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    31
}
35
3d56325d7002 Rename AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 29
diff changeset
    32
ai.blindRandom.prototype.analyse = function(brd) {
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    33
    var origBrd = new this.brdEngine(brd);
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    34
    while (true) {
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    35
        var rnd = Math.floor(Math.random()*4);
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    36
        if (origBrd[ai.canDirs[rnd]]())
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    37
            return ai.dirs[rnd];
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    38
    }
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    39
}
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    40
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
35
3d56325d7002 Rename AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 29
diff changeset
    41
ai.blindRandom.prototype.cleanup = function() { }
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    42
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    43

10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    44
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    45
////////////////////////////////////////////////////////////////
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    46
// Blind weight random AI.
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    47
////////////////////////////////////////////////////////////////
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    48
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    49
ai.blindWeightRandom = function(brdEngine, cfg) {
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    50
    this.brdEngine = brdEngine;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    51
    this.cfg = this.cfg || {};
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    52
    var left = ai.blindWeightRandom.fixWeight(this.cfg.left);
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    53
    var right = ai.blindWeightRandom.fixWeight(this.cfg.right);
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    54
    var up = ai.blindWeightRandom.fixWeight(this.cfg.up);
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    55
    var down = ai.blindWeightRandom.fixWeight(this.cfg.down);
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    56
    var total = left + right + up + down;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    57
    this.threshold1 = left/total;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    58
    this.threshold2 = (left+down)/total;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    59
    this.threshold3 = (left+down+right)/total;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    60
}
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    61
ai.blindWeightRandom.fixWeight = function(val) {
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    62
    val = val && parseFloat(v) || 1;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    63
    if (val <= 0)
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    64
        val = 1;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    65
    return val;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    66
}
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    67
ai.blindWeightRandom.prototype.analyse = function(brd) {
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    68
    var origBrd = new this.brdEngine(brd);
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    69
    while (true) {
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    70
        var rnd = Math.random();
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    71
        if (rnd < this.threshold1)
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    72
            var dir = 0;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    73
        else if (rnd < this.threshold2)
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    74
            var dir = 1;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    75
        else if (rnd < this.threshold3)
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    76
            var dir = 2;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    77
        else
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    78
            var dir = 3;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    79
        if (origBrd[ai.canDirs[dir]]())
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    80
            return ai.dirs[dir];
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    81
    }
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    82
}
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    83
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    84
ai.blindWeightRandom.prototype.cleanup = function() { }
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    85
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    86

a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    87
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    88
////////////////////////////////////////////////////////////////
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    89
// Blind cycle AI.
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    90
////////////////////////////////////////////////////////////////
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    91
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    92
ai.blindCycle = function(brdEngine, cfg) {
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    93
    this.brdEngine = brdEngine;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    94
    this.cfg = cfg || {};
29
30a09d50ae21 Fix typo.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 28
diff changeset
    95
    this.cfg.whilePossible = this.cfg.whilePossible || false;
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    96
    this.cfg.clockwise = this.cfg.clockwise || false;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    97
}
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    98
ai.blindCycle.dirs = ["left", "down", "right", "up"];
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    99
ai.blindCycle.canDirs = ["canLeft", "canDown", "canRight", "canUp"];
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   100
ai.blindCycle.prototype.nextDir = function(dir) {
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   101
    if (this.cfg.clockwise)
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   102
        return (dir + (4-1)) % 4;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   103
    else
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   104
        return (dir + 1) % 4;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   105
}
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   106
ai.blindCycle.prototype.analyse = function(brd) {
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   107
    var origBrd = new this.brdEngine(brd);
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   108
    this.prevDir = this.prevDir || 0;
29
30a09d50ae21 Fix typo.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 28
diff changeset
   109
    if (!this.cfg.whilePossible)
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   110
        this.prevDir = this.nextDir(this.prevDir);
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   111
    while (true) {
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   112
        if (origBrd[ai.blindCycle.canDirs[this.prevDir]]())
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   113
            return ai.blindCycle.dirs[this.prevDir];
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   114
        this.prevDir = this.nextDir(this.prevDir);
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   115
    }
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   116
}
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   117
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   118
ai.blindCycle.prototype.cleanup = function() {
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   119
    delete this.prevDir;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   120
}
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   121
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   122

8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   123
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   124
////////////////////////////////////////////////////////////////
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   125
// 1 step deep with linear weight function on score, max value,
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   126
// bonuses for max value stay at corner or edge and bonuses
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   127
// for each free field.
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   128
////////////////////////////////////////////////////////////////
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   129
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   130
ai.oneStepDeep = function(brdEngine, cfg) {
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   131
    this.brdEngine = brdEngine;
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   132
    this.cfg = ai.copyObj(ai.oneStepDeep.bestCfg);
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   133
    ai.copyObj(cfg, this.cfg);
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   134
}
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   135
ai.oneStepDeep.bestCfg = {scoreCoef: 1, maxValCoef: 0, cornerBonus: 0, edgeBonus: 0, freeBonus: 0};
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   136
ai.oneStepDeep.prototype.weight = function(brd) {
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   137
    var weight = 0;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   138
    if (this.cfg.scoreCoef > 0)
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   139
        weight += this.cfg.scoreCoef * brd.score();
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   140
    var max = brd.max();
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   141
    if (this.cfg.maxValCoef > 0)
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   142
        weight += this.cfg.maxValCoef * max;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   143
    if (this.cfg.cornerBonus > 0 && brd.atCorner(max))
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   144
        weight += this.cfg.cornerBonus;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   145
    if (this.cfg.edgeBonus > 0 && brd.atEdge(max))
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   146
        weight += this.cfg.edgeBonus;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   147
    if (this.cfg.freeBonus > 0)
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   148
        weight += this.cfg.freeBonus * brd.free();
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   149
    return weight;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   150
}
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   151
ai.oneStepDeep.prototype.analyse = function(brd) {
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   152
    var origBrd = new this.brdEngine(brd);
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   153
    var nextBrd = new this.brdEngine();
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   154
    var maxWeight = -1;
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   155
    var bestDir;
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   156
    for (var i = 0; i < ai.dirs.length; i++) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   157
        var dir = ai.dirs[i];
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   158
        if (origBrd[dir](nextBrd)) {
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   159
            var weight = this.weight(nextBrd);
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   160
            if (maxWeight < weight) {
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   161
                bestDir = dir;
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   162
                maxWeight = weight;
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   163
            }
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   164
        }
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   165
    }
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   166
    return bestDir;
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   167
}
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   168
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   169
ai.oneStepDeep.prototype.cleanup = function() { }
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   170
24
079bcd734b68 Fix: TypeError: ui.ai.current.cleanup is not a function
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 21
diff changeset
   171

14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   172
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   173
////////////////////////////////////////////////////////////////
18
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   174
// N level deep on score value without random simulation.
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   175
////////////////////////////////////////////////////////////////
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   176
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   177
ai.deepMaxScore = function(brdEngine) {
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   178
    this.brdEngine = brdEngine;
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   179
}
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   180
ai.deepMaxScore.prototype.analyse = function(brd) {
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   181
    var origBrd = new this.brdEngine(brd);
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   182
    var nextBrd = new this.brdEngine();
18
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   183
    var prevScore = -1, nextScore = -1;
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   184
    var maxScore = -1;
18
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   185
    var bestDir;
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   186
    for (var i = 0; i < ai.dirs.length; i++) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   187
        var dir = ai.dirs[i];
18
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   188
        if (origBrd[dir](nextBrd)) {
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   189
            nextScore = nextBrd.score();
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   190
            var score = this.bestScore(nextBrd);
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   191
            // console.log("dir: %o, prevScore: %o, nextScore: %o, maxScore: %o, score: %o", dir, prevScore, nextScore, maxScore, score);
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   192
            if (maxScore < score || (maxScore === score && prevScore < nextScore)) {
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   193
                prevScore = nextScore;
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   194
                maxScore = score;
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   195
                bestDir = dir;
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   196
            }
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   197
        }
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   198
    }
18
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   199
    return bestDir;
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   200
}
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   201
ai.deepMaxScore.prototype.bestScore = function(brd, seenBrds) {
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   202
    if (seenBrds) {
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   203
        for (var i = 0; i < seenBrds.length; i++)
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   204
            if (brd.equals(seenBrds[i]))
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   205
                return 0;
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   206
    } else {
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   207
        seenBrds = [];
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   208
    }
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   209
    seenBrds.push(brd);
18
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   210
    var currScore = brd.score();
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   211
    var maxScore = currScore;
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   212
    var nextBrd = new this.brdEngine();
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   213
    for (var i = 0; i < ai.dirs.length; i++) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   214
        if (brd[ai.dirs[i]](nextBrd)) {
18
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   215
            var score = nextBrd.score();
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   216
            if (score > currScore)
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   217
                maxScore = Math.max(maxScore, this.bestScore(nextBrd, seenBrds));
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   218
        }
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   219
    }
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   220
    return maxScore;
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   221
}
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   222
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   223
ai.deepMaxScore.prototype.cleanup = function() { }
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   224
24
079bcd734b68 Fix: TypeError: ui.ai.current.cleanup is not a function
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 21
diff changeset
   225

20
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   226
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   227
////////////////////////////////////////////////////////////////
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   228
// N level deep on score value + max value prefer corner,
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   229
// without random simulation.
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   230
////////////////////////////////////////////////////////////////
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   231
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   232
/* cfg.cornerBonus - value to add if max value at corner. */
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   233
/* cfg.edgeBonus - value to add if max value at edge. */
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   234
ai.deepMaxScoreCorner = function(brdEngine, cfg) {
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   235
    this.brdEngine = brdEngine;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   236
    this.cfg = cfg || {};
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   237
    this.cfg.cornerBonus = this.cfg.cornerBonus || 20000;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   238
    this.cfg.edgeBonus = this.cfg.edgeBonus || 100;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   239
    this.cfg.freeBonus = this.cfg.edgeBonus || 100;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   240
}
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   241
ai.deepMaxScoreCorner.prototype.scoreCorner = function(brd) {
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   242
    var score = brd.score();
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   243
    var max = brd.max();
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   244
    if (brd.atCorner(max))
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   245
        score += this.cfg.cornerBonus;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   246
    else if (brd.atEdge(max))
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   247
        score += this.cfg.edgeBonus;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   248
    score += brd.free() * this.cfg.freeBonus;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   249
    return score;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   250
}
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   251
ai.deepMaxScoreCorner.prototype.scoreEdge = function(brd) {
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   252
    var score = brd.score();
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   253
    var max = brd.max();
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   254
    if (brd.atEdge(max))
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   255
        score += this.cfg.edgeBonus;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   256
    score += brd.free() * this.cfg.freeBonus;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   257
    return score;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   258
}
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   259
ai.deepMaxScoreCorner.prototype.analyse = function(brd) {
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   260
    var origBrd = new this.brdEngine(brd);
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   261
    var nextBrd = new this.brdEngine();
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   262
    var prevScore = -1, nextScore = -1;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   263
    var maxScore = -1;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   264
    var bestDir;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   265
    for (var i = 0; i < ai.dirs.length; i++) {
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   266
        var dir = ai.dirs[i];
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   267
        if (origBrd[dir](nextBrd)) {
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   268
            nextScore = this.scoreCorner(nextBrd);
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   269
            var score = this.bestScore(nextBrd);
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   270
            // console.log("dir: %o, prevScore: %o, nextScore: %o, maxScore: %o, score: %o", dir, prevScore, nextScore, maxScore, score);
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   271
            if (maxScore < score || (maxScore === score && prevScore < nextScore)) {
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   272
                prevScore = nextScore;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   273
                maxScore = score;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   274
                bestDir = dir;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   275
            }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   276
        }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   277
    }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   278
    return bestDir;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   279
}
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   280
ai.deepMaxScoreCorner.prototype.bestScore = function(brd, seenBrds) {
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   281
    if (seenBrds) {
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   282
        for (var i = 0; i < seenBrds.length; i++)
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   283
            if (brd.equals(seenBrds[i]))
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   284
                return 0;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   285
    } else {
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   286
        seenBrds = [];
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   287
    }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   288
    seenBrds.push(brd);
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   289
    var currScore = this.scoreEdge(brd);
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   290
    var maxScore = currScore;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   291
    var nextBrd = new this.brdEngine();
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   292
    for (var i = 0; i < ai.dirs.length; i++) {
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   293
        if (brd[ai.dirs[i]](nextBrd)) {
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   294
            var score = this.scoreEdge(nextBrd);
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   295
            if (score > currScore)
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   296
                maxScore = Math.max(maxScore, this.bestScore(nextBrd, seenBrds));
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   297
        }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   298
    }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   299
    return maxScore;
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   300
}
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   301
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   302
ai.deepMaxScoreCorner.prototype.cleanup = function() { }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   303
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   304
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   305
////////////////////////////////////////////////////////////////
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   306
// N level deep with random simulation.
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   307
////////////////////////////////////////////////////////////////
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   308
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   309
/* cfg.cornerBonus - value to add if max value at corner. */
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   310
/* cfg.edgeBonus - value to add if max value at edge. */
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   311
ai.expectimax = function(brdEngine, cfg) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   312
    this.brdEngine = brdEngine;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   313
    this.cfg = cfg || {};
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   314
    this.cfg.balance = this.cfg.balance || .9;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   315
    if (!this.cfg.depth || this.cfg.depth < 0 || 8 <= this.cfg.depth)
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   316
        this.cfg.depth = 5;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   317
    this.cfg.cornerBonus = this.cfg.cornerBonus || 20000;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   318
    this.cfg.edgeBonus = this.cfg.edgeBonus || 100;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   319
    this.cfg.freeBonus = this.cfg.edgeBonus || 100;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   320
    this.cfg.weightPriority = this.cfg.weightPriority || 10;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   321
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   322
ai.expectimax.prototype.lvl1Score = function(brd) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   323
    var score = brd.score();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   324
    var max = brd.max();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   325
    if (brd.atCorner(max))
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   326
        score += this.cfg.cornerBonus;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   327
    else if (brd.atEdge(max))
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   328
        score += this.cfg.edgeBonus;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   329
    score += brd.free() * this.cfg.freeBonus;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   330
    return score;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   331
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   332
ai.expectimax.prototype.lvlnScore = function(brd) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   333
    var score = brd.score();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   334
    // var max = brd.max();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   335
    // if (brd.atCorner(max))
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   336
    //     score += this.cfg.cornerBonus;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   337
    // else if (brd.atEdge(max))
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   338
    //     score += this.cfg.edgeBonus;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   339
    // score += brd.free() * this.cfg.freeBonus;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   340
    return score;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   341
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   342
ai.expectimax.prototype.analyse = function(brd) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   343
    var origBrd = new this.brdEngine(brd);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   344
    var nextBrd = new this.brdEngine();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   345
    var prevScore = -1, nextScore = -1;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   346
    var maxWeight = -1;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   347
    var bestDir;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   348
    this.cleanup();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   349
    for (var i = 0; i < ai.dirs.length; i++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   350
        var dir = ai.dirs[i];
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   351
        if (origBrd[dir](nextBrd)) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   352
            nextScore = this.lvl1Score(nextBrd);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   353
            var weight = this.weight(nextBrd, 0);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   354
            // console.log("dir: %o, prevScore: %o, nextScore: %o, maxWeight: %o, weight: %o", dir, prevScore, nextScore, maxWeight, weight);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   355
            if (maxWeight + this.cfg.weightPriority < weight || (maxWeight <= weight && prevScore < nextScore)) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   356
                prevScore = nextScore;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   357
                maxWeight = weight;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   358
                bestDir = dir;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   359
            }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   360
        }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   361
    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   362
    this.cleanup();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   363
    return bestDir;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   364
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   365
ai.expectimax.prototype.weight = function(brd, depth) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   366
    if (depth === this.cfg.depth)
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   367
        return this.lvlnScore(brd);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   368
    if (this.cache[depth]) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   369
        var cache = this.cache[depth];
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   370
        for (var i = cache.length-1; i >= 0; i--) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   371
            if (brd.equals(cache[i].brd))
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   372
                return cache[i].weight;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   373
        }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   374
    } else {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   375
        this.cache[depth] = [];
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   376
    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   377
    var weight = 0;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   378
    var free = 0;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   379
    for (var i = 0; i < 3; i++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   380
        for (var j = 0; j < 3; j++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   381
            if (brd.get(i, j) === 0) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   382
                var randBoard = brd.copy();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   383
                randBoard.set(i, j, 1);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   384
                var nextBrd = new this.brdEngine();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   385
                var n = 0, w = 0;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   386
                for (var diri = 0; diri < ai.dirs.length; diri++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   387
                    if (randBoard[ai.dirs[diri]](nextBrd)) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   388
                        w += this.weight(nextBrd, depth+1);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   389
                        n++;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   390
                    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   391
                }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   392
                if (n > 0)
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   393
                    w = w / n;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   394
                weight += this.cfg.balance * w;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   395
                randBoard.set(i, j, 2);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   396
                var n = 0, w = 0;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   397
                for (var diri = 0; diri < ai.dirs.length; diri++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   398
                    if (randBoard[ai.dirs[diri]](nextBrd)) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   399
                        w += this.weight(nextBrd, depth+1);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   400
                        n++;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   401
                    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   402
                }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   403
                if (n > 0)
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   404
                    w = w / n;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   405
                weight += this.cfg.balance * w;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   406
                free++;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   407
            }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   408
        }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   409
    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   410
    if (free > 0)
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   411
        weight = weight / free;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   412
    this.cache[depth].push({brd: brd, weight: weight});
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   413
    return weight;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   414
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   415
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   416
ai.expectimax.prototype.cleanup = function() {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   417
    this.cache = [];
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   418
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   419