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