summaryrefslogtreecommitdiff
path: root/qml/javascript/navigator.js
blob: b7e943c1dece72efa8ff5bb67506bf727ad1e329 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
.pragma library

function getCurrentAction(path, tree) {

    var way = tree;
    var ended = false;

    /*
     * Get the action pointed by the path.
     */
    path.forEach( function(element, index, array) {
        if (!ended && element < way.length) {
            way = way[element];
        } else {
            ended = true;
        }
    });

    if ( !ended ) {
        return way;
    } else {
        return undefined;
    }

}

/**
  * return the next move to play in the tree.
  */
function getMove(color, tree) {

    var element;

    if (color) {
        element = tree.W;
    } else {
        element = tree.B;
    }

    if (element !== undefined) {
        return element[0];
    }
    return undefined;

}

/*
 * return true if the branch is wrong.
 */
function isWrong(branch) {
    return (["WV", "TR"].some(function (element, index, array){
        return branch.hasOwnProperty(element);
    }))
}

function getNextMove(path, tree, player) {

    if (path === undefined) {
        return false;
    }

    var way = getCurrentAction(path, tree);
     if (Array.isArray(way)) {
         /* get all the possibilities, except the one which are mark wrong */
         var filtered = way.filter(function callback(element) {
             return !isWrong(element[0]);
         });
         var newIndex = Math.ceil(Math.random() * filtered.length) - 1;
         return getMove(player, filtered[newIndex][0]);

     } else {
         return getMove(player, way);
     }
}

/**
 * Compare the player move with the level tree, and check if the player move is allowed.
 * return undefined if the move was not in the level, or return the new path.
 */
function checkAction(path, tree, player, playedPosition, action) {

    if (path === undefined) {
        return false;
    }

    var way = getCurrentAction(path, tree);
    var pathIndex;
    var properties = {};

    if (Array.isArray(way)) {
        /*
         * We have choice between different possibilities.
         * We check each of them to get the player action.
         */
        if (way.some( function(element, index, array) {

            /*
             * Increment the path to the next position, and check the expected
             * result.
             */
            path.push(index);
            var next = getCurrentAction(path, tree)[0];

            var expectedIndex = getMove(player, next);

            if (playedPosition === expectedIndex) {

                /*
                 * Check for wrong variation.
                 */
                if  (isWrong(next)) {
                    properties.wrong = true;
                }

                path.push(0);
                return true;
            }

            /*
             * The position was not the expected one. Restore the path to the
             * original one.
             */
            path.pop();
            return false;

        })) {
            /*
             * We got the rigth action. Now, get the next position in the path.
             */
            pathIndex = path.length - 1;
            path[pathIndex] = path[pathIndex] + 1;
            action(path, properties);
            return true;
        }
    } else {

        /*
         * We only have one possibility, return it.
         */
        var move = getMove(player, way);
        if (move === playedPosition) {
            /*
             * The player played the good move.
             */
            pathIndex = path.length - 1;
            path[pathIndex] = path[pathIndex] + 1;
            action(path, properties);
            return true;
        }
    }
    return false;

}

/**
 * Play the computer action.
 * path: the current path
 * tree: the level
 * player: the current player
 * addPiece: function called with the new move and the new path.
 */
function playComputer(path, tree, player, addPiece) {

    var way = getCurrentAction(path, tree);

    var newPath;

    if (Array.isArray(way)) {
        /* We have differents branches. We take one at random.
         */
        var newIndex = Math.ceil(Math.random() * way.length) - 1;
        newPath = way[newIndex][0]; /* the player move (index 0) */
        path.push(newIndex, 1); /* return the oponent move (index 1)*/
    } else {
        var pathIndex;
        pathIndex = path.length - 1;
        path[pathIndex] = path[pathIndex] + 1;
        newPath = way;
    }
    var move = getMove(!player, newPath);
    addPiece(move, path);
}

function undo(path) {
    var way = getCurrentAction(path, tree);

}