This has the advantage that you dont ever need to check for "off board moves" and can get almost branchfree because the piecetype 0..11 is also just an index onto the square. So the main lookup is just a int** [64][12] with an extra config that tells the algorithm how to behave.
Move loops can be breaking (rays) or not. And this movegenerator does everything including castling and enpassant. pawn pushes and all the stuff is handled correctly. Pawns can only attack enemies diagonally, Pawns can only move forward in empty squares and can only push 2 squres on first rank etc.
The content or rays is not important here since it already works.
I want to make this code more compact so insights are appreciated: https://godbolt.org/z/bKnnzsb3o
Code: Select all
#define _move(FROM, TO) *movelist++ = ((FROM << 6) | TO)
#define Color(X) (('_' > X) - (X > '_')) //Branchless fen piece to color -1..0..1
extern int** rays[64][12]; //Lookups and rays - ep and castling included
extern char board[64];
extern int piecetable[128]; //FEN char to 0..11 int
extern int ep, castle, halfmove, fullmove;
int movecolor;
const int raycnt[12] = { 3,3,1,1,4,4,4,4,8,8,3,3 };
enum mov { move_slide = 1, square_enemy = 2, square_empty = 4, square_ep = 8, move_cstl = 16 };
extern bool Legal(int kingcolor, int from, int to); //Query into
void GetMoves(int sq, int piece, int*& movelist)
{
//pP nN bB rR qQ kK
int** begin = rays[sq][piece];
int* end = *(begin + raycnt[piece]);
int* ray;
while((ray = *begin++) != end)
{
int* end = ray + (ray[-1] & 0xFF);
int config = (ray[-1] >> 8);
int co = Color(board[sq]);
while (ray != end)
{
int to = *ray++;
char tpiece = board[to];
int ce = Color(tpiece);
if ((config & square_empty) && ce == 0) _move(sq, to);
else if ((config & square_enemy) && ce != co) _move(sq, to);
else if ((config & square_ep) && ep == to) _move(sq, to);
else if ((config & move_cstl) && Legal(co, sq, to)) _move(sq, to);
else if (config & move_slide) break;
}
}
}
int main(){
static int moves[256];
int* movelist = moves;
for (int i = 0; i < 64; i++)
{
char piece = board[i]; int color = Color(piece);
if (color == 0 || color == movecolor) continue;
GetMoves(i, piecetable[piece], movelist);
}
}


