ai.js
author Oleksandr Gavenko <gavenkoa@gmail.com>
Sat, 20 Sep 2014 22:55:24 +0300
changeset 99 df4736e659f2
parent 74 93cb48b73b39
child 104 47d42234dd5c
permissions -rw-r--r--
Rename AI.
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
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
     3
/** @fileOverview AI modules. */
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
     4
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
     5
/** @module */
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
     6
var ai = {};
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
     7
/** Directions. @constant */
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
     8
ai.dirs = ["up", "right", "down", "left"];
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
     9
/** Possible direction function names. @constant */
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    10
ai.canDirs = ["canUp", "canRight", "canDown", "canLeft"];
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    11
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    12
/** Create empty 'to' if argument missing. */
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    13
ai.copyObj = function(from, to) {
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    14
    if (to == null || typeof to !== "object")
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    15
        to = {};
54
2c389325d13b Fix typo.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 53
diff changeset
    16
    if (from == null || typeof from !== "object")
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    17
        return to;
54
2c389325d13b Fix typo.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 53
diff changeset
    18
    for (var attr in from) {
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    19
        if (from.hasOwnProperty(attr))
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    20
            to[attr] = from[attr];
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    21
    }
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    22
    return to;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    23
}
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
    24
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    25
// 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
    26
// 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
    27
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    28

10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    29
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    30
////////////////////////////////////////////////////////////////
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    31
// Blind random AI.
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    32
////////////////////////////////////////////////////////////////
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    33
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    34
/** Blind random AI.
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    35
 * @param {Board} brdEngine  board engine from board.js
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    36
 * @constructor */
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
    37
ai.BlindRandom = function(brdEngine) {
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    38
    this.brdEngine = brdEngine;
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    39
}
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
    40
ai.BlindRandom.prototype.analyse = function(brd) {
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    41
    var origBrd = new this.brdEngine(brd);
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    42
    while (true) {
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    43
        var rnd = Math.floor(Math.random()*4);
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    44
        if (origBrd[ai.canDirs[rnd]]())
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    45
            return ai.dirs[rnd];
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    46
    }
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    47
}
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    48
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
    49
ai.BlindRandom.prototype.cleanup = function() { }
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    50
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
    51

10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    52
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
    53
////////////////////////////////////////////////////////////////
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    54
// Blind weight random AI.
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    55
////////////////////////////////////////////////////////////////
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    56
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    57
/**
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    58
 * @name ai.BlindWeightRandom.cfg
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    59
 * @namespace
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    60
 * @property {number} left   weight
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    61
 * @property {number} right  weight
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    62
 * @property {number} up     weight
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    63
 * @property {number} down   weight
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    64
 */
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    65
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    66
/** Blind weight random AI.
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    67
 * @param {Board} brdEngine  board engine from board.js
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    68
 * @param {ai.BlindWeightRandom.cfg} cfg  configuration settings
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
    69
 * @constructor */
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
    70
ai.BlindWeightRandom = function(brdEngine, cfg) {
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    71
    this.brdEngine = brdEngine;
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
    72
    this.cfg = ai.copyObj(ai.BlindWeightRandom.bestCfg);
56
76d257640b7d Merge config with best settings.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 54
diff changeset
    73
    ai.copyObj(cfg, this.cfg);
76d257640b7d Merge config with best settings.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 54
diff changeset
    74
    var total = this.cfg.left + this.cfg.right + this.cfg.up + this.cfg.down;
76d257640b7d Merge config with best settings.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 54
diff changeset
    75
    this.threshold1 = this.cfg.left/total;
76d257640b7d Merge config with best settings.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 54
diff changeset
    76
    this.threshold2 = (this.cfg.left + this.cfg.down)/total;
76d257640b7d Merge config with best settings.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 54
diff changeset
    77
    this.threshold3 = (this.cfg.left + this.cfg.down + this.cfg.right)/total;
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    78
}
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
    79
ai.BlindWeightRandom.bestCfg = { left: 1, down: 10, right: 5, up: 1 };
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
    80
ai.BlindWeightRandom.prototype.analyse = function(brd) {
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    81
    var origBrd = new this.brdEngine(brd);
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    82
    while (true) {
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    83
        var rnd = Math.random();
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    84
        if (rnd < this.threshold1)
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    85
            var dir = 0;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    86
        else if (rnd < this.threshold2)
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    87
            var dir = 1;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    88
        else if (rnd < this.threshold3)
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    89
            var dir = 2;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    90
        else
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    91
            var dir = 3;
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    92
        if (origBrd[ai.canDirs[dir]]())
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    93
            return ai.dirs[dir];
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    94
    }
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    95
}
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    96
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
    97
ai.BlindWeightRandom.prototype.cleanup = function() { }
36
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    98
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
    99

a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
   100
a18fc2601ce8 Add blind eight random AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 35
diff changeset
   101
////////////////////////////////////////////////////////////////
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   102
// Blind cycle AI.
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   103
////////////////////////////////////////////////////////////////
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   104
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   105
/**
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   106
 * @name ai.BlindCycle.cfg
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   107
 * @namespace
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   108
 * @property {boolean} whilePossible  move in one direction while possible
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   109
 * @property {boolean} down           switch direction clockwise
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   110
 */
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   111
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   112
/** Blind cycle AI.
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   113
 * @param {Board} brdEngine  board engine from board.js
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   114
 * @param {ai.BlindCycle.cfg} cfg  configuration settings
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   115
 * @constructor */
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   116
ai.BlindCycle = function(brdEngine, cfg) {
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   117
    this.brdEngine = brdEngine;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   118
    this.cfg = cfg || {};
29
30a09d50ae21 Fix typo.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 28
diff changeset
   119
    this.cfg.whilePossible = this.cfg.whilePossible || false;
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   120
    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
   121
}
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   122
ai.BlindCycle.dirs = ["left", "down", "right", "up"];
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   123
ai.BlindCycle.canDirs = ["canLeft", "canDown", "canRight", "canUp"];
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   124
ai.BlindCycle.prototype.nextDir = function(dir) {
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   125
    if (this.cfg.clockwise)
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   126
        return (dir + (4-1)) % 4;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   127
    else
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   128
        return (dir + 1) % 4;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   129
}
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   130
ai.BlindCycle.prototype.analyse = function(brd) {
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   131
    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
   132
    this.prevDir = this.prevDir || 0;
29
30a09d50ae21 Fix typo.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 28
diff changeset
   133
    if (!this.cfg.whilePossible)
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   134
        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
   135
    while (true) {
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   136
        if (origBrd[ai.BlindCycle.canDirs[this.prevDir]]())
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   137
            return ai.BlindCycle.dirs[this.prevDir];
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   138
        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
   139
    }
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   140
}
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   141
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   142
ai.BlindCycle.prototype.cleanup = function() {
27
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   143
    delete this.prevDir;
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   144
}
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   145
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   146

8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   147
8f96d09a4d94 Add Blind cycle AI. Add example of setting passing.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 24
diff changeset
   148
////////////////////////////////////////////////////////////////
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   149
// 1 step deep with linear weight function on score, max value,
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   150
// bonuses for max value stay at corner or edge and bonuses
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   151
// for each free field.
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   152
////////////////////////////////////////////////////////////////
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   153
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   154
/**
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   155
 * Defines coefficient for linear resulted weight function.
99
df4736e659f2 Rename AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 74
diff changeset
   156
 * @name ai.OneStepAhead.cfg
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   157
 * @namespace
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   158
 * @property {number} scoreCoef    multiplicator for score
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   159
 * @property {number} maxValCoef   multiplicator for max value
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   160
 * @property {number} cornerBonus  bonus for max value at board corner
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   161
 * @property {number} edgeBonus    bonus for max value at board edge
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   162
 * @property {number} freeBonus    bonus foe each free cell
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   163
 */
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   164
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   165
/** 1 step deep with * AI.
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   166
 * @param {Board} brdEngine  board engine from board.js
99
df4736e659f2 Rename AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 74
diff changeset
   167
 * @param {ai.OneStepAhead.cfg} cfg  configuration settings
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   168
 * @constructor */
99
df4736e659f2 Rename AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 74
diff changeset
   169
ai.OneStepAhead = function(brdEngine, cfg) {
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   170
    this.brdEngine = brdEngine;
99
df4736e659f2 Rename AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 74
diff changeset
   171
    this.cfg = ai.copyObj(ai.OneStepAhead.bestCfg);
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   172
    ai.copyObj(cfg, this.cfg);
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   173
}
99
df4736e659f2 Rename AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 74
diff changeset
   174
ai.OneStepAhead.bestCfg = {scoreCoef: 1, maxValCoef: 0, cornerBonus: 0, edgeBonus: 0, freeBonus: 0};
df4736e659f2 Rename AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 74
diff changeset
   175
ai.OneStepAhead.prototype.weight = function(brd) {
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   176
    var weight = 0;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   177
    if (this.cfg.scoreCoef > 0)
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   178
        weight += this.cfg.scoreCoef * brd.score();
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   179
    var max = brd.max();
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   180
    if (this.cfg.maxValCoef > 0)
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   181
        weight += this.cfg.maxValCoef * max;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   182
    if (this.cfg.cornerBonus > 0 && brd.atCorner(max))
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   183
        weight += this.cfg.cornerBonus;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   184
    if (this.cfg.edgeBonus > 0 && brd.atEdge(max))
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   185
        weight += this.cfg.edgeBonus;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   186
    if (this.cfg.freeBonus > 0)
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   187
        weight += this.cfg.freeBonus * brd.free();
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   188
    return weight;
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   189
}
99
df4736e659f2 Rename AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 74
diff changeset
   190
ai.OneStepAhead.prototype.analyse = function(brd) {
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   191
    var origBrd = new this.brdEngine(brd);
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   192
    var nextBrd = new this.brdEngine();
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   193
    var maxWeight = -1;
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   194
    var bestDir;
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   195
    for (var i = 0; i < ai.dirs.length; i++) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   196
        var dir = ai.dirs[i];
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   197
        if (origBrd[dir](nextBrd)) {
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   198
            var weight = this.weight(nextBrd);
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   199
            if (maxWeight < weight) {
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   200
                bestDir = dir;
53
ee53cd2cb69a Join all one step deep AIs into one with linear weight function.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 36
diff changeset
   201
                maxWeight = weight;
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   202
            }
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   203
        }
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   204
    }
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   205
    return bestDir;
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   206
}
12
a9a44cfc3e08 Moves for 2d array board + test toolkit.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 10
diff changeset
   207
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
99
df4736e659f2 Rename AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 74
diff changeset
   208
ai.OneStepAhead.prototype.cleanup = function() { }
10
70ece7f758a0 Move rule and AI engine to separate files.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents:
diff changeset
   209
24
079bcd734b68 Fix: TypeError: ui.ai.current.cleanup is not a function
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 21
diff changeset
   210

14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   211
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   212
////////////////////////////////////////////////////////////////
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
   213
// 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
   214
////////////////////////////////////////////////////////////////
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   215
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   216
/** N level deep on score value without random simulation.
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   217
 * @param {Board} brdEngine  board engine from board.js
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   218
 * @constructor */
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   219
ai.DeepMaxScore = function(brdEngine) {
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   220
    this.brdEngine = brdEngine;
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   221
}
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   222
ai.DeepMaxScore.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
   223
    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
   224
    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
   225
    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
   226
    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
   227
    var bestDir;
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   228
    for (var i = 0; i < ai.dirs.length; i++) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   229
        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
   230
        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
   231
            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
   232
            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
   233
            // 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
   234
            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
   235
                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
   236
                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
   237
                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
   238
            }
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   239
        }
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   240
    }
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
   241
    return bestDir;
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   242
}
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   243
ai.DeepMaxScore.prototype.bestScore = function(brd, seenBrds) {
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   244
    if (seenBrds) {
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   245
        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
   246
            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
   247
                return 0;
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   248
    } else {
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   249
        seenBrds = [];
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   250
    }
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   251
    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
   252
    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
   253
    var maxScore = currScore;
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   254
    var nextBrd = new this.brdEngine();
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   255
    for (var i = 0; i < ai.dirs.length; i++) {
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   256
        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
   257
            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
   258
            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
   259
                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
   260
        }
42d62e5123b2 Choose move that lead to maximum next score among all possible when next moves
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 14
diff changeset
   261
    }
14
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   262
    return maxScore;
9b49e710f5a7 Add "N level deep on score value without random" AI.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 12
diff changeset
   263
}
19
94a4201d27a3 Fold code into loops.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 18
diff changeset
   264
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   265
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
   266
24
079bcd734b68 Fix: TypeError: ui.ai.current.cleanup is not a function
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 21
diff changeset
   267

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
   268
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   269
////////////////////////////////////////////////////////////////
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   270
// 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
   271
// 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
   272
////////////////////////////////////////////////////////////////
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   273
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   274
/**
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   275
 * Defines coefficient for linear resulted weight function.
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   276
 * @name ai.DeepMaxScoreCorner.cfg
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   277
 * @namespace
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   278
 * @property {number} scoreCoef    multiplicator for score
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   279
 * @property {number} maxValCoef   multiplicator for max value
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   280
 * @property {number} cornerBonus  bonus for max value at board corner
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   281
 * @property {number} edgeBonus    bonus for max value at board edge
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   282
 * @property {number} freeBonus    bonus foe each free cell
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   283
 */
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   284
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   285
/** N level deep AI without random simulation.
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   286
 * @param {Board} brdEngine  board engine from board.js
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   287
 * @param {Object} cfg  configuration settings
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   288
 * @constructor */
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   289
ai.DeepMaxScoreCorner = function(brdEngine, cfg) {
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
   290
    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
   291
    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
   292
    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
   293
    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
   294
    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
   295
}
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   296
ai.DeepMaxScoreCorner.prototype.scoreCorner = function(brd) {
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
   297
    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
   298
    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
   299
    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
   300
        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
   301
    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
   302
        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
   303
    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
   304
    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
   305
}
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   306
ai.DeepMaxScoreCorner.prototype.scoreEdge = function(brd) {
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
   307
    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
   308
    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
   309
    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
   310
        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
   311
    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
   312
    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
   313
}
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   314
ai.DeepMaxScoreCorner.prototype.analyse = function(brd) {
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
   315
    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
   316
    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
   317
    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
   318
    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
   319
    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
   320
    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
   321
        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
   322
        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
   323
            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
   324
            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
   325
            // 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
   326
            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
   327
                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
   328
                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
   329
                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
   330
            }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   331
        }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   332
    }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   333
    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
   334
}
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   335
ai.DeepMaxScoreCorner.prototype.bestScore = function(brd, seenBrds) {
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
   336
    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
   337
        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
   338
            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
   339
                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
   340
    } 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
   341
        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
   342
    }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   343
    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
   344
    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
   345
    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
   346
    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
   347
    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
   348
        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
   349
            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
   350
            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
   351
                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
   352
        }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   353
    }
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   354
    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
   355
}
ab294e8db00c Add detecting value at edge or corner, free cell count. Added AI that count
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 19
diff changeset
   356
/* Mark that next board will be unrelated to previous, so any stored precompution can be cleared. */
59
28613a54c71c Capitilize AI names.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 57
diff changeset
   357
ai.DeepMaxScoreCorner.prototype.cleanup = function() { }
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
   358
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   359
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   360
////////////////////////////////////////////////////////////////
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   361
// N level deep with random simulation.
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
57
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   364
/**
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   365
 * Defines coefficient for linear resulted weight function.
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   366
 * @name ai.expectimax.cfg
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   367
 * @namespace
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   368
 * @property {number} scoreCoef    multiplicator for score
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   369
 * @property {number} maxValCoef   multiplicator for max value
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   370
 * @property {number} cornerBonus  bonus for max value at board corner
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   371
 * @property {number} edgeBonus    bonus for max value at board edge
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   372
 * @property {number} freeBonus    bonus foe each free cell
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   373
 */
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   374
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   375
/** N level deep with random simulation.
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   376
 * @param {Board} brdEngine  board engine from board.js
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   377
 * @param {ai.expectimax.cfg} cfg  configuration settings
94e1b2d0bd31 Add JSDoc annotation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 56
diff changeset
   378
 * @constructor */
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   379
ai.expectimax = function(brdEngine, cfg) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   380
    this.brdEngine = brdEngine;
74
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   381
    this.cfg = ai.copyObj(ai.expectimax.bestCfg);
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   382
    ai.copyObj(cfg, this.cfg);
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   383
    if (this.cfg.balance <= 0)
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   384
        this.cfg.balance = ai.expectimax.bestCfg.balance;
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   385
    if ( this.cfg.balance > 1)
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   386
        this.cfg.balance = 1;
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   387
    if (!this.cfg.depth || this.cfg.depth < 0 || 8 <= this.cfg.depth)
74
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   388
        this.cfg.depth = ai.expectimax.bestCfg.depth;
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   389
}
74
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   390
ai.expectimax.bestCfg = {balance: .9, depth: 3, scoreCoef: 1, maxValCoef: 0, cornerBonus: 0, edgeBonus: 0, freeBonus: 0, weightPriority: 10};
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   391
ai.expectimax.prototype.weight = function(brd) {
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   392
    var score = 0;
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   393
    if (this.cfg.scoreCoef > 0)
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   394
        score += this.cfg.scoreCoef * brd.score();
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   395
    var max = brd.max();
74
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   396
    if (this.cfg.maxValCoef > 0)
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   397
        score += this.cfg.maxValCoef * max;
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   398
    if (this.cfg.cornerBonus > 0)
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   399
        if (brd.atCorner(max))
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   400
            score += this.cfg.cornerBonus;
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   401
    if (this.cfg.edgeBonus > 0)
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   402
        if (brd.atEdge(max))
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   403
            score += this.cfg.edgeBonus;
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   404
    if (this.cfg.freeBonus > 0)
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   405
        score += this.cfg.freeBonus * brd.free();
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   406
    return score;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   407
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   408
ai.expectimax.prototype.analyse = function(brd) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   409
    var origBrd = new this.brdEngine(brd);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   410
    var nextBrd = new this.brdEngine();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   411
    var prevScore = -1, nextScore = -1;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   412
    var maxWeight = -1;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   413
    var bestDir;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   414
    this.cleanup();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   415
    for (var i = 0; i < ai.dirs.length; i++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   416
        var dir = ai.dirs[i];
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   417
        if (origBrd[dir](nextBrd)) {
74
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   418
            var weight = this.recWeight(nextBrd, 1);
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   419
            var ok = (weight - maxWeight) > this.cfg.weightPriority;
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   420
            if ( ! ok && maxWeight <= weight) {
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   421
                nextScore = this.weight(nextBrd);
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   422
                ok = prevScore < nextScore;
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   423
            }
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   424
            if (ok) {
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   425
                prevScore = nextScore;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   426
                maxWeight = weight;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   427
                bestDir = dir;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   428
            }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   429
        }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   430
    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   431
    this.cleanup();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   432
    return bestDir;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   433
}
74
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   434
ai.expectimax.prototype.recWeight = function(brd, depth) {
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   435
    if (depth >= this.cfg.depth)
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   436
        return this.weight(brd);
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   437
    if (this.cache[depth]) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   438
        var cache = this.cache[depth];
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   439
        for (var i = cache.length-1; i >= 0; i--) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   440
            if (brd.equals(cache[i].brd))
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   441
                return cache[i].weight;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   442
        }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   443
    } else {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   444
        this.cache[depth] = [];
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   445
    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   446
    var weight = 0;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   447
    var free = 0;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   448
    for (var i = 0; i < 3; i++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   449
        for (var j = 0; j < 3; j++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   450
            if (brd.get(i, j) === 0) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   451
                var randBoard = brd.copy();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   452
                randBoard.set(i, j, 1);
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   453
                var nextBrd = new this.brdEngine();
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   454
                var n = 0, w = 0;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   455
                for (var diri = 0; diri < ai.dirs.length; diri++) {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   456
                    if (randBoard[ai.dirs[diri]](nextBrd)) {
74
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   457
                        w += this.recWeight(nextBrd, depth+1);
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   458
                        n++;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   459
                    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   460
                }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   461
                if (n > 0)
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   462
                    w = w / n;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   463
                weight += this.cfg.balance * w;
74
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   464
                if (this.cfg.balance < 1) {
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   465
                    randBoard.set(i, j, 2);
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   466
                    var n = 0, w = 0;
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   467
                    for (var diri = 0; diri < ai.dirs.length; diri++) {
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   468
                        if (randBoard[ai.dirs[diri]](nextBrd)) {
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   469
                            w += this.recWeight(nextBrd, depth+1);
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   470
                            n++;
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   471
                        }
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   472
                    }
74
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   473
                    if (n > 0)
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   474
                        w = w / n;
93cb48b73b39 Enable config for expectimax. Fix weight function for expectimax.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 60
diff changeset
   475
                    weight += this.cfg.balance * w;
21
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   476
                }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   477
                free++;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   478
            }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   479
        }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   480
    }
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   481
    if (free > 0)
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   482
        weight = weight / free;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   483
    this.cache[depth].push({brd: brd, weight: weight});
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   484
    return weight;
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   485
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   486
/* 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
   487
ai.expectimax.prototype.cleanup = function() {
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   488
    this.cache = [];
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   489
}
ed0292f0c7c6 Expectimax implementation.
Oleksandr Gavenko <gavenkoa@gmail.com>
parents: 20
diff changeset
   490