-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patheval.jai
89 lines (71 loc) · 2.5 KB
/
eval.jai
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
// for NNUE resources: https://hxim.github.io/Stockfish-Evaluation-Guide/
uci_evaluate :: (chess: *Chess) -> int #expand {
return nnue_evaluate_board(chess);
}
evaluate :: (chess: *ChessGame, fifty: int) -> int {
TF, score := trivial_evaluation(chess, fifty);
if TF return score;
eval := nnue_evaluate(chess);
return (eval * (100-fifty)) / 200;
}
#scope_file
// We use trivial evaluation to deal with endgame positions.
trivial_evaluation :: (using chess: *Chess, fifty: int) -> bool, int {
WIN_SCORE :: 5_000;
eval_winning_position :: (strong_king: u64, q: u64, r: u64, b: u64, n: u64, p: u64, weak_king: u64) -> int {
push_to_edge :: (sq: int) -> int {
r := sq / 8;
f := sq % 8;
fd := min(f, 7-f);
rd := min(r, 7-r);
return 90 - (7 * fd * fd / 2 + 7 * rd * rd / 2);
}
eg_pawn_table :: int.[
0, 0, 0, 0, 0, 0, 0, 0,
750, 750, 750, 750, 750, 750, 750, 750,
550, 550, 550, 550, 550, 550, 550, 550,
250, 250, 250, 250, 250, 250, 250, 250,
150, 150, 150, 150, 150, 150, 150, 150,
50, 50, 50, 50, 50, 50, 50, 50,
25, 25, 25, 25, 25, 25, 25, 25,
0, 0, 0, 0, 0, 0, 0, 0,
];
win := bit_scan_forward(strong_king);
los := bit_scan_forward(weak_king);
winx := win / 8;
winy := win % 8;
losx := los / 8;
losy := los % 8;
distance := abs(winx - losx) + abs(winy - losy);
push_close := 140 - 20 * distance;
edge := push_to_edge(los);
mat := popcount(q)*900 + popcount(r)*500 + popcount(b)*350 + popcount(n)*300;
pawn_points:= 0;
while p {
i := bit_scan_forward(p);
pawn_points += eg_pawn_table[i];
p &= p-1;
}
return WIN_SCORE + push_close + edge + mat + pawn_points;
}
// used for trivial checkmates/draws.
w_pieces := w_queen|w_rook|w_bishop|w_knight|w_pawn;
b_pieces := b_queen|b_rook|b_bishop|b_knight|b_pawn;
if b_pieces == 0 {
if w_pieces & (~(w_pawn|w_knight)) {
side := ifx turn == Turn.WHITE then 1 else -1;
eval := eval_winning_position(w_king, q=w_queen, r=w_rook, b=w_bishop, n=w_knight, p=bit_reverse64(w_pawn), b_king) * side;
return true, eval;
}
}
if w_pieces == 0 {
if b_pieces & (~(b_pawn|b_knight)) {
side := ifx turn == Turn.WHITE then -1 else 1;
eval := eval_winning_position(b_king, q=b_queen, r=b_rook, b=b_bishop, n=b_knight, p=b_pawn, w_king) * side;
return true, eval;
}
}
return false, 0;
}
#import "File";
#import "String";