-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathzobrist.cpp
More file actions
99 lines (87 loc) · 2.26 KB
/
Copy pathzobrist.cpp
File metadata and controls
99 lines (87 loc) · 2.26 KB
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
#include <stdlib.h>
#include "bitmanip.h"
#include "defines.h"
#include "zobrist.h"
u64 zrBoard[64][2][KING + 1];
u64 zrSide;
u64 zrEp[8];
u64 rand64() {
return
(((u64)rand() & 0xffffull) << 0) ^
(((u64)rand() & 0xffffull) << 16) ^
(((u64)rand() & 0xffffull) << 32) ^
(((u64)rand() & 0xffffull) << 48);
}
void zobristInit() {
for (int sq = 0; sq < 64; sq++) {
for (int side = 0; side < 2; side++) {
for (int piece = PAWN; piece <= KING; piece ++) {
zrBoard[sq][side][piece] = rand64();
}
}
}
zrSide = rand64();
for (int i = 0; i < 8; i++) {
zrEp[i] = rand64();
}
}
u64 getZobrist(Board *b) {
u64 z = 0;
for (int side = WHITE; side <= BLACK; side++) {
int index = (side == WHITE) ? BB_WP : BB_BP;
for (int piece = PAWN; piece <= KING; piece++) {
u64 mask = b->bb[index++];
int sq;
while (mask) {
GET_BIT_AND_CLEAR(mask, sq);
z ^= zrBoard[sq][side][piece];
}
}
}
if (b->side == BLACK) {
z ^= zrSide;
}
if (b->bb[BB_EP]) {
int sq = ctz(b->bb[BB_EP]);
z ^= zrEp[sq & 7];
}
return z;
}
u64 updateZobrist(u64 z, Board *b, Move m) {
int allMe = (b->side == WHITE) ? BB_WALL : BB_BALL;
int allYou = BB_WALL + BB_BALL - allMe;
u64 toMask = 1ull << m.to;
// m.piece disappears from m.from.
z ^= zrBoard[m.from][b->side][m.piece];
// m.piece or m.promotion appears at m.to.
if (m.promotion) {
z ^= zrBoard[m.to][b->side][m.promotion];
} else {
z ^= zrBoard[m.to][b->side][m.piece];
}
// Any opponent's piece disappears from m.to.
if (b->bb[allYou] & toMask) {
int i = allYou + 1, p = PAWN;
while (!(b->bb[i] & toMask)) {
i++;
p++;
}
z ^= zrBoard[m.to][1 - b->side][p];
}
// If the move is an en passant capture, remove the opponent's pawn.
if ((m.piece == PAWN) && (toMask == b->bb[BB_EP])) {
int captureSq = (b->side == WHITE) ? (m.to - 8) : (m.to + 8);
z ^= zrBoard[captureSq][1 - b->side][PAWN];
}
// Clear the old en passant value, if it existed.
if (b->bb[BB_EP]) {
int sq = ctz(b->bb[BB_EP]);
z ^= zrEp[sq & 7];
}
// Set the new en passant value, if it exists
if ((m.piece == PAWN) && (abs(m.to - m.from) == 16)) {
z ^= zrEp[m.from & 7];
}
z ^= zrSide;
return z;
}