I'm not sure what you mean by special code. It is just common in in that it looks for occupied between squares and certain attacked squares. The algorithm for doing that I kind of feel is special. First I have two king types WK and WKC. A WK on the board does not consider castleing at any time. A WKC on the board considers castleing only if there is a WRC on h1 or a1.dangi12012 wrote: ↑Sat Nov 05, 2022 10:48 amDo you need special code for castling? - the only move where the position is legal before and after, but yet the move might be illegal?Mike Sherwin wrote: ↑Sat Nov 05, 2022 2:39 am Well my generator is pseudo legal and I know no other way than to make the move, call InCheck and then unmake the move for the last ply. If that is stupidthen please explain.
[fen]rn2k1nr/ppp3pp/3p4/4pp1b/8/8/PPPP1PPP/R3K1NR w KQkq - 0 1[/fen]
Code: Select all
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;
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;
}