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
|
#pragma once
#include <iostream>
#include <string>
#include <climits>
#include "board.h"
// >0 white good, <0 black good
template <int (*Eval)(const Board&)> // should return high for white
int alphabeta(const Board &board, int depth);
int evaluate_pieceScore(const Board &board);
// IMPLEMENTATIONS
template <int (*Eval)(const Board&)>
static int alphabetaWhite(const Board &board, int depth, int alpha, int beta);
template <int (*Eval)(const Board&)>
static int alphabetaBlack(const Board &board, int depth, int alpha, int beta) {
if (depth == 0 || board.pieceScore[WHITE] >= Board::worth(KING)) {
return Eval(board);
}
int value = INT_MAX;
vector<Board> subs = board.subsequents();
if (depth >= 2) {
sort(subs.begin(), subs.end(), [](const Board &B1, const Board &B2) {
return Eval(B1) < Eval(B2);
});
}
for (const Board &B : subs) {
int v = alphabetaWhite<Eval>(B, depth - 1, alpha, beta);
if (v < value) {
value = v;
if (v < beta) {
beta = v;
if (beta <= alpha) break;
}
}
}
// if (depth == 1) cerr << value << ", ";
// else {
// if (depth == 2) cerr << endl;
// cerr << string(depth, ' ') << "alphabetaBlack: returning " << value << endl;
// }
// if (depth == 1 && abs(value) >= Board::worth(KING) / 10) cerr << board << endl;
// cerr << board << endl;
return value;
}
template <int (*Eval)(const Board&)>
static int alphabetaWhite(const Board &board, int depth, int alpha, int beta) {
if (depth == 0 || board.pieceScore[BLACK] >= Board::worth(KING)) {
return Eval(board);
}
int value = INT_MIN;
vector<Board> subs = board.subsequents();
if (depth >= 2) {
sort(subs.begin(), subs.end(), [](const Board &B1, const Board &B2) {
return Eval(B1) > Eval(B2);
});
}
for (const Board &B : subs) {
int v = alphabetaBlack<Eval>(B, depth - 1, alpha, beta);
if (v > value) {
value = v;
if (v > alpha) {
alpha = v;
if (beta <= alpha) break;
}
}
}
// if (depth == 1) cerr << value << ", ";
// else {
// if (depth == 2) cerr << endl;
// cerr << string(depth, ' ') << "alphabetaWhite: returning " << value << endl;
// }
// if (depth == 1 && abs(value) >= Board::worth(KING) / 10) cerr << board << endl;
// cerr << board << endl;
return value;
}
template <int (*Eval)(const Board&)>
int alphabeta(const Board &board, int depth) {
if (board.onTurn == WHITE) {
return alphabetaWhite<Eval>(board, depth, INT_MIN, INT_MAX);
} else {
return alphabetaBlack<Eval>(board, depth, INT_MIN, INT_MAX);
}
}
|