return index;
}
void CBoard_move_generate(CBoard_T self) {
Square source, target;
U64 bitboard, attack;
MoveList_T CBoard_move_generate(CBoard_T self, eColor color) {
MoveList_T moves;
Move move;
Square source, target;
U64 bitboard, attack;
U64 occupancy = self->colorBB[WHITE] | self->colorBB[BLACK];
U64 occupancy = self->colorBB[WHITE] | self->colorBB[BLACK];
for (int color = 0; color < 2; color++) {
// Generate quiet pawn moves
{
Piece_T Piece = &Pieces[color][PAWN];
bitboard = self->pieceBB[PAWN] & self->colorBB[color];
while (bitboard) {
// push
{
int add = (color == WHITE) ? +8 : -8;
target = source = bit_lsb_index(bitboard);
target += add;
if (target > a1 && target < h8 && !bit_get(occupancy, target)) {
// promote
if ((color == WHITE && source >= a7 && source <= h7) ||
(color == BLACK && source >= a2 && source <= h2)) {
// add move to move list
printf("PROMOTION!!! ");
} else {
// one ahead
// add move to move list
printf("SINGLE PUSH!!! ");
// two ahead
if (((color == BLACK && source >= a7 && source <= h7) ||
(color == WHITE && source >= a2 && source <= h2)) &&
!bit_get(occupancy, target + add)) {
// add to move list;
printf("DOUBLE PUSH!!! ");
}
printf("%s pawn: %s; target: %s\n",
(color == WHITE) ? "white" : "black",
square_to_coordinates[source],
square_to_coordinates[target]);
moves = MoveList_new();
// Generate quiet pawn moves
{
Piece_T Piece = &Pieces[color][PAWN];
int index = Piece_index(Piece);
bitboard = self->pieceBB[PAWN] & self->colorBB[color];
while (bitboard) {
// push
{
int add = (color == WHITE) ? +8 : -8;
target = source = bit_lsb_index(bitboard);
target += add;
if (target > a1 && target < h8 && !bit_get(occupancy, target)) {
// promote
if ((color == WHITE && source >= a7 && source <= h7) ||
(color == BLACK && source >= a2 && source <= h2)) {
for (int i = 1; i < 6; i++) {
move = Move_encode(source, target, index,
Piece_index(&Pieces[color][i]), 0, 0, 0, 0);
MoveList_add(moves, move);
}
}
}
// Capture
{
attack = Piece->attacks(source, occupancy) & self->colorBB[!color];
while (attack) {
target = bit_lsb_index(attack);
bit_pop(attack, target);
if ((color == WHITE && source >= a7 && source <= h7) ||
(color == BLACK && source >= a2 && source <= h2)) {
// add move to move list
printf("Capture PROMOTION!!! ");
} else {
printf("%s pawn: %s; Capture: %s\n",
(color == WHITE) ? "white" : "black",
square_to_coordinates[source],
square_to_coordinates[target]);
} else {
MoveList_add(moves,
Move_encode(source, target, index, 0, 0, 0, 0, 0));
// two ahead
target += add;
if (((color == BLACK && source >= a7 && source <= h7) ||
(color == WHITE && source >= a2 && source <= h2)) &&
!bit_get(occupancy, target)) {
MoveList_add(moves,
Move_encode(source, target, index, 0, 0, 1, 0, 0));
}
}
}
// enpassant
{
if (self->enpassant != no_sq) {
attack =
Piece->attacks(source, occupancy) & (C64(1) << self->enpassant);
if (attack) {
target = bit_lsb_index(attack);
printf("%s enpassand %s\n", square_to_coordinates[source],
square_to_coordinates[target]);
}
// Capture
{
attack = Piece->attacks(source, occupancy) & self->colorBB[!color];
while (attack) {
target = bit_lsb_index(attack);
bit_pop(attack, target);
if ((color == WHITE && source >= a7 && source <= h7) ||
(color == BLACK && source >= a2 && source <= h2)) {
for (int i = 1; i < 6; i++) {
move = Move_encode(source, target, index,
Piece_index(&Pieces[color][i]), 1, 0, 0, 0);
MoveList_add(moves, move);
}
} else {
MoveList_add(moves,
Move_encode(source, target, index, 0, 1, 0, 0, 0));
}
}
bit_pop(bitboard, source);
}
for (int piece = 1; piece < 6; piece++) {
bitboard = self->pieceBB[piece] & self->colorBB[color];
Piece_T Piece = &Pieces[color][piece];
while (bitboard) {
source = bit_lsb_index(bitboard);
bit_pop(bitboard, source);
attack = Piece->attacks(source, occupancy) & ~self->colorBB[color];
while (attack) {
// enpassant
{
if (self->enpassant != no_sq) {
attack =
Piece->attacks(source, occupancy) & (C64(1) << self->enpassant);
if (attack) {
target = bit_lsb_index(attack);
if (bit_get(self->colorBB[!color], target))
printf("%s from %s capture to %s\n", Piece->unicode,
square_to_coordinates[source],
square_to_coordinates[target]);
else
printf("%s from %s move %s\n", Piece->unicode,
square_to_coordinates[source],
square_to_coordinates[target]);
bit_pop(attack, target);
MoveList_add(moves,
Move_encode(source, target, index, 0, 1, 0, 1, 0));
}
}
}
bit_pop(bitboard, source);
}
for (int piece = 1; piece <= 6; piece++) {
bitboard = self->pieceBB[piece] & self->colorBB[color];
Piece_T Piece = &Pieces[color][piece];
int index = Piece_index(Piece);
while (bitboard) {
source = bit_lsb_index(bitboard);
bit_pop(bitboard, source);
attack = Piece->attacks(source, occupancy) & ~self->colorBB[color];
while (attack) {
target = bit_lsb_index(attack);
if (bit_get(self->colorBB[!color], target))
MoveList_add(moves,
Move_encode(source, target, index, 0, 1, 0, 0, 0));
else
MoveList_add(moves,
Move_encode(source, target, index, 0, 0, 0, 0, 0));
bit_pop(attack, target);
}
}
}
}
// Castling
{
if (!CBoard_square_isAttack(self, e1, BLACK)) {
int index = Piece_index(&Pieces[WHITE][KING]);
if (self->castle & WK && !bit_get(occupancy, f1) &&
!bit_get(occupancy, g1)) {
printf("CASTLE WHITE KING SIDE\n");
MoveList_add(moves, Move_encode(e8, g8, index, 0, 0, 0, 0, 1));
}
if (self->castle & WQ && !bit_get(occupancy, b1) &&
!bit_get(occupancy, c1) && !bit_get(occupancy, d1)) {
printf("CASTLE WHITE QUEEN SIDE\n");
MoveList_add(moves, Move_encode(e8, c8, index, 0, 0, 0, 0, 1));
}
}
if (!CBoard_square_isAttack(self, e1, WHITE)) {
int index = Piece_index(&Pieces[BLACK][KING]);
if (self->castle & BK && !bit_get(occupancy, f8) &&
!bit_get(occupancy, g8)) {
printf("CASTLE BLACK KING SIDE\n");
MoveList_add(moves, Move_encode(e8, g8, index, 0, 0, 0, 0, 1));
}
if (self->castle & BQ && !bit_get(occupancy, b8) &&
!bit_get(occupancy, c8) && !bit_get(occupancy, d8)) {
printf("CASTLE BLACK QUEEN SIDE\n");
MoveList_add(moves, Move_encode(e8, c8, index, 0, 0, 0, 0, 1));
}
}
}
return moves;
}
void CBoard_print(CBoard_T self) {