
The first mile marker has been reached. The above mentioned functions have been debugged and seem to be working properly, no guarantees. I have entered every series of moves I can think of to test every possibility and had GenAllMoves() do the verification. Enter e2e4 to make a move, e7e8n to promote and e1g1 to castle, etc.
The code has been written as simple to understand as I can. But, if one is new to writing branchless code then it might not be easily understood. Some examples are.
In MakeMove() the following line of code is executed for every move.
Code: Select all
piece[BLACK] ^= (u64)(mtt != ES) << mts;
(u64)0 << mts; (m->s.ts) does nothing.
(u64)1 << mts; removes the captured piece from that sides piece list. One might object that performing that operation when not necessary waste time. However, most moves are capture moves from Qsearch(). Something like 90% or more of the moves are captures!
Code: Select all
m.s.ft += ((ts == g1) * (WCS - WKC) + (ts == c1) * (WCL - WKC));
! uses pseudo piece types. WKC, WRC, BKC, BRC appear on the board. The other pseudo pieces exist only in switch statements. But some of them could also appear on the board. For example a pawn that moves to the 5th rank can change from a WP to a WPE. It would be a little faster because the second switch(fs >> 3) for the pawns would not be needed. I might optimize that later. In the code above WCS and WCL are pseudo pieces for castling that cannot be on the board. The from type starts off as a WKC (white king that can castle). That is (pseudo) piece 7. WCS and WCL is further along in the piece type list.
Code: Select all
enum {
ES,
WP, WN, WB, WRC, WR, WQ, WKC, WK,
BP, BN, BB, BRC, BR, BQ, BKC, BK,
WCS, WCL, WPD, WPE, WPQ, WPN, WPR, WPB,
BCS, BCL, BPD, BPE, BPQ, BPN, BPR, BPB
};
Here is the complete MSVS 2022 standard 2020 code so far.
Code: Select all
// !
// !.cpp
#include <cstring>
#include <bit>
#include <cctype>
#include <iostream>
#include "Defines.cpp"
#include "Equates.cpp"
#include "Globals.cpp"
#include "Utilities.cpp"
#include "Move.cpp"
#include "GenMoves.cpp"
#include "Search.cpp"
#include "GetCommand.cpp"
#include "Initialize.cpp"
#include "Main.cpp"
Code: Select all
// !
// Main.cpp
s32 main() {
Initialize();
while (mode) {
if (mode == GETCMD) GetCommand(thread[0]);
if (mode == SEARCH) StartSearch(thread[0]);
}
return 0;
}
Code: Select all
// !
// Initialize.cpp
void InitThreads() {
numThreads = 4;
thread = new Thread * [numThreads];
for (s32 i = 0; i < numThreads; i++) {
thread[i] = new Thread;
}
}
u64 mask_shift(u64 bb, s32 ranks) {
if (ranks > 0) return bb >> (ranks << 3);
else return bb << -(ranks << 3);
}
void InitRays() {
// Classic style sliding piece bitboards.
// Bob-Mike-Dan
// Bob = Robert Hyatt - originator of basic approach
// Mike = Michael Sherwin - Originally stop bits but later worked to modernize
// Dan = Daniel Infuehr - Final optimizations and code example
for (s32 sq = a1; sq <= h8; sq++) {
ray[sq].NW = dir_D2(sq) & GetUpper(sq);
ray[sq].NN = dir_VE(sq) & GetUpper(sq);
ray[sq].NE = dir_D1(sq) & GetUpper(sq);
ray[sq].EE = dir_HO(sq) & GetUpper(sq);
ray[sq].SE = dir_D1(sq) & GetLower(sq);
ray[sq].SS = dir_VE(sq) & GetLower(sq);
ray[sq].SW = dir_D2(sq) & GetLower(sq);
ray[sq].WW = dir_HO(sq) & GetLower(sq);
}
ray[64] = ray[63];
for (s32 sq = a1; sq <= h8; sq++) rev[sq] = ray[63 - sq];
rev[64] = ray[0];
}
void InitBoardBB() {
s32 file, rank;
for (s32 sq = a1; sq <= h8; sq++) {
file = sq & 7;
rank = sq >> 3;
wPawnCapts[sq] = 0;
bPawnCapts[sq] = 0;
knightMoves[sq] = 0;
bishopMoves[sq] = 0;
rookMoves[sq] = 0;
queenMoves[sq] = 0;
kingMoves[sq] = 0;
// pawns
if (sq >= a2 && sq <= h7) {
if (file != FILEa) {
wPawnCapts[sq] |= 1ull << (sq + 7);
bPawnCapts[sq] |= 1ull << (sq - 9);
}
if (file != FILEh) {
wPawnCapts[sq] |= 1ull << (sq + 9);
bPawnCapts[sq] |= 1ull << (sq - 7);
}
}
// knights
if (rank <= RANK6 && file <= FILEg) knightMoves[sq] |= 1ull << (sq + 17);
if (rank <= RANK7 && file <= FILEf) knightMoves[sq] |= 1ull << (sq + 10);
if (rank >= RANK2 && file <= FILEf) knightMoves[sq] |= 1ull << (sq - +6);
if (rank >= RANK3 && file <= FILEg) knightMoves[sq] |= 1ull << (sq - 15);
if (rank >= RANK3 && file >= FILEb) knightMoves[sq] |= 1ull << (sq - 17);
if (rank >= RANK2 && file >= FILEc) knightMoves[sq] |= 1ull << (sq - 10);
if (rank <= RANK7 && file >= FILEc) knightMoves[sq] |= 1ull << (sq + +6);
if (rank <= RANK6 && file >= FILEb) knightMoves[sq] |= 1ull << (sq + 15);
// bishops
bishopMoves[sq] = ray[sq].NW | ray[sq].NE | ray[sq].SE | ray[sq].SW;
//rooks
rookMoves[sq] = ray[sq].NN | ray[sq].EE | ray[sq].SS | ray[sq].WW;
// queen
queenMoves[sq] = bishopMoves[sq] | rookMoves[sq];
// king
if (rank <= RANK7) kingMoves[sq] |= 1ull << (sq + 8);
if (rank >= RANK2) kingMoves[sq] |= 1ull << (sq - 8);
if (file <= FILEg) kingMoves[sq] |= 1ull << (sq + 1);
if (file >= FILEb) kingMoves[sq] |= 1ull << (sq - 1);
if (rank <= RANK7 && file <= FILEg) kingMoves[sq] |= 1ull << (sq + 9);
if (rank >= RANK2 && file <= FILEg) kingMoves[sq] |= 1ull << (sq - 7);
if (rank >= RANK2 && file >= FILEb) kingMoves[sq] |= 1ull << (sq - 9);
if (rank <= RANK7 && file >= FILEb) kingMoves[sq] |= 1ull << (sq + 7);
}
}
void InitGame(Thread* t) {
s32 ok;
mode = GETCMD;
computer = BLACK;
ply = 0;
gly = 0;
ok = LoadFen(t, startFen);
if (!ok) {
std::cout << "Apparently a bad fen" << std::endl;
}
}
void InitStruct(Thread* t) {
piece[BLACK] = 0;
piece[WHITE] = 0;
king[BLACK] = 0;
king[WHITE] = 0;
for (s32 i = 0; i <= BK; i++) pctypbb[i] = 0;
for (s32 sq = a1; sq <= h8; sq++) {
s32 pce = board[sq];
switch (pce) {
case ES:
// no action
break;
case WP:
piece[WHITE] |= 1ull << sq;
pctypbb[WP] |= 1ull << sq;
break;
case WN:
piece[WHITE] |= 1ull << sq;
pctypbb[WN] |= 1ull << sq;
break;
case WB:
piece[WHITE] |= 1ull << sq;
pctypbb[WB] |= 1ull << sq;
break;
case WRC:
case WR:
piece[WHITE] |= 1ull << sq;
pctypbb[WR] |= 1ull << sq;
break;
case WQ:
piece[WHITE] |= 1ull << sq;
pctypbb[WQ] |= 1ull << sq;
break;
case WKC:
case WK:
piece[WHITE] |= 1ull << sq;
king[WHITE] |= 1ull << sq;
break;
case BP:
piece[BLACK] |= 1ull << sq;
pctypbb[BP] |= 1ull << sq;
break;
case BN:
piece[BLACK] |= 1ull << sq;
pctypbb[BN] |= 1ull << sq;
break;
case BB:
piece[BLACK] |= 1ull << sq;
pctypbb[BB] |= 1ull << sq;
break;
case BRC:
case BR:
piece[BLACK] |= 1ull << sq;
pctypbb[BR] |= 1ull << sq;
break;
case BQ:
piece[BLACK] |= 1ull << sq;
pctypbb[BQ] |= 1ull << sq;
break;
case BKC:
case BK:
piece[BLACK] |= 1ull << sq;
king[BLACK] |= 1ull << sq;
break;
}
}
for (s32 i = 0; i < 100; i++) epbit[i] = 0;
}
void Initialize() {
InitThreads();
InitRays();
InitBoardBB();
InitGame(thread[0]);
InitStruct(thread[0]);
}
Code: Select all
// !
// GetCommand.cpp
void GetCommand(Thread* t) {
s08 line[256], cmd[256], a_move, fs, ts, fs2;
uMove m;
u64 pieces;
s32 ok, not_ok;
if (!fgets(line, 256, stdin)) return;
ok = sscanf(line, "%s", cmd);
cmd[255] = '\0';
a_move = true;
if (line[0] < 'a' || line[0] > 'h') a_move = false;
if (line[1] < '1' || line[1] > '8') a_move = false;
if (line[2] < 'a' || line[2] > 'h') a_move = false;
if (line[3] < '1' || line[3] > '8') a_move = false;
if (a_move) {
ok = GenAllMoves(t);
if (!ok) {
printf("Illegal Move/n");
return;
}
fs = (line[1] - '1') * 8 + (line[0] - 'a');
ts = (line[3] - '1') * 8 + (line[2] - 'a');
a_move = false;
pieces = piece[stm];
while (pieces) {
fs2 = std::countr_zero(pieces);
pieces ^= 1ull << fs2;
if (fs == fs2) {
if (gbb[ply][fs] & (1ull << ts)) {
a_move = true;
break;
}
}
}
if (a_move) {
m = FillMoveFields(t, fs, ts);
if (m.s.ft == WPQ) {
if (line[4] == 'n') m.s.ft = WPN; else;
if (line[4] == 'b') m.s.ft = WPB; else;
if (line[4] == 'r') m.s.ft = WPR;
}
else;
if (m.s.ft == BPQ) {
if (line[4] == 'n') m.s.ft = BPN; else;
if (line[4] == 'b') m.s.ft = BPB; else;
if (line[4] == 'r') m.s.ft = BPR;
}
MakeMove(t, &m);
g[gly] = m;
gly++;
not_ok = InCheckBy[stm](t, king[1 - stm]);
if (not_ok) {
gly--;
m = g[gly];
TakeBack(t, &m);
return;
}
}
PrintBoard(t);
return;
}
if (!strcmp(cmd, "undo") && gly > 0) {
gly--;
m = g[gly];
TakeBack(t, &m);
PrintBoard(t);
return;
}
}
Code: Select all
// !
// Search.cpp
void StartSearch(Thread* t) {
}
Code: Select all
// !
// GenMoves.cpp
bool GenAllMoves(Thread* t) {
s08 fs, ft;
u64 atk;
u64 pieces = piece[stm];
u64 notme = ~pieces;
u64 occ = pieces | piece[1 - stm];
u64 empty = ~occ;
u64 enemy = notme ^ empty;
abb[ply] = 0;
do {
fs = std::countr_zero(pieces);
ft = board[fs];
switch (ft) {
case ES:
// can't get here
break;
case WP:
switch (fs >> 3) {
case RANK1:
// can't get here
break;
case RANK2:
gbb[ply][fs] = ((0x0000000000000100ull << fs) & empty);
gbb[ply][fs] |= ((gbb[ply][fs] << 8) & empty);
atk = wPawnCapts[fs];
gbb[ply][fs] |= atk & enemy;
abb[ply] |= atk;
break;
case RANK3:
case RANK4:
gbb[ply][fs] = ((0x0000000000000100ull << fs) & empty);
atk = wPawnCapts[fs];
gbb[ply][fs] |= atk & enemy;
abb[ply] |= atk;
break;
case RANK5:
gbb[ply][fs] = ((0x0000000000000100ull << fs) & empty);
atk = wPawnCapts[fs];
gbb[ply][fs] |= (atk & (enemy | epbit[ply]));
abb[ply] |= atk;
break;
case RANK6:
case RANK7:
gbb[ply][fs] = ((0x0000000000000100ull << fs) & empty);
atk = wPawnCapts[fs];
gbb[ply][fs] |= atk & enemy;
abb[ply] |= atk;
break;
}
break;
case WN:
gbb[ply][fs] = knightMoves[fs] & notme;
abb[ply] |= knightMoves[fs];
break;
case WB:
gbb[ply][fs]
= (ray[std::countr_zero(ray[fs].NW & occ)].NW
| ray[std::countr_zero(ray[fs].NE & occ)].NE
| rev[std::countl_zero(ray[fs].SE & occ)].SE
| rev[std::countl_zero(ray[fs].SW & occ)].SW)
^ bishopMoves[fs];
abb[ply] |= gbb[ply][fs];
gbb[ply][fs] &= notme;
break;
case WRC:
case WR:
gbb[ply][fs]
= (ray[std::countr_zero(ray[fs].NN & occ)].NN
| ray[std::countr_zero(ray[fs].EE & occ)].EE
| rev[std::countl_zero(ray[fs].SS & occ)].SS
| rev[std::countl_zero(ray[fs].WW & occ)].WW)
^ rookMoves[fs];
abb[ply] |= gbb[ply][fs];
gbb[ply][fs] &= notme;
break;
case WQ:
gbb[ply][fs]
= (ray[std::countr_zero(ray[fs].NW & occ)].NW
| ray[std::countr_zero(ray[fs].NE & occ)].NE
| rev[std::countl_zero(ray[fs].SE & occ)].SE
| rev[std::countl_zero(ray[fs].SW & occ)].SW
| ray[std::countr_zero(ray[fs].NN & occ)].NN
| ray[std::countr_zero(ray[fs].EE & occ)].EE
| rev[std::countl_zero(ray[fs].SS & occ)].SS
| rev[std::countl_zero(ray[fs].WW & occ)].WW)
^ queenMoves[fs];
abb[ply] |= gbb[ply][fs];
gbb[ply][fs] &= notme;
break;
case WKC:
gbb[ply][fs] = kingMoves[fs] & notme;
abb[ply] |= kingMoves[fs];
gbb[ply][fs] |= (u64)((board[h1] == WRC) + ((occ & SWCS) == 0) + (AttackedByBlack(t, AWCS) == 0) == 3) << g1;
gbb[ply][fs] |= (u64)((board[a1] == WRC) + ((occ & SWCL) == 0) + (AttackedByBlack(t, AWCL) == 0) == 3) << c1;
break;
case WK:
gbb[ply][fs] = kingMoves[fs] & notme;
abb[ply] |= kingMoves[fs];
break;
case BP:
switch (fs >> 3) {
case RANK1:
// can't get here
break;
case RANK2:
case RANK3:
gbb[ply][fs] = (1ull << (fs - 8)) & empty;
atk = bPawnCapts[fs];
gbb[ply][fs] |= atk & enemy;
abb[ply] |= atk;
break;
case RANK4:
gbb[ply][fs] = (1ull << (fs - 8)) & empty;
atk = bPawnCapts[fs];
gbb[ply][fs] |= (atk & (enemy | epbit[ply]));
abb[ply] |= atk;
break;
case RANK5:
case RANK6:
gbb[ply][fs] = (1ull << (fs - 8)) & empty;
atk = bPawnCapts[fs];
gbb[ply][fs] |= atk & enemy;
abb[ply] |= atk;
break;
case RANK7:
gbb[ply][fs] = (1ull << (fs - 8)) & empty;
gbb[ply][fs] |= ((gbb[ply][fs] >> 8) & empty);
atk = bPawnCapts[fs];
gbb[ply][fs] |= atk & enemy;
abb[ply] |= atk;
break;
}
break;
case BN:
gbb[ply][fs] = knightMoves[fs] & notme;
abb[ply] |= knightMoves[fs];
break;
case BB:
gbb[ply][fs]
= (ray[std::countr_zero(ray[fs].NW & occ)].NW
| ray[std::countr_zero(ray[fs].NE & occ)].NE
| rev[std::countl_zero(ray[fs].SE & occ)].SE
| rev[std::countl_zero(ray[fs].SW & occ)].SW)
^ bishopMoves[fs];
abb[ply] |= gbb[ply][fs];
gbb[ply][fs] &= notme;
break;
case BRC:
case BR:
gbb[ply][fs]
= (ray[std::countr_zero(ray[fs].NN & occ)].NN
| ray[std::countr_zero(ray[fs].EE & occ)].EE
| rev[std::countl_zero(ray[fs].SS & occ)].SS
| rev[std::countl_zero(ray[fs].WW & occ)].WW)
^ rookMoves[fs];
abb[ply] |= gbb[ply][fs];
gbb[ply][fs] &= notme;
break;
case BQ:
gbb[ply][fs]
= (ray[std::countr_zero(ray[fs].NW & occ)].NW
| ray[std::countr_zero(ray[fs].NE & occ)].NE
| rev[std::countl_zero(ray[fs].SE & occ)].SE
| rev[std::countl_zero(ray[fs].SW & occ)].SW
| ray[std::countr_zero(ray[fs].NN & occ)].NN
| ray[std::countr_zero(ray[fs].EE & occ)].EE
| rev[std::countl_zero(ray[fs].SS & occ)].SS
| rev[std::countl_zero(ray[fs].WW & occ)].WW)
^ queenMoves[fs];
abb[ply] |= gbb[ply][fs];
gbb[ply][fs] &= notme;
break;
case BKC:
gbb[ply][fs] = kingMoves[fs] & notme;
abb[ply] |= kingMoves[fs];
gbb[ply][fs] |= (u64)((board[h8] == BRC) + ((occ & SBCS) == 0) + (AttackedByWhite(t, ABCS) == 0) == 3) << g8;
gbb[ply][fs] |= (u64)((board[a8] == BRC) + ((occ & SBCL) == 0) + (AttackedByWhite(t, ABCL) == 0) == 3) << c8;
break;
case BK:
gbb[ply][fs] = kingMoves[fs] & notme;
abb[ply] |= kingMoves[fs];
break;
}
pieces ^= 1ull << fs;
} while (pieces);
return 1 - (king[1 - stm] & abb[ply]);
}
Code: Select all
// !
// Move.cpp
void MakeMove(Thread* t, uMove* m) {
switch (m->s.ft) {
case ES:
// can't get here
break;
case WP:
board[mfs] = ES;
board[mts] = WP;
piece[WHITE] ^= 1ull << mfs;
piece[WHITE] ^= 1ull << mts;
wpos -= pst[WP][mfs];
wpos += pst[WP][mts];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat -= val[mtt];
bpos -= pst[mtt][mts];
pctypbb[WP] ^= 1ull << mfs;
pctypbb[WP] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case WN:
board[mfs] = ES;
board[mts] = WN;
piece[WHITE] ^= 1ull << mfs;
piece[WHITE] ^= 1ull << mts;
wpos -= pst[WN][mfs];
wpos += pst[WN][mts];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat -= val[mtt];
bpos -= pst[mtt][mts];
pctypbb[WN] ^= 1ull << mfs;
pctypbb[WN] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case WB:
board[mfs] = ES;
board[mts] = WB;
piece[WHITE] ^= 1ull << mfs;
piece[WHITE] ^= 1ull << mts;
wpos -= pst[WB][mfs];
wpos += pst[WB][mts];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat -= val[mtt];
bpos -= pst[mtt][mts];
pctypbb[WB] ^= 1ull << mfs;
pctypbb[WB] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case WRC:
case WR:
board[mfs] = ES;
board[mts] = WR;
piece[WHITE] ^= 1ull << mfs;
piece[WHITE] ^= 1ull << mts;
wpos -= pst[WR][mfs];
wpos += pst[WR][mts];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat -= val[mtt];
bpos -= pst[mtt][mts];
pctypbb[WR] ^= 1ull << mfs;
pctypbb[WR] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case WQ:
board[mfs] = ES;
board[mts] = WQ;
piece[WHITE] ^= 1ull << mfs;
piece[WHITE] ^= 1ull << mts;
wpos -= pst[WQ][mfs];
wpos += pst[WQ][mts];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat -= val[mtt];
bpos -= pst[mtt][mts];
pctypbb[WQ] ^= 1ull << mfs;
pctypbb[WQ] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case WKC:
case WK:
board[mfs] = ES;
board[mts] = WK;
piece[WHITE] ^= 1ull << mfs;
piece[WHITE] ^= 1ull << mts;
king[WHITE] ^= 1ull << mfs;
king[WHITE] ^= 1ull << mts;
wpos -= pst[WK][mfs];
wpos += pst[WK][mts];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat -= val[mtt];
bpos -= pst[mtt][mts];
pctypbb[mtt] ^= 1ull << mts;
break;
case BP:
board[mfs] = ES;
board[mts] = BP;
piece[BLACK] ^= 1ull << mfs;
piece[BLACK] ^= 1ull << mts;
bpos -= pst[BP][mfs];
bpos += pst[BP][mts];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat -= val[mtt];
wpos -= pst[mtt][mts];
pctypbb[BP] ^= 1ull << mfs;
pctypbb[BP] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case BN:
board[mfs] = ES;
board[mts] = BN;
piece[BLACK] ^= 1ull << mfs;
piece[BLACK] ^= 1ull << mts;
bpos -= pst[BN][mfs];
bpos += pst[BN][mts];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat -= val[mtt];
wpos -= pst[mtt][mts];
pctypbb[BN] ^= 1ull << mfs;
pctypbb[BN] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case BB:
board[mfs] = ES;
board[mts] = BB;
piece[BLACK] ^= 1ull << mfs;
piece[BLACK] ^= 1ull << mts;
bpos -= pst[BB][mfs];
bpos += pst[BB][mts];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat -= val[mtt];
wpos -= pst[mtt][mts];
pctypbb[BB] ^= 1ull << mfs;
pctypbb[BB] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case BRC:
case BR:
board[mfs] = ES;
board[mts] = BR;
piece[BLACK] ^= 1ull << mfs;
piece[BLACK] ^= 1ull << mts;
bpos -= pst[BR][mfs];
bpos += pst[BR][mts];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat -= val[mtt];
wpos -= pst[mtt][mts];
pctypbb[BR] ^= 1ull << mfs;
pctypbb[BR] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case BQ:
board[mfs] = ES;
board[mts] = BQ;
piece[BLACK] ^= 1ull << mfs;
piece[BLACK] ^= 1ull << mts;
bpos -= pst[BQ][mfs];
bpos += pst[BQ][mts];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat -= val[mtt];
wpos -= pst[mtt][mts];
pctypbb[BQ] ^= 1ull << mfs;
pctypbb[BQ] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case BKC:
case BK:
board[mfs] = ES;
board[mts] = BK;
piece[BLACK] ^= 1ull << mfs;
piece[BLACK] ^= 1ull << mts;
king[BLACK] ^= 1ull << mfs;
king[BLACK] ^= 1ull << mts;
bpos -= pst[BK][mfs];
bpos += pst[BK][mts];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat -= val[mtt];
wpos -= pst[mtt][mts];
pctypbb[mtt] ^= 1ull << mts;
break;
case WCS:
board[e1] = ES;
board[g1] = WK;
piece[WHITE] ^= 1ull << e1;
piece[WHITE] ^= 1ull << g1;
king[WHITE] ^= 1ull << e1;
king[WHITE] ^= 1ull << g1;
wpos -= pst[WK][e1];
wpos += pst[WK][g1];
board[h1] = ES;
board[f1] = WR;
piece[WHITE] ^= 1ull << h1;
piece[WHITE] ^= 1ull << f1;
wpos += 10;
pctypbb[WR] ^= 1ull << h1;
pctypbb[WR] ^= 1ull << f1;
break;
case WCL:
board[e1] = ES;
board[c1] = WK;
piece[WHITE] ^= 1ull << e1;
piece[WHITE] ^= 1ull << c1;
king[WHITE] ^= 1ull << e1;
king[WHITE] ^= 1ull << c1;
wpos -= pst[WK][e1];
wpos += pst[WK][c1];
board[a1] = ES;
board[d1] = WR;
piece[WHITE] ^= 1ull << a1;
piece[WHITE] ^= 1ull << d1;
wpos += 8;
pctypbb[WR] ^= 1ull << a1;
pctypbb[WR] ^= 1ull << d1;
break;
case WPD:
board[mfs] = ES;
board[mts] = WP;
piece[WHITE] ^= 1ull << mfs;
piece[WHITE] ^= 1ull << mts;
wpos -= pst[WP][mfs];
wpos += pst[WP][mts];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat -= val[mtt];
bpos -= pst[mtt][mts];
pctypbb[WP] ^= 1ull << mfs;
pctypbb[WP] ^= 1ull << mts;
epbit[ply + 1] = 1ull << (mts - 8);
break;
case WPE:
board[mfs] = ES;
board[mts] = WP;
piece[WHITE] ^= 1ull << mfs;
piece[WHITE] ^= 1ull << mts;
wpos -= pst[WP][mfs];
wpos += pst[WP][mts];
board[mts - 8] = ES;
piece[BLACK] ^= 1ull << (mts - 8);
bmat -= val[BP];
bpos -= pst[BP][mts - 8];
pctypbb[WP] ^= 1ull << mfs;
pctypbb[WP] ^= 1ull << mts;
pctypbb[BP] ^= 1ull << (mts - 8);
break;
case WPQ:
board[mfs] = ES;
board[mts] = WQ;
piece[WHITE] ^= 1ull << mfs;
piece[WHITE] ^= 1ull << mts;
wpos -= pst[WP][mfs];
wpos += pst[WQ][mts];
wmat += 80;
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat -= val[mtt];
bpos -= pst[mtt][mts];
pctypbb[WP] ^= 1ull << mfs;
pctypbb[WQ] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case WPN:
board[mfs] = ES;
board[mts] = WN;
piece[WHITE] ^= 1ull << mfs;
piece[WHITE] ^= 1ull << mts;
wpos -= pst[WP][mfs];
wpos += pst[WN][mts];
wmat += 19;
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat -= val[mtt];
bpos -= pst[mtt][mts];
pctypbb[WP] ^= 1ull << mfs;
pctypbb[WN] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case WPR:
board[mfs] = ES;
board[mts] = WR;
piece[WHITE] ^= 1ull << mfs;
piece[WHITE] ^= 1ull << mts;
wpos -= pst[WP][mfs];
wpos += pst[WR][mts];
wmat += 40;
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat -= val[mtt];
bpos -= pst[mtt][mts];
pctypbb[WP] ^= 1ull << mfs;
pctypbb[WR] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case WPB:
board[mfs] = ES;
board[mts] = WB;
piece[WHITE] ^= 1ull << mfs;
piece[WHITE] ^= 1ull << mts;
wpos -= pst[WP][mfs];
wpos += pst[WB][mts];
wmat += 22;
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat -= val[mtt];
bpos -= pst[mtt][mts];
pctypbb[WP] ^= 1ull << mfs;
pctypbb[WB] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case BCS:
board[e8] = ES;
board[g8] = BK;
piece[BLACK] ^= 1ull << e8;
piece[BLACK] ^= 1ull << g8;
king[BLACK] ^= 1ull << e8;
king[BLACK] ^= 1ull << g8;
bpos -= pst[BK][e8];
bpos += pst[BK][g8];
board[h8] = ES;
board[f8] = BR;
piece[BLACK] ^= 1ull << h8;
piece[BLACK] ^= 1ull << f8;
bpos += 10;
pctypbb[BR] ^= 1ull << h8;
pctypbb[BR] ^= 1ull << f8;
break;
case BCL:
board[e8] = ES;
board[c8] = BK;
piece[BLACK] ^= 1ull << e8;
piece[BLACK] ^= 1ull << c8;
king[BLACK] ^= 1ull << e8;
king[BLACK] ^= 1ull << c8;
bpos -= pst[BK][e8];
bpos += pst[BK][c8];
board[a8] = ES;
board[d8] = BR;
piece[BLACK] ^= 1ull << a8;
piece[BLACK] ^= 1ull << d8;
bpos += 8;
pctypbb[BR] ^= 1ull << a8;
pctypbb[BR] ^= 1ull << d8;
break;
case BPD:
board[mfs] = ES;
board[mts] = BP;
piece[BLACK] ^= 1ull << mfs;
piece[BLACK] ^= 1ull << mts;
bpos -= pst[BP][mfs];
bpos += pst[BP][mts];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat -= val[mtt];
wpos -= pst[mtt][mts];
pctypbb[BP] ^= 1ull << mfs;
pctypbb[BP] ^= 1ull << mts;
epbit[ply + 1] = 1ull << (mts + 8);
break;
case BPE:
board[mfs] = ES;
board[mts] = BP;
piece[BLACK] ^= 1ull << mfs;
piece[BLACK] ^= 1ull << mts;
wpos -= pst[WP][mfs];
wpos += pst[WP][mts];
board[mts + 8] = ES;
piece[WHITE] ^= 1ull << (mts + 8);
wmat -= val[WP];
wpos -= pst[WP][mts + 8];
pctypbb[BP] ^= 1ull << mfs;
pctypbb[BP] ^= 1ull << mts;
pctypbb[WP] ^= 1ull << (mts + 8);
break;
case BPQ:
board[mfs] = ES;
board[mts] = BQ;
piece[BLACK] ^= 1ull << mfs;
piece[BLACK] ^= 1ull << mts;
bpos -= pst[BP][mfs];
bpos += pst[BQ][mts];
bmat += 80;
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat -= val[mtt];
wpos -= pst[mtt][mts];
pctypbb[BP] ^= 1ull << mfs;
pctypbb[BQ] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case BPN:
board[mfs] = ES;
board[mts] = BN;
piece[BLACK] ^= 1ull << mfs;
piece[BLACK] ^= 1ull << mts;
bpos -= pst[BP][mfs];
bpos += pst[BN][mts];
bmat += 19;
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat -= val[mtt];
wpos -= pst[mtt][mts];
pctypbb[BP] ^= 1ull << mfs;
pctypbb[BN] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case BPR:
board[mfs] = ES;
board[mts] = BR;
piece[BLACK] ^= 1ull << mfs;
piece[BLACK] ^= 1ull << mts;
bpos -= pst[BP][mfs];
bpos += pst[BN][mts];
bmat += 40;
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat -= val[mtt];
wpos -= pst[mtt][mts];
pctypbb[BP] ^= 1ull << mfs;
pctypbb[BR] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
case BPB:
board[mfs] = ES;
board[mts] = BB;
piece[BLACK] ^= 1ull << mfs;
piece[BLACK] ^= 1ull << mts;
bpos -= pst[BP][mfs];
bpos += pst[BB][mts];
bmat += 22;
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat -= val[mtt];
wpos -= pst[mtt][mts];
pctypbb[BP] ^= 1ull << mfs;
pctypbb[BB] ^= 1ull << mts;
pctypbb[mtt] ^= 1ull << mts;
break;
}
ply++;
stm = 1 - stm;
}
void TakeBack(Thread* t, uMove* m) {
s08 ft;
ply--;
stm = 1 - stm;
ft = m->s.ft;
switch (ft) {
case ES:
// can't get here
break;
case WP:
board[mfs] = WP;
board[mts] = mtt;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
wpos -= pst[WP][mts];
wpos += pst[WP][mfs];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat += val[mtt];
bpos += pst[mtt][mts];
pctypbb[WP] ^= 1ull << mts;
pctypbb[WP] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case WN:
board[mfs] = WN;
board[mts] = mtt;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
wpos -= pst[WN][mts];
wpos += pst[WN][mfs];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat += val[mtt];
bpos += pst[mtt][mts];
pctypbb[WN] ^= 1ull << mts;
pctypbb[WN] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case WB:
board[mfs] = WB;
board[mts] = mtt;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
wpos -= pst[WB][mts];
wpos += pst[WB][mfs];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat += val[mtt];
bpos += pst[mtt][mts];
pctypbb[WB] ^= 1ull << mts;
pctypbb[WB] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case WRC:
board[mfs] = WRC;
board[mts] = mtt;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
wpos -= pst[WR][mts];
wpos += pst[WR][mfs];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat += val[mtt];
bpos += pst[mtt][mts];
pctypbb[WR] ^= 1ull << mts;
pctypbb[WR] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case WR:
board[mfs] = WR;
board[mts] = mtt;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
wpos -= pst[WR][mts];
wpos += pst[WR][mfs];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat += val[mtt];
bpos += pst[mtt][mts];
pctypbb[WR] ^= 1ull << mts;
pctypbb[WR] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case WQ:
board[mfs] = WQ;
board[mts] = mtt;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
wpos -= pst[WQ][mts];
wpos += pst[WQ][mfs];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat += val[mtt];
bpos += pst[mtt][mts];
pctypbb[WQ] ^= 1ull << mts;
pctypbb[WQ] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case WKC:
board[mfs] = WKC;
board[mts] = mtt;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
king[WHITE] ^= 1ull << mts;
king[WHITE] ^= 1ull << mfs;
wpos -= pst[WK][mts];
wpos += pst[WK][mfs];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat += val[mtt];
bpos += pst[mtt][mts];
pctypbb[mtt] ^= 1ull << mts;
break;
case WK:
board[mfs] = WK;
board[mts] = mtt;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
king[WHITE] ^= 1ull << mts;
king[WHITE] ^= 1ull << mfs;
wpos -= pst[WK][mts];
wpos += pst[WK][mfs];
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat += val[mtt];
bpos += pst[mtt][mts];
pctypbb[mtt] ^= 1ull << mts;
break;
case BP:
board[mfs] = BP;
board[mts] = mtt;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
bpos -= pst[BP][mts];
bpos += pst[BP][mfs];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat += val[mtt];
wpos += pst[mtt][mts];
pctypbb[BP] ^= 1ull << mts;
pctypbb[BP] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case BN:
board[mfs] = BN;
board[mts] = mtt;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
bpos -= pst[BN][mts];
bpos += pst[BN][mfs];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat += val[mtt];
wpos += pst[mtt][mts];
pctypbb[BN] ^= 1ull << mts;
pctypbb[BN] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case BB:
board[mfs] = BB;
board[mts] = mtt;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
bpos -= pst[BB][mts];
bpos += pst[BB][mfs];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat += val[mtt];
wpos += pst[mtt][mts];
pctypbb[BB] ^= 1ull << mts;
pctypbb[BB] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case BRC:
board[mfs] = BRC;
board[mts] = mtt;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
bpos -= pst[BR][mts];
bpos += pst[BR][mfs];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat += val[mtt];
wpos += pst[mtt][mts];
pctypbb[BR] ^= 1ull << mts;
pctypbb[BR] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case BR:
board[mfs] = BR;
board[mts] = mtt;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
bpos -= pst[BR][mts];
bpos += pst[BR][mfs];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat += val[mtt];
wpos += pst[mtt][mts];
pctypbb[BR] ^= 1ull << mts;
pctypbb[BR] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case BQ:
board[mfs] = BQ;
board[mts] = mtt;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
bpos -= pst[BR][mts];
bpos += pst[BR][mfs];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat += val[mtt];
wpos += pst[mtt][mts];
pctypbb[BQ] ^= 1ull << mts;
pctypbb[BQ] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case BKC:
board[mfs] = BKC;
board[mts] = mtt;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
king[BLACK] ^= 1ull << mts;
king[BLACK] ^= 1ull << mfs;
bpos -= pst[BK][mts];
bpos += pst[BK][mfs];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat += val[mtt];
wpos += pst[mtt][mts];
pctypbb[mtt] ^= 1ull << mts;
break;
case BK:
board[mfs] = BK;
board[mts] = mtt;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
king[BLACK] ^= 1ull << mts;
king[BLACK] ^= 1ull << mfs;
bpos -= pst[BK][mts];
bpos -= pst[BK][mts];
bpos += pst[BK][mfs];
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat += val[mtt];
wpos += pst[mtt][mts];
pctypbb[mtt] ^= 1ull << mts;
break;
case WCS:
board[e1] = WKC;
board[g1] = ES;
piece[WHITE] ^= 1ull << g1;
piece[WHITE] ^= 1ull << e1;
king[WHITE] ^= 1ull << g1;
king[WHITE] ^= 1ull << e1;
bpos -= pst[BK][mts];
wpos -= pst[WK][g1];
wpos += pst[WK][e1];
board[h1] = WRC;
board[f1] = ES;
piece[WHITE] ^= 1ull << f1;
piece[WHITE] ^= 1ull << h1;
wpos -= pst[WR][f1];
wpos += pst[WR][h1];
pctypbb[WR] ^= 1ull << f1;
pctypbb[WR] ^= 1ull << h1;
break;
case WCL:
board[e1] = WKC;
board[c1] = ES;
piece[WHITE] ^= 1ull << c1;
piece[WHITE] ^= 1ull << e1;
king[WHITE] ^= 1ull << c1;
king[WHITE] ^= 1ull << e1;
wpos -= pst[WK][c1];
wpos += pst[WK][e1];
board[a1] = WRC;
board[d1] = ES;
piece[WHITE] ^= 1ull << d1;
piece[WHITE] ^= 1ull << a1;
wpos -= pst[WR][d1];
wpos += pst[WR][a1];
pctypbb[WR] ^= 1ull << d1;
pctypbb[WR] ^= 1ull << a1;
break;
case WPD:
board[mfs] = WP;
board[mts] = ES;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
wpos -= pst[WP][mts];
wpos += pst[WP][mfs];
epbit[ply + 1] = 0;
pctypbb[WP] ^= 1ull << mts;
pctypbb[WP] ^= 1ull << mfs;
break;
case WPE:
board[mfs] = WP;
board[mts] = ES;
board[mts - 8] = BP;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
wpos -= pst[WP][mts];
wpos += pst[WP][mfs];
piece[BLACK] ^= 1ULL << (mts - 8);
bmat += val[BP];
bpos += pst[BP][mts];
pctypbb[WP] ^= 1ull << mts;
pctypbb[WP] ^= 1ull << mfs;
pctypbb[BP] ^= 1ull << (mts - 8);
break;
case WPQ:
board[mfs] = WP;
board[mts] = mtt;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
wpos -= pst[WQ][mts];
wpos += pst[WP][mfs];
wmat -= 80;
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat += val[mtt];
bpos += pst[mtt][mts];
pctypbb[WQ] ^= 1ull << mts;
pctypbb[WP] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case WPN:
board[mfs] = WP;
board[mts] = mtt;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
wpos -= pst[WN][mts];
wpos += pst[WP][mfs];
wmat -= 19;
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat += val[mtt];
bpos += pst[mtt][mts];
pctypbb[WN] ^= 1ull << mts;
pctypbb[WP] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case WPR:
board[mfs] = WP;
board[mts] = mtt;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
wpos -= pst[WR][mts];
wpos += pst[WP][mfs];
wmat -= 40;
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat += val[mtt];
bpos += pst[mtt][mts];
pctypbb[WR] ^= 1ull << mts;
pctypbb[WP] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case WPB:
board[mfs] = WP;
board[mts] = mtt;
piece[WHITE] ^= 1ull << mts;
piece[WHITE] ^= 1ull << mfs;
wpos -= pst[WB][mts];
wpos += pst[WP][mfs];
wmat -= 22;
piece[BLACK] ^= (u64)(mtt != ES) << mts;
bmat += val[mtt];
bpos += pst[mtt][mts];
pctypbb[WB] ^= 1ull << mts;
pctypbb[WP] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case BCS:
board[e8] = BKC;
board[g8] = ES;
piece[BLACK] ^= 1ull << g8;
piece[BLACK] ^= 1ull << e8;
king[BLACK] ^= 1ull << g8;
king[BLACK] ^= 1ull << e8;
bpos -= pst[BK][g8];
bpos += pst[BK][e8];
board[h8] = BRC;
board[f8] = ES;
piece[BLACK] ^= 1ull << f8;
piece[BLACK] ^= 1ull << h8;
bpos -= pst[BR][f8];
bpos += pst[BR][h8];
pctypbb[BR] ^= 1ull << f8;
pctypbb[BR] ^= 1ull << h8;
break;
case BCL:
board[e8] = BKC;
board[c8] = ES;
piece[BLACK] ^= 1ull << c8;
piece[BLACK] ^= 1ull << e8;
king[BLACK] ^= 1ull << c8;
king[BLACK] ^= 1ull << e8;
bpos -= pst[BK][c8];
bpos += pst[BK][e8];
board[a8] = BRC;
board[d8] = ES;
piece[BLACK] ^= 1ull << c8;
piece[BLACK] ^= 1ull << a8;
bpos -= pst[BR][d8];
bpos += pst[BR][a8];
pctypbb[BR] ^= 1ull << c8;
pctypbb[BR] ^= 1ull << a8;
break;
case BPD:
board[mfs] = BP;
board[mts] = ES;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
bpos -= pst[BP][mts];
bpos += pst[BP][mfs];
pctypbb[BP] ^= 1ull << mts;
pctypbb[BP] ^= 1ull << mfs;
epbit[ply + 1] = 0;
break;
case BPE:
board[mfs] = BP;
board[mts] = ES;
board[mts + 8] = WP;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
bpos -= pst[BP][mts];
bpos += pst[BP][mfs];
piece[WHITE] ^= 1ULL << (mts + 8);
bmat += val[WP];
bpos += pst[WP][mts];
pctypbb[BP] ^= 1ull << mts;
pctypbb[BP] ^= 1ull << mfs;
pctypbb[WP] ^= 1ull << (mts + 8);
break;
case BPQ:
board[mfs] = BP;
board[mts] = mtt;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
bpos -= pst[BQ][mts];
bpos += pst[BP][mfs];
bmat -= 80;
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat += val[mtt];
wpos += pst[mtt][mts];
pctypbb[BQ] ^= 1ull << mts;
pctypbb[BP] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case BPN:
board[mfs] = BP;
board[mts] = mtt;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
bpos -= pst[BN][mts];
bpos += pst[BP][mfs];
bmat -= 19;
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat += val[mtt];
wpos += pst[mtt][mts];
pctypbb[BN] ^= 1ull << mts;
pctypbb[BP] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case BPR:
board[mfs] = BP;
board[mts] = mtt;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
bpos -= pst[BR][mts];
bpos += pst[BP][mfs];
bmat -= 40;
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat += val[mtt];
wpos += pst[mtt][mts];
pctypbb[BR] ^= 1ull << mts;
pctypbb[BP] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
case BPB:
board[mfs] = BP;
board[mts] = mtt;
piece[BLACK] ^= 1ull << mts;
piece[BLACK] ^= 1ull << mfs;
bpos -= pst[BB][mts];
bpos += pst[BP][mfs];
bmat -= 22;
piece[WHITE] ^= (u64)(mtt != ES) << mts;
wmat += val[mtt];
wpos += pst[mtt][mts];
pctypbb[BB] ^= 1ull << mts;
pctypbb[BP] ^= 1ull << mfs;
pctypbb[mtt] ^= 1ull << mts;
break;
}
}
Code: Select all
// !
// Utilities.cpp
void PrintBoard(Thread* t) {
s32 x, y, sq, pce;
s08 fig[] = { ".PNBRRQKKpnbrrqkk" };
for (y = 7; y >= 0; y--) {
for (x = 0; x < 8; x++) {
sq = ((y << 3) + x);
pce = board[sq];
std::cout << " " << fig[pce];
}
std::cout << std::endl;
}
std::cout << std::endl;
}
bool LoadFen(Thread* t, s08* f) {
s32 rank, file, sq, fs, pce;
for (sq = a1; sq <= h8; sq++) board[sq] = ES;
ply = 0;
file = FILEa;
rank = RANK8;
fs = 56;
for (;; f++) {
if (*f == ' ') break;
switch (*f) {
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
file += *f - '0';
fs = (rank * 8 + file) & 63;
continue;
case '/':
file = FILEa;
rank--;
fs = (rank * 8 + file) & 63;
continue;
case 'P':
pce = WP;
break;
case 'N':
pce = WN;
break;
case 'B':
pce = WB;
break;
case 'R':
pce = WR;
break;
case 'Q':
pce = WQ;
break;
case 'K':
pce = WK;
break;
case 'p':
pce = BP;
break;
case 'n':
pce = BN;
break;
case 'b':
pce = BB;
break;
case 'r':
pce = BR;
break;
case 'q':
pce = BQ;
break;
case 'k':
pce = BK;
break;
}
board[fs] = pce;
file++;
fs = (rank * 8 + file) & 63;
}
f++;
switch (*f++) {
case 'w':
stm = WHITE;
break;
case 'b':
stm = BLACK;
break;
default:
return false;
}
if (*f++ != ' ') return false;
if (*f == '-') {
f++;
if (*f++ != ' ') return false;
}
else {
for (;;) {
if (*f == ' ') {
f++;
break;
}
switch (*f++) {
case 'K':
board[e1] = WKC;
board[h1] = WRC;
break;
case 'Q':
board[e1] = WKC;
board[a1] = WRC;
break;
case 'k':
board[e8] = BKC;
board[h8] = BRC;
break;
case 'q':
board[e8] = BKC;
board[a8] = BRC;
break;
default:
return false;
}
}
}
epbit[0] = 0;
if (*f == '-') f++;
else {
if (*f < 'a' || *f > 'h') return false;
if (*(f + 1) < '0' || *(f + 1) > '7') return false;
rank = *(f + 1) - '1';
file = *f - 'a';
f += 2;
}
if (*f++ != ' ') return false;
fifty[0] = 0;
for (;;) {
if (!isdigit(*f)) break;
fifty[0] = *f++ * 10;
fifty[0] += *f++ - '0';
}
if (*f++ != ' ') return false;
start = 0;
for (;;) {
if (!isdigit(*f)) break;
start = *f++ * 10;
start += *f++ - '0';
}
if (start < 1) return false;
while (*f == ' ') f++;
if (*f != '\0') return false;
return true;
}
s32 AttackedByWhite(Thread* t, u64 bb) {
s32 n = 0;
u64 bbn;
u64 occ = piece[BLACK] | piece[WHITE];
do {
s32 sq = std::countr_zero(bb);
bbn = (knightMoves[sq] & pctypbb[WN])
| (bPawnCapts[sq] & pctypbb[WP])
| (kingMoves[sq] & pctypbb[WK])
| (((ray[std::countr_zero(ray[sq].NW & occ)].NW
| ray[std::countr_zero(ray[sq].NE & occ)].NE
| rev[std::countl_zero(ray[sq].SE & occ)].SE
| rev[std::countl_zero(ray[sq].SW & occ)].SW)
^ bishopMoves[sq])
& (pctypbb[WB] | pctypbb[WQ]))
| (((ray[std::countr_zero(ray[sq].NN & occ)].NN
| ray[std::countr_zero(ray[sq].EE & occ)].EE
| rev[std::countl_zero(ray[sq].SS & occ)].SS
| rev[std::countl_zero(ray[sq].WW & occ)].WW)
^ rookMoves[sq])
& (pctypbb[WR] | pctypbb[WQ]));
n += std::popcount(bbn);
bb ^= 1ull << sq;
} while (bb);
return n;
}
s32 AttackedByBlack(Thread* t, u64 bb) {
s32 n = 0;
u64 bbn;
u64 occ = piece[BLACK] | piece[WHITE];
do {
s32 sq = std::countr_zero(bb);
bbn = (knightMoves[sq] & pctypbb[BN])
| (wPawnCapts[sq] & pctypbb[BP])
| (kingMoves[sq] & pctypbb[BK])
| (((ray[std::countr_zero(ray[sq].NW & occ)].NW
| ray[std::countr_zero(ray[sq].NE & occ)].NE
| rev[std::countl_zero(ray[sq].SE & occ)].SE
| rev[std::countl_zero(ray[sq].SW & occ)].SW)
^ bishopMoves[sq])
& (pctypbb[BB] | pctypbb[BQ]))
| (((ray[std::countr_zero(ray[sq].NN & occ)].NN
| ray[std::countr_zero(ray[sq].EE & occ)].EE
| rev[std::countl_zero(ray[sq].SS & occ)].SS
| rev[std::countl_zero(ray[sq].WW & occ)].WW)
^ rookMoves[sq])
& (pctypbb[BR] | pctypbb[BQ]));
n += std::popcount(bbn);
bb ^= 1ull << sq;
} while (bb);
return n;
}
s32(*InCheckBy[2])(Thread*, u64) = { AttackedByBlack, AttackedByWhite };
uMove FillMoveFields(Thread* t, s08 fs, s08 ts) {
uMove m;
m.s.fs = fs;
m.s.ts = ts;
m.s.tt = board[ts];
m.s.ft = board[fs];
switch (m.s.ft) {
case ES:
// can't get here
break;
case WP:
switch (fs >> 3) {
case RANK1:
// can't get here
break;
case RANK2:
m.s.ft += ((fs + 16 == ts) * (WPD - WP));
break;
case RANK3:
case RANK4:
// no action
break;
case RANK5:
m.s.ft += ((ts != fs + 8 && !m.s.tt) * (WPE - WP));
break;
case RANK6:
// no action
break;
case RANK7:
m.s.ft = WPQ;
break;
}
break;
case WN:
case WB:
case WRC:
case WR:
case WQ:
// no action
break;
case WKC:
m.s.ft += ((ts == g1) * (WCS - WKC) + (ts == c1) * (WCL - WKC));
break;
case WK:
// no action
break;
case BP:
switch (fs >> 3) {
case RANK1:
// can't get here
break;
case RANK2:
m.s.ft = BPQ;
break;
case RANK3:
// no action
break;
case RANK4:
m.s.ft += ((ts != fs - 8 && !m.s.tt) * (BPE - BP));
break;
case RANK5:
case RANK6:
// no action
break;
case RANK7:
m.s.ft += ((fs - 16 == ts) * (BPD - BP));
break;
}
break;
case BN:
case BB:
case BRC:
case BR:
case BQ:
// no action
break;
case BKC:
m.s.ft += ((ts == g8) * (BCS - BKC) + (ts == c8) * (BCL - BKC));
break;
}
return m;
}
Code: Select all
// !
// Globals.cpp
s32 mode;
s32 computer;
s32 numThreads;
Thread** thread;
Ray ray[65];
Ray rev[65];
u64 wPawnCapts[64];
u64 bPawnCapts[64];
u64 knightMoves[64];
u64 bishopMoves[64];
u64 rookMoves[64];
u64 queenMoves[64];
u64 kingMoves[64];
s32 val[] = { 0, 10, 29, 32, 50, 50, 90, 0, 0, 10, 29, 32, 50, 50, 90, 0, 0 };
s32 pst[17][64];
s08 startFen[] = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
s08 fen[100];
Code: Select all
// !
// Equates.cpp
constexpr auto AWCS = 0b0000000000000000000000000000000000000000000000000000000001110000;
constexpr auto AWCL = 0b0000000000000000000000000000000000000000000000000000000000011100;
constexpr auto ABCS = 0b0111000000000000000000000000000000000000000000000000000000000000;
constexpr auto ABCL = 0b0001110000000000000000000000000000000000000000000000000000000000;
constexpr auto SWCS = 0b0000000000000000000000000000000000000000000000000000000001100000;
constexpr auto SWCL = 0b0000000000000000000000000000000000000000000000000000000000001110;
constexpr auto SBCS = 0b0110000000000000000000000000000000000000000000000000000000000000;
constexpr auto SBCL = 0b0000111000000000000000000000000000000000000000000000000000000000;
enum { EXIT, GETCMD, SEARCH };
enum { BLACK, WHITE };
enum { ILLEGAL, LEGAL };
enum {
a1, b1, c1, d1, e1, f1, g1, h1,
a2, b2, c2, d2, e2, f2, g2, h2,
a3, b3, c3, d3, e3, f3, g3, h3,
a4, b4, c4, d4, e4, f4, g4, h4,
a5, b5, c5, d5, e5, f5, g5, h5,
a6, b6, c6, d6, e6, f6, g6, h6,
a7, b7, c7, d7, e7, f7, g7, h7,
a8, b8, c8, d8, e8, f8, g8, h8
};
enum { FILEa, FILEb, FILEc, FILEd, FILEe, FILEf, FILEg, FILEh };
enum { RANK1, RANK2, RANK3, RANK4, RANK5, RANK6, RANK7, RANK8 };
enum {
ES,
WP, WN, WB, WRC, WR, WQ, WKC, WK,
BP, BN, BB, BRC, BR, BQ, BKC, BK,
WCS, WCL, WPD, WPE, WPQ, WPN, WPR, WPB,
BCS, BCL, BPD, BPE, BPQ, BPN, BPR, BPB
};
Code: Select all
// !
// Defines.cpp
typedef char s08;
typedef int s32;
typedef unsigned long long u64;
typedef long long s64;
#define dir_HO(X) (0xFFull << (X & 56))
#define dir_VE(X) (0x0101010101010101ull << (X & 7))
#define dir_D1(X) (mask_shift(0x8040201008040201ull, (X & 7) - (X >> 3)))
#define dir_D2(X) (mask_shift(0x0102040810204080ull, 7 - (X & 7) - (X >> 3)))
#define GetLower(X) ((1ull << X) - 1)
#define GetUpper(X) (0xFFFFFFFFFFFFFFFE << (X))
struct Ray {
u64 NW;
u64 NN;
u64 NE;
u64 EE;
u64 SE;
u64 SS;
u64 SW;
u64 WW;
};
struct sMove {
s08 fs; // from square
s08 ts; // to square
s08 ft; // from type
s08 tt; // to type
s32 sc; // score
};
union uMove {
sMove s;
u64 u;
};
// instead of typing m->s.fs just type mfs
#define mfs m->s.fs
#define mts m->s.ts
#define mft m->s.ft
#define mtt m->s.tt
struct Thread {
uMove g[500];
u64 piece[2];
u64 king[2];
u64 pctypbb[17];
u64 epbit[100];
u64 abb[100];
u64 gbb[100][64];
s32 board[64];
s32 fifty[100];
s32 ply;
s32 gly;
s32 stm;
s32 wmat;
s32 bmat;
s32 wpos;
s32 bpos;
s32 start;
};
// to avoid having to type t->whatever just type whatever
#define g t->g
#define piece t->piece
#define king t->king
#define pctypbb t->pctypbb
#define epbit t->epbit
#define abb t->abb
#define gbb t->gbb
#define board t->board
#define fifty t->fifty
#define ply t->ply
#define gly t->gly
#define stm t->stm
#define matsc t->matsc
#define wmat t->wmat
#define bmat t->bmat
#define wpos t->wpos
#define bpos t->bpos
#define start t->start