For move generation i basically just followed the guide from Code Monkey King in his youtube series, and also i took a little of inspiration from cosette ( for move formatting )
My move formatting is as follows:
Code: Select all
/*
A chess movement is encoded in 16 bits: binary:
bit 0-6 : square from 0000 000000 111111
bit 7-12 : square to 0000 111111 000000
bit 13-16 : Flag 1111 000000 000000
*/
The flag is very similar as the moveFlag in cosette, an enum starting from index 0, to index 12
My moves are not in an struct, i encode the moves in just an unsinged int of 16 bits. ( 'ushort' type in C# ), i encode them using binary shifts and operators.
I basically have a flag to generate or not quiet moves in the generate moves function (that flag is disabled in QS, you'll know that later)
In my experience is better to encapsulate the pseudo-legal move generation in a single function, rather than having separate functions and call them all in the main "generateMoves()" function.
i first generate:
- King moves
if there's double check, return the list early, if not i countinue generating the remaining moves.
i just use bitmasks to check if the piece is attacking another piece, and i substract the attacks from my friendly pieces ( we don't want friendly fire

)
To give you an example, this is for attacks for knights:
Code: Select all
// ---------------- [ Knight ] --------------------
pieces = bitboards[sideToMove] & bitboards[ChessPiece.Knight];
while(pieces > 0)
{
square_from = BitUtility.GetLS1BIndex(pieces);
BitUtility.RemoveLS1B(ref pieces);
moves = GetKnightMoves(square_from) & ~bitboards[sideToMove];
while(moves > 0)
{
square_to = BitUtility.GetLS1BIndex(moves);
BitUtility.RemoveLS1B(ref moves);
flag = BitUtility.ContainsBit(bitboards[sideToMove ^ 1], square_to) ? MoveFlag.Capture : MoveFlag.Quiet;
if (flag == MoveFlag.Quiet && !_GenerateQuiets) continue;
moveslist[++moveIndex] = MoveUtility.Encode_move(square_from, square_to, flag);
}
}
My bitboard representation is an array of 8 bitboards:
index 0 = blakck bitboard
index 1 = white bitboard
index 2 = all pawns bitboard
index 3 = all knights bitboards
and so on...
so to get just the black pawns you have to do (bitboards[pawn] & bitboards[black]) and it will give you the correct bitboards.
I hope my information helps a little. Good luck with your engine and have fun!