/
GridComputer.js
115 lines (92 loc) · 2.89 KB
/
GridComputer.js
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
import Constants from '../Constants';
export class GridComputer {
constructor (grid, player) {
this.bestChoise = null;
this.minimax(grid, player, 0);
return this.bestChoise;
}
minimax (grid, player, depth) {
let winnerResult = GetWinner(grid);
if (winnerResult !== Constants.PLAYER._) {
return this.getScore(winnerResult, player, depth);
}
if (IsFull(grid)) {
return 0;
}
let availableMoves = this.getFreePositions(grid);
let stack = [];
let oppositePlayer = this.getOppositePlayer(player);
availableMoves.forEach((move) => {
let clonedGrid = grid.set(move, player);
let result = this.minimax(clonedGrid, oppositePlayer, depth + 1);
stack.push(result);
});
let result = stack[0];
let optimalMove = availableMoves[0];
for (let i = 1; i < stack.length; i++) {
if ((stack[i] > result && player === Constants.PLAYER.X) ||
(stack[i] < result && player === Constants.PLAYER.O)) {
result = stack[i];
optimalMove = availableMoves[i];
}
}
if (depth === 0 && player === Constants.PLAYER.X) {
this.bestChoise = optimalMove;
}
return result;
}
getScore (result, player, depth) {
if (result === Constants.PLAYER.X) {
return 10 - depth;
} else if (result === Constants.PLAYER._) {
return 0;
}
return depth - 10;
}
getFreePositions (grid) {
let stack = [];
for (let i = 0; i < grid.count(); i++) {
if (grid.get(i) === Constants.PLAYER._) {
stack.push(i);
}
}
return stack;
}
getOppositePlayer(player) {
return player === Constants.PLAYER.X ? Constants.PLAYER.O : Constants.PLAYER.X;
}
};
export function IsFull (grid) {
return grid.indexOf(Constants.PLAYER._) === -1;
};
export function GetWinner (grid) {
// for each row
for (let i = 0; i < 3; i++) {
if (grid.get(i) === grid.get(i + 3) &&
grid.get(i) === grid.get(i + 6) &&
grid.get(i) !== Constants.PLAYER._) {
return grid.get(i);
}
}
// for each column
for (let i = 0; i <= 6; i += 3) {
if (grid.get(i) === grid.get(i + 1) &&
grid.get(i) === grid.get(i + 2) &&
grid.get(i) !== Constants.PLAYER._) {
return grid.get(i);
}
}
// left diagonal
if (grid.get(0) === grid.get(4) &&
grid.get(0) === grid.get(8) &&
grid.get(0) !== Constants.PLAYER._) {
return grid.get(0);
}
// right diagonal
if (grid.get(2) === grid.get(4) &&
grid.get(2) === grid.get(6) &&
grid.get(2) !== Constants.PLAYER._) {
return grid.get(2);
}
return Constants.PLAYER._;
};