What would be the best way to generate passed pawn moves? Take note that it must not be a tactical move, that means it shouldn't include captures, promotions and checks. Here is my first try, though I have not tested it yet.
Code: Select all
/* returns a bitboard with all bits above b filled up (including b) */
uint64 fillUp2(uint64 b) {
b |= b << 8;
b |= b << 16;
return (b | (b << 32));
}
/* returns a bitboard with all bits below b filled down (including b) */
uint64 fillDown2(uint64 b) {
b |= b >> 8;
b |= b >> 16;
return (b | (b >> 32));
}
// shift the parameter b with i places to the left
uint64 shiftLeft(uint64 b, uint32 i) {return (b << i);}
// shift the parameter b with i places to the right
uint64 shiftRight(uint64 b, uint32 i) {return (b >> i);}
static uint64 (*FillPtr2[])(uint64) = {&fillUp2, &fillDown2};
static uint64 (*ShiftPtr[])(uint64, uint32) = {&shiftLeft, &shiftRight};
/* this generates non tactical non checking passed pawn moves only */
void genPassedPawnMoves(const position_t *pos, sort_t *sort) {
static const int Shift[] = {9, 7};
uint64 pc_bits, mv_bits, pawns, xpawns, mask, dcc;
int from, to;
ASSERT(pos != NULL);
ASSERT(sort != NULL);
sort->size = 0;
pawns = pos->pawns & pos->color[pos->side];
xpawns = pos->pawns & pos->color[pos->side^1];
dcc = discoveredCheckCandidates(pos, pos->side);
mask = (~Rank8ByColorBB[pos->side] & ~((*FillPtr2[pos->side^1])((*ShiftPtr[pos->side^1])(pos->pawns, 8))))
& ~(((*ShiftPtr[pos->side^1])(xpawns, Shift[pos->side^1]) & ~FileABB)
| ((*ShiftPtr[pos->side^1])(xpawns, Shift[pos->side]) & ~FileHBB))
& ~PawnCaps[pos->kpos[pos->side^1]][pos->side^1];
mv_bits = (*ShiftPtr[pos->side])(pawns, 8) & mask;
while (mv_bits) {
to = popFirstBit(&mv_bits);
pc_bits = (PawnMoves[to][pos->side^1] & pawns) & ~dcc;
while (pc_bits) {
from = popFirstBit(&pc_bits);
sort->list[sort->size++].m = GenOneForward(from, to);
}
}
mv_bits = (*ShiftPtr[pos->side])(pawns, 16) & Rank4ByColorBB[pos->side] & mask
& ((*ShiftPtr[pos->side])(~pos->occupied, 8) & (*ShiftPtr[pos->side])(~pos->occupied, 16));
while (mv_bits) {
to = popFirstBit(&mv_bits);
pc_bits = pawns & Rank2ByColorBB[pos->side] & ~dcc;
while (pc_bits) {
from = popFirstBit(&pc_bits);
sort->list[sort->size++].m = GenTwoForward(from, to);
}
}
}
P.S. A1 = 0, H8 = 63, WHITE = 0, BLACK = 1
P.S.2 I'm using the sides color as index to Shift pointer as LEFT = 0 and RIGHT = 1 as they directly corresponds to WHITE and BLACK