ai.js
author Oleksandr Gavenko <gavenkoa@gmail.com>
Tue, 09 Sep 2014 19:54:11 +0300
changeset 28 caf0be6d7e68
parent 27 8f96d09a4d94
child 29 30a09d50ae21
permissions -rw-r--r--
Remove debug output.
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 = {};
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
     4
ai.dirs = ["up", "down", "left", "right"];
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
     5
ai.canDirs = ["canUp", "canDown", "canLeft", "canRight"];
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
     6
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
     7
// 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
     8
// 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
     9
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    10

10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    11
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    12
////////////////////////////////////////////////////////////////
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    13
// Random AI.
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    14
////////////////////////////////////////////////////////////////
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    15
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    16
ai.random = function(brdEngine) {
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    17
    this.brdEngine = brdEngine;
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    18
}
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    19
ai.random.prototype.analyse = function(brd) {
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    20
    var origBrd = new this.brdEngine(brd);
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    21
    while (true) {
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    22
        var rnd = Math.floor(Math.random()*4);
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    23
        if (origBrd[["canUp", "canDown", "canLeft", "canRight"][rnd]]())
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    24
            return ["up", "down", "left", "right"][rnd];
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    25
    }
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    26
}
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    27
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    28
ai.random.prototype.cleanup = function() { }
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    29
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    30

10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    31
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    32
////////////////////////////////////////////////////////////////
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    33
// Blind cycle AI.
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    34
////////////////////////////////////////////////////////////////
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    35
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    36
ai.blindCycle = function(brdEngine, cfg) {
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    37
    this.brdEngine = brdEngine;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    38
    this.cfg = cfg || {};
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    39
    this.cfg.untilPossible = this.cfg.untilPossible || false;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    40
    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
    41
}
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    42
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
    43
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
    44
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
    45
    if (this.cfg.clockwise)
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    46
        return (dir + (4-1)) % 4;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    47
    else
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    48
        return (dir + 1) % 4;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    49
}
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    50
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
    51
    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
    52
    this.prevDir = this.prevDir || 0;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    53
    if (!this.cfg.untilPossible)
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    54
        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
    55
    while (true) {
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    56
        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
    57
            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
    58
        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
    59
    }
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    60
}
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    61
/* 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
    62
ai.blindCycle.prototype.cleanup = function() {
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    63
    delete this.prevDir;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    64
}
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    65
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    66

8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    67
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
    68
////////////////////////////////////////////////////////////////
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    69
// 1 level deep on max scores.
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    70
////////////////////////////////////////////////////////////////
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    71
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    72
ai.nextMaxScore = function(brdEngine) {
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    73
    this.brdEngine = brdEngine;
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    74
}
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    75
ai.nextMaxScore.prototype.analyse = function(brd) {
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    76
    var origBrd = new this.brdEngine(brd);
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    77
    var nextBrd = new this.brdEngine();
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    78
    var maxScore = -1;
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
    79
    var bestDir;
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
    80
    for (var i = 0; i < ai.dirs.length; i++) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
    81
        var dir = ai.dirs[i];
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
    82
        if (origBrd[dir](nextBrd)) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
    83
            var score = nextBrd.score();
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
    84
            if (maxScore < score) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
    85
                bestDir = dir;
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
    86
                maxScore = score;
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
    87
            }
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    88
        }
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    89
    }
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
    90
    return bestDir;
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    91
}
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    92
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    93
ai.nextMaxScore.prototype.cleanup = function() { }
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    94
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    95

10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    96
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    97
////////////////////////////////////////////////////////////////
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    98
// 1 level deep on max value.
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    99
////////////////////////////////////////////////////////////////
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   100
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   101
ai.nextMaxValue = function(brdEngine) {
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   102
    this.brdEngine = brdEngine;
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   103
}
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   104
ai.nextMaxValue.prototype.analyse = function(brd) {
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   105
    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
   106
    var nextBrd = new this.brdEngine();
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   107
    var maxMax = -1;
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   108
    var bestDir;
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   109
    for (var i = 0; i < ai.dirs.length; i++) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   110
        var dir = ai.dirs[i];
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   111
        if (origBrd[dir](nextBrd)) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   112
            var max = nextBrd.score();
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   113
            if (maxMax < max) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   114
                maxMax = max;
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   115
                bestDir = dir;
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   116
            }
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   117
        }
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   118
    }
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   119
    return bestDir;
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   120
}
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   121
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
24
079bcd734b68 Fix: TypeError: ui.ai.current.cleanup is not a function
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 21
diff changeset
   122
ai.nextMaxValue.prototype.cleanup = function() { }
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   123
24
079bcd734b68 Fix: TypeError: ui.ai.current.cleanup is not a function
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 21
diff changeset
   124

14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   125
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   126
////////////////////////////////////////////////////////////////
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
   127
// 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
   128
////////////////////////////////////////////////////////////////
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   129
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   130
ai.deepMaxScore = function(brdEngine) {
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   131
    this.brdEngine = brdEngine;
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   132
}
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   133
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
   134
    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
   135
    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
   136
    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
   137
    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
   138
    var bestDir;
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   139
    for (var i = 0; i < ai.dirs.length; i++) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   140
        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
   141
        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
   142
            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
   143
            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
   144
            // 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
   145
            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
   146
                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
   147
                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
   148
                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
   149
            }
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   150
        }
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   151
    }
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
   152
    return bestDir;
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   153
}
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   154
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
   155
    if (seenBrds) {
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   156
        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
   157
            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
   158
                return 0;
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   159
    } else {
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   160
        seenBrds = [];
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   161
    }
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   162
    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
   163
    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
   164
    var maxScore = currScore;
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   165
    var nextBrd = new this.brdEngine();
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   166
    for (var i = 0; i < ai.dirs.length; i++) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   167
        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
   168
            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
   169
            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
   170
                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
   171
        }
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   172
    }
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   173
    return maxScore;
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   174
}
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   175
/* 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
   176
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
   177
24
079bcd734b68 Fix: TypeError: ui.ai.current.cleanup is not a function
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 21
diff changeset
   178

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
   179
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   180
////////////////////////////////////////////////////////////////
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   181
// 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
   182
// 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
   183
////////////////////////////////////////////////////////////////
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   184
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   185
/* 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
   186
/* 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
   187
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
   188
    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
   189
    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
   190
    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
   191
    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
   192
    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
   193
}
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   194
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
   195
    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
   196
    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
   197
    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
   198
        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
   199
    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
   200
        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
   201
    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
   202
    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
   203
}
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   204
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
   205
    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
   206
    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
   207
    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
   208
        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
   209
    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
   210
    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
   211
}
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   212
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
   213
    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
   214
    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
   215
    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
   216
    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
   217
    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
   218
    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
   219
        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
   220
        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
   221
            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
   222
            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
   223
            // 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
   224
            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
   225
                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
   226
                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
   227
                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
   228
            }
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
        }
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
    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
   232
}
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
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
   234
    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
   235
        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
   236
            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
   237
                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
   238
    } 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
   239
        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
   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
    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
   242
    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
   243
    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
   244
    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
   245
    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
   246
        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
   247
            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
   248
            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
   249
                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
   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
    }
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
    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
   253
}
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
/* 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
   255
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
   256
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   257
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   258
////////////////////////////////////////////////////////////////
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   259
// N level deep with random simulation.
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   260
////////////////////////////////////////////////////////////////
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   261
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   262
/* cfg.cornerBonus - value to add if max value at corner. */
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   263
/* cfg.edgeBonus - value to add if max value at edge. */
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   264
ai.expectimax = function(brdEngine, cfg) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   265
    this.brdEngine = brdEngine;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   266
    this.cfg = cfg || {};
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   267
    this.cfg.balance = this.cfg.balance || .9;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   268
    if (!this.cfg.depth || this.cfg.depth < 0 || 8 <= this.cfg.depth)
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   269
        this.cfg.depth = 5;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   270
    this.cfg.cornerBonus = this.cfg.cornerBonus || 20000;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   271
    this.cfg.edgeBonus = this.cfg.edgeBonus || 100;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   272
    this.cfg.freeBonus = this.cfg.edgeBonus || 100;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   273
    this.cfg.weightPriority = this.cfg.weightPriority || 10;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   274
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   275
ai.expectimax.prototype.lvl1Score = function(brd) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   276
    var score = brd.score();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   277
    var max = brd.max();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   278
    if (brd.atCorner(max))
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   279
        score += this.cfg.cornerBonus;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   280
    else if (brd.atEdge(max))
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   281
        score += this.cfg.edgeBonus;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   282
    score += brd.free() * this.cfg.freeBonus;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   283
    return score;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   284
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   285
ai.expectimax.prototype.lvlnScore = function(brd) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   286
    var score = brd.score();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   287
    // var max = brd.max();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   288
    // if (brd.atCorner(max))
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   289
    //     score += this.cfg.cornerBonus;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   290
    // else if (brd.atEdge(max))
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   291
    //     score += this.cfg.edgeBonus;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   292
    // score += brd.free() * this.cfg.freeBonus;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   293
    return score;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   294
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   295
ai.expectimax.prototype.analyse = function(brd) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   296
    var origBrd = new this.brdEngine(brd);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   297
    var nextBrd = new this.brdEngine();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   298
    var prevScore = -1, nextScore = -1;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   299
    var maxWeight = -1;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   300
    var bestDir;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   301
    this.cleanup();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   302
    for (var i = 0; i < ai.dirs.length; i++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   303
        var dir = ai.dirs[i];
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   304
        if (origBrd[dir](nextBrd)) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   305
            nextScore = this.lvl1Score(nextBrd);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   306
            var weight = this.weight(nextBrd, 0);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   307
            // 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
   308
            if (maxWeight + this.cfg.weightPriority < weight || (maxWeight <= weight && prevScore < nextScore)) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   309
                prevScore = nextScore;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   310
                maxWeight = weight;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   311
                bestDir = dir;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   312
            }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   313
        }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   314
    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   315
    this.cleanup();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   316
    return bestDir;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   317
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   318
ai.expectimax.prototype.weight = function(brd, depth) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   319
    if (depth === this.cfg.depth)
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   320
        return this.lvlnScore(brd);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   321
    if (this.cache[depth]) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   322
        var cache = this.cache[depth];
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   323
        for (var i = cache.length-1; i >= 0; i--) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   324
            if (brd.equals(cache[i].brd))
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   325
                return cache[i].weight;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   326
        }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   327
    } else {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   328
        this.cache[depth] = [];
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   329
    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   330
    var weight = 0;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   331
    var free = 0;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   332
    for (var i = 0; i < 3; i++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   333
        for (var j = 0; j < 3; j++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   334
            if (brd.get(i, j) === 0) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   335
                var randBoard = brd.copy();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   336
                randBoard.set(i, j, 1);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   337
                var nextBrd = new this.brdEngine();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   338
                var n = 0, w = 0;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   339
                for (var diri = 0; diri < ai.dirs.length; diri++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   340
                    if (randBoard[ai.dirs[diri]](nextBrd)) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   341
                        w += this.weight(nextBrd, depth+1);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   342
                        n++;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   343
                    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   344
                }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   345
                if (n > 0)
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   346
                    w = w / n;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   347
                weight += this.cfg.balance * w;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   348
                randBoard.set(i, j, 2);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   349
                var n = 0, w = 0;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   350
                for (var diri = 0; diri < ai.dirs.length; diri++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   351
                    if (randBoard[ai.dirs[diri]](nextBrd)) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   352
                        w += this.weight(nextBrd, depth+1);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   353
                        n++;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   354
                    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   355
                }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   356
                if (n > 0)
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   357
                    w = w / n;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   358
                weight += this.cfg.balance * w;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   359
                free++;
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
    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   363
    if (free > 0)
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   364
        weight = weight / free;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   365
    this.cache[depth].push({brd: brd, weight: weight});
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   366
    return weight;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   367
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   368
/* 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
   369
ai.expectimax.prototype.cleanup = function() {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   370
    this.cache = [];
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   371
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   372