I'm new to chess-programming (experienced with chess and with programming separately ). I just read a lot of about it in last months and felt ready to start coding. After writing now some code, I have few basic question:
1. I started in C++ and I'm little confused how to organize my code. Should I use classes, structures or rather don't use any of them (what will give better performance)? For example when I have bitboards storing whole position:
Code: Select all
U64 wKing;
U64 wQueens;
(...)
U64 wPieces;
U64 bKing;
(...)
U64 bPieces;
U64 allPieces;
2. Another question connected with code organization: How to divide my code in to separated .cpp and .h files. What can I keep in header files and what rather not? For example I put every enumerations, typedefs constants and so on in to separated ".h" file and think it's ok. But I put also to another header file stuff like:
Code: Select all
U64 squaresMask[64];
U64 kingtAttacks[64];
void initMasks() {...}
void initAttacks() {...}
etc.
3. Now some doubts in move generation. I decided to init all arrays of bitbords attacks in the start of the engine. But how fast should it be? Is there any better solution than looping through all squares (non-sliding pieces) like that:
Code: Select all
//King's attacks corners:
kingAttacks[A1] = squaresMask[A2] | squaresMask[B1] | squaresMask[B2];
kingAttacks[A8] = squaresMask[A7] | squaresMask[B8] | squaresMask[B7];
kingAttacks[H1] = squaresMask[H2] | squaresMask[G1] | squaresMask[G2];
kingAttacks[H8] = squaresMask[H7] | squaresMask[G8] | squaresMask[G7];
//King's attacks first rank:
for (int i = 1; i < 8; ++i)
{
kingAttacks[i] = squaresMask[i + DIR_N] | squaresMask[i + DIR_NE] | squaresMask[i + DIR_NW] | squaresMask[i + DIR_W] | squaresMask[i + DIR_E];
}
then last rank, first file, last file ...
//King's attacks rest of board:
for (int i = 8; i <= 55; ++i)
{
if ((i % 8 == 0) && ((i + 1) % 8 == 0)) { continue; }
kingAttacks[i] = squaresMask[i + DIR_N] | squaresMask[i + DIR_S] | squaresMask[i + DIR_W] | squaresMask[i + DIR_E] | squaresMask[i + DIR_NW] | squaresMask[i + DIR_NE] | squaresMask[i + DIR_SW] | squaresMask[i + DIR_SE];
}
Code: Select all
//Knight's attacks
for (int i = 0; i < 63; ++i)
{
knightAttacks[i] = 0ULL;
if (i + 17 < 63) { knightAttacks[i] |= squaresMask[i + 17]; }
if (i - 17 > 0) { knightAttacks[i] |= squaresMask[i - 17]; }
if (i + 15 < 63) { knightAttacks[i] |= squaresMask[i + 15]; }
if (i - 15 > 0) { knightAttacks[i] |= squaresMask[i - 15]; }
if (i + 6 < 63) { knightAttacks[i] |= squaresMask[i + 6]; }
if (i - 6 > 0) { knightAttacks[i] |= squaresMask[i - 6]; }
if (i + 10 < 63) { knightAttacks[i] |= squaresMask[i + 10]; }
if (i - 10 > 0) { knightAttacks[i] |= squaresMask[i - 10]; }
}
Code: Select all
U64 rookRankAttacks[64][64];
U64 rookFileAttacks[64][64];
Sorry if my post is too long or my questions are too basic I read a lot, but for sure I didn't find all articles in the internet, so every link will be appreciate.
Thanks for all answers.
Regards,
Paulo