-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcHash.cpp
More file actions
184 lines (148 loc) · 5.31 KB
/
cHash.cpp
File metadata and controls
184 lines (148 loc) · 5.31 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
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
#include "cHash.h"
sem_t gHashTableAccess;
// http://www.cplusplus.com/reference/random/mersenne_twister_engine/operator()/
cHash::cHash(int board[][8]) {
int i, j, index;
std::random_device r;
std::mt19937_64 gen(r()); // the seed doesnt really matter
mHashTableSize =
(unsigned long long)(2)
<< 33; // 8 gigs (~1 billion hashes) lmao change this to fit your system
mBoardHash = 0;
for (i = 0; i < 832; i++) {
mPieceHashes[i] = gen();
}
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++) {
// each piece type gets 64 values in the array
// offset to piece's chunk offset to position
index = ((board[i][j] + 6) << 6) + ((i << 3) * j);
mBoardHash ^= mPieceHashes[index];
}
}
void cHash::fInitSemaphore() {
if (sem_init(&gHashTableAccess, 0, 1) == -1) {
std::cout << "Rank " << rank << ": Nao pode iniciar o semaforo"
<< std::endl;
exit(-1);
}
}
void cHash::fSetBoard(int board[][8]) {
int index, i, j;
mBoardHash = 0;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++) {
// each piece type gets 64 values in the array
// offset to piece's chunk offset to position
index = ((board[i][j] + 6) << 6) + ((i << 3) * j);
mBoardHash ^= mPieceHashes[index];
}
}
void cHash::fUpdateHash(gameMove *m, unsigned long long &hash) {
int index;
int len = m->toJ - m->fromJ;
// remove hash of piece that moved
index = ((m->piece + 6) << 6) + ((m->fromI << 3) * m->fromJ);
hash ^= mPieceHashes[index];
// add hash of empty piece at the original location
index = ((EMPTY + 6) << 6) + ((m->fromI << 3) * m->fromJ);
hash ^= mPieceHashes[index];
// remove hash of the captured piece
index = ((m->capture + 6) << 6) + ((m->toI << 3) * m->toJ);
hash ^= mPieceHashes[index];
// check for pawn promotion, place queen instead of pawn
if (m->piece == W_PAWN && m->toI == 0) {
index = ((W_QUEEN + 6) << 6) + ((m->toI << 3) * m->toJ);
hash ^= mPieceHashes[index];
}
else if (m->piece == B_PAWN && m->toI == 7) {
index = ((B_QUEEN + 6) << 6) + ((m->toI << 3) * m->toJ);
hash ^= mPieceHashes[index];
}
// check for en passant, remove captured pawn hash, add empty hash, place pawn
else if (abs(m->piece) == B_PAWN && m->fromJ != m->toJ &&
m->capture == EMPTY) {
// pawn moved diagonally to an empty square -> en passant capture
index = ((-(m->piece) + 6) << 6) + ((m->fromI << 3) * m->toJ);
hash ^= mPieceHashes[index];
index = ((EMPTY + 6) << 6) + ((m->fromI << 3) * m->toJ);
hash ^= mPieceHashes[index];
index = ((m->piece + 6) << 6) + ((m->toI << 3) * m->toJ);
hash ^= mPieceHashes[index];
}
// check for castling
else if (abs(m->piece) == B_KING && abs(len) == 2) {
// castle to the right
if (len > 0) {
// remove castle hash
index = (((m->piece > 0 ? B_ROOK : W_ROOK) + 6) << 6) +
((m->fromI << 3) * (m->toJ + 1));
hash ^= mPieceHashes[index];
// add empty hash
index = ((EMPTY + 6) << 6) + ((m->fromI << 3) * (m->toJ + 1));
hash ^= mPieceHashes[index];
// remove empty hash of square castle moved to
index = ((EMPTY + 6) << 6) + ((m->fromI << 3) * (m->toJ - 1));
hash ^= mPieceHashes[index];
// add castle hash at new location
index = (((m->piece > 0 ? B_ROOK : W_ROOK) + 6) << 6) +
((m->fromI << 3) * (m->toJ - 1));
hash ^= mPieceHashes[index];
// add king hash
index = ((m->piece + 6) << 6) + ((m->toI << 3) * m->toJ);
hash ^= mPieceHashes[index];
}
else // castle to the left
{
// remove castle hash
index = (((m->piece > 0 ? B_ROOK : W_ROOK) + 6) << 6) +
((m->fromI << 3) * (m->toJ - 2));
hash ^= mPieceHashes[index];
// add empty hash
index = ((EMPTY + 6) << 6) + ((m->fromI << 3) * (m->toJ - 2));
hash ^= mPieceHashes[index];
// remove empty hash of square castle moved to
index = ((EMPTY + 6) << 6) + ((m->fromI << 3) * (m->toJ + 1));
hash ^= mPieceHashes[index];
// add castle hash at new location
index = (((m->piece > 0 ? B_ROOK : W_ROOK) + 6) << 6) +
((m->fromI << 3) * (m->toJ + 1));
hash ^= mPieceHashes[index];
// add king hash
index = ((m->piece + 6) << 6) + ((m->toI << 3) * m->toJ);
hash ^= mPieceHashes[index];
}
} else {
// add hash of the piece at the new location
index = ((m->piece + 6) << 6) + ((m->toI << 3) * m->toJ);
hash ^= mPieceHashes[index];
}
}
hashState *cHash::fFindState(unsigned long long &hash) {
unsigned long long key = hash % mHashTableSize;
if (mHashTable.empty()) return nullptr;
std::unordered_map<unsigned long long, hashState>::iterator it =
mHashTable.find(key);
// not found
if (it == mHashTable.end())
return nullptr;
else
return &(it->second);
}
void cHash::fAddState(hashState &state) {
unsigned long long key = state.hash % mHashTableSize;
sem_wait(&gHashTableAccess);
mHashTable.emplace(key, state);
sem_post(&gHashTableAccess);
}
unsigned long long cHash::fBoardToHash(int board[][8]) {
int index, i, j;
unsigned long long hash = 0;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
index = ((board[i][j] + 6) << 6) + ((i << 3) * j);
hash ^= mPieceHashes[index];
}
}
return hash;
}