Code: Select all
// In GenAllMoves(Thread* t, sMove* m);
case WKC:
mft = ((u64)((board[h1] == WRC) && !(occ & owcs) && !AtkByBlack(t, awcs))) * WCS;
m += (mft == WCS);
mft = ((u64)((board[a1] == WRC) && !(occ & owcl) && !AtkByBlack(t, awcl))) * WCL;
m += (mft == WCL);
[[fallthrough]];
case WK:
atk |= bb = kingMoves[fs] & notme;
break;
Code: Select all
static bool AtkByBlack(Thread* t, u64 b) {
u64 atk = 0;
u64 occ = sides[WHITE] | sides[BLACK];
while (b) {
s32 sq = std::countr_zero(b);
b ^= 1ull << sq;
atk |= (wPawnCaptures[sq] & pawns[BLACK]);
atk |= (knightMoves[sq] & knights[BLACK]);
atk |= (kingMoves[sq] & kings[BLACK]);
atk |= (dSubset[sq][(((occ & dMask[sq]) * file_b2_b7) >> 58)] & (bishops[BLACK] | queens[BLACK]));
atk |= (aSubset[sq][(((occ & aMask[sq]) * file_b2_b7) >> 58)] & (bishops[BLACK] | queens[BLACK]));
atk |= (hSubset[sq][(occ >> hShift[sq]) & 63] & (rooks[BLACK] | queens[BLACK]));
atk |= (vSubset[sq][((((occ >> (sq & 7)) & file_a2_a7) * diag_c2_h7) >> 58)] & (rooks[BLACK] | queens[BLACK]));
}
return (atk != 0);
}
Code: Select all
// diagonals
for (ts = sq + 9, dx = x + 1, dy = y + 1; dx < FILEh && dy < RANK8; dMask[sq] |= 1ull << ts, ts += 9, dx++, dy++);
for (ts = sq - 9, dx = x - 1, dy = y - 1; dx > FILEa && dy > RANK1; dMask[sq] |= 1ull << ts, ts -= 9, dx--, dy--);
// anti diagonals
for (ts = sq + 7, dx = x - 1, dy = y + 1; dx > FILEa && dy < RANK8; aMask[sq] |= 1ull << ts, ts += 7, dx--, dy++);
for (ts = sq - 7, dx = x + 1, dy = y - 1; dx < FILEh && dy > RANK1; aMask[sq] |= 1ull << ts, ts -= 7, dx++, dy--);
// diagonal indexes
for (index = 0; index < 64; index++) {
dSubset[sq][index] = 0;
occ = index << 1;
if ((sq & 7) != FILEh && (sq >> 3) != RANK8) {
for (ts = sq + 9; ; ts += 9) {
dSubset[sq][index] |= (1ull << ts);
if (occ & (1ull << (ts & 7))) break;
if ((ts & 7) == FILEh || (ts >> 3) == RANK8) break;
}
}
if ((sq & 7) != FILEa && (sq >> 3) != RANK1) {
for (ts = sq - 9; ; ts -= 9) {
dSubset[sq][index] |= (1ull << ts);
if (occ & (1ull << (ts & 7))) break;
if ((ts & 7) == FILEa || (ts >> 3) == RANK1) break;
}
}
}
// anti diagonal indexes
for (index = 0; index < 64; index++) {
aSubset[sq][index] = 0;
occ = index << 1;
if ((sq & 7) != FILEa && (sq >> 3) != RANK8) {
for (ts = sq + 7; ; ts += 7) {
aSubset[sq][index] |= (1ull << ts);
if (occ & (1ull << (ts & 7))) break;
if ((ts & 7) == FILEa || (ts >> 3) == RANK8) break;
}
}
if ((sq & 7) != FILEh && (sq >> 3) != RANK1) {
for (ts = sq - 7; ; ts -= 7) {
aSubset[sq][index] |= (1ull << ts);
if (occ & (1ull << (ts & 7))) break;
if ((ts & 7) == FILEh || (ts >> 3) == RANK1) break;
}
}
}
// vertical indexes
for (index = 0; index < 64; index++) {
vSubset[sq][index] = 0;
uint64_t blockers = 0;
for (int i = 0; i <= 5; i++) {
if (index & (1ull << i)) {
blockers |= (1ull << (((5 - i) << 3) + 8));
}
}
if ((sq >> 3) != RANK8) {
for (ts = sq + 8; ; ts += 8) {
vSubset[sq][index] |= (1ull << ts);
if (blockers & (1ull << (ts - (ts & 7)))) break;
if ((ts >> 3) == RANK8) break;
}
}
if ((sq >> 3) != RANK1) {
for (ts = sq - 8; ; ts -= 8) {
vSubset[sq][index] |= (1ull << ts);
if (blockers & (1ull << (ts - (ts & 7)))) break;
if ((ts >> 3) == RANK1) break;
}
}
}
// horizontal indexes
for (index = 0; index < 64; index++) {
hSubset[sq][index] = 0;
occ = index << 1;
if ((sq & 7) != FILEh) {
for (ts = sq + 1; ; ts += 1) {
hSubset[sq][index] |= (1ull << ts);
if (occ & (1ull << (ts & 7))) break;
if ((ts & 7) == FILEh) break;
}
}
if ((sq & 7) != FILEa) {
for (ts = sq - 1; ; ts -= 1) {
hSubset[sq][index] |= (1ull << ts);
if (occ & (1ull << (ts & 7))) break;
if ((ts & 7) == FILEa) break;
}
}
}
// horizontal shift
hShift[sq] = (sq & 56) + 1;
}
Code: Select all
enum {
WP2, WP3, WP4, WP5, WP6, WP7, WN, WB, WRC, WR, WQ, WKC, WK,
ES,
BP7, BP6, BP5, BP4, BP3, BP2, BN, BB, BRC, BR, BQ, BKC, BK,
WPQ, WPN, WPR, WPB, WCS, WCL,
BPQ, BPN, BPR, BPB, BCS, BCL
};
Code: Select all
case WP5:
sq = mts - ((epbit[sly] == (1ull << mts)) << 3);
mtt = board[sq];
board[mfs] = ES;
board[sq] = ES;
board[mts] = WP6;
pawns[WHITE] ^= (1ull << mfs | 1ull << mts);
sides[WHITE] ^= (1ull << mfs | 1ull << mts);
*types[mtt] ^= (u64)(mtt != ES) << sq;
sides[BLACK] ^= (u64)(mtt != ES) << sq;
mat[BLACK] -= value[mtt];
pos[WHITE] += (wptbl[mts] - wptbl[mfs]);
pos[BLACK] -= tbls[mtt][sq];
break;
These are just a few highlights of Protozoa. Right now I can only make moves verified by the move generator. My last working engine is Bricabrac. It searched approximately 11,000,000 positions a second using a single thread on a Ryzen 9 3950x at 4.2 GHz. This engine will be substantially faster!
![Very Happy :D](./images/smilies/icon_biggrin.gif)
One other design feature that is different from Bricabrac is that it will be able to play more than one game at a time. I'm also developing a GUI where one can setup as many positions as there are available threads and analyze all at the same time. Analysis will incorporate a combination of real time reinforcement learning and full width search.
When I get Protozoa to the point it can play a game in a chess gui I will provide a link to the engine.