add pawn movegen (untested)

This commit is contained in:
2024-02-26 19:15:42 +01:00
parent ca4e274957
commit f1a081a7b6
4 changed files with 136 additions and 37 deletions

View File

@@ -36,13 +36,13 @@
/* move flags */ /* move flags */
#define M_FLAGS_BEG 18 #define M_FLAGS_BEG 18
#define M_HAS_FLAGS mask(_M_FLAGS_BEG + 0) /* probably unused */ #define M_HAS_FLAGS mask(M_FLAGS_BEG + 0) /* probably unused */
#define M_CAPTURE mask(_M_FLAGS_BEG + 1) #define M_CAPTURE mask(M_FLAGS_BEG + 1)
#define M_ENPASSANT mask(_M_FLAGS_BEG + 2) #define M_ENPASSANT mask(M_FLAGS_BEG + 2)
#define M_PROMOTION mask(_M_FLAGS_BEG + 3) #define M_PROMOTION mask(M_FLAGS_BEG + 3)
#define M_CASTLE_K mask(_M_FLAGS_BEG + 4) #define M_CASTLE_K mask(M_FLAGS_BEG + 4)
#define M_CASTLE_Q mask(_M_FLAGS_BEG + 5) #define M_CASTLE_Q mask(M_FLAGS_BEG + 5)
#define M_CHECK mask(_M_FLAGS_BEG + 6) /* probably unknown/useless */ #define M_CHECK mask(M_FLAGS_BEG + 6) /* probably unknown/useless */
#define M_FLAGS (M_CAPTURE | M_ENPASSANT | M_PROMOTION | \ #define M_FLAGS (M_CAPTURE | M_ENPASSANT | M_PROMOTION | \
M_CASTLE_K | M_CASTLE_Q | M_CHECK) M_CASTLE_K | M_CASTLE_Q | M_CHECK)
@@ -55,6 +55,11 @@ static inline move_t move_make(square_t from, square_t to)
return (to << 3) | from; return (to << 3) | from;
} }
static inline move_t move_make_promote(square_t from, square_t to, piece_type_t piece)
{
return move_make(from, to) | M_ENPASSANT | (piece << 15);
}
static inline move_t move_from(move_t move) static inline move_t move_from(move_t move)
{ {
return move & 56; return move & 56;

View File

@@ -18,9 +18,16 @@
#include "piece.h" #include "piece.h"
#include "move.h" #include "move.h"
//void add_pseudo_move(move_t *pmove, square_t from, square_t to) /**
* gen_pawn_push() - generate pawn push
* @pos: position
*
* Generate all pseudo pawn pushes.
*/
//int gen_pawn_push(pos_t *pos, bitboard_t occ)
//{ //{
// pmov
//} //}
/** /**
@@ -32,29 +39,32 @@
*/ */
int gen_all_pseudomoves(pos_t *pos) int gen_all_pseudomoves(pos_t *pos)
{ {
int me = pos->turn, other = OPPONENT(me); color_t me = pos->turn, enemy = OPPONENT(me);
bitboard_t my_pieces = pos->bb[me][ALL_PIECES], notmine = ~my_pieces, bitboard_t my_pieces = pos->bb[me][ALL_PIECES], not_my_pieces = ~my_pieces,
other_pieces = pos->bb[other][ALL_PIECES], enemy_pieces = pos->bb[enemy][ALL_PIECES];
occ = my_pieces | other_pieces, movebits; bitboard_t occ = my_pieces | enemy_pieces, empty = ~occ;
bitboard_t movebits, from_pawns;
int tmp1, tmp2, from, to; int tmp1, tmp2, from, to;
movelist_t moves = pos->moves; movelist_t moves = pos->moves;
/* sliding pieces */ /* sliding pieces */
bit_for_each64(from, tmp1, pos->bb[me][BISHOP]) { bit_for_each64(from, tmp1, pos->bb[me][BISHOP]) {
movebits = hyperbola_bishop_moves(occ, from) & notmine; movebits = hyperbola_bishop_moves(occ, from) & not_my_pieces;
bit_for_each64(to, tmp2, movebits) { bit_for_each64(to, tmp2, movebits) {
moves.move[moves.nmoves++] = move_make(from, to); moves.move[moves.nmoves++] = move_make(from, to);
} }
} }
bit_for_each64(from, tmp1, pos->bb[me][ROOK]) { bit_for_each64(from, tmp1, pos->bb[me][ROOK]) {
movebits = hyperbola_rook_moves(occ, from) & notmine; movebits = hyperbola_rook_moves(occ, from) & not_my_pieces;
bit_for_each64(to, tmp2, movebits) { bit_for_each64(to, tmp2, movebits) {
moves.move[moves.nmoves++] = move_make(from, to); moves.move[moves.nmoves++] = move_make(from, to);
} }
} }
/* TODO: remove this one */
bit_for_each64(from, tmp1, pos->bb[me][QUEEN]) { bit_for_each64(from, tmp1, pos->bb[me][QUEEN]) {
movebits = hyperbola_queen_moves(occ, from) & notmine; movebits = hyperbola_queen_moves(occ, from) & not_my_pieces;
bit_for_each64(to, tmp2, movebits) { bit_for_each64(to, tmp2, movebits) {
moves.move[moves.nmoves++] = move_make(from, to); moves.move[moves.nmoves++] = move_make(from, to);
} }
@@ -62,24 +72,93 @@ int gen_all_pseudomoves(pos_t *pos)
/* knight */ /* knight */
bit_for_each64(from, tmp1, pos->bb[me][KNIGHT]) { bit_for_each64(from, tmp1, pos->bb[me][KNIGHT]) {
movebits = bb_knight_moves(occ, from) & notmine; movebits = bb_knight_moves(occ, from) & not_my_pieces;
bit_for_each64(to, tmp2, movebits) { bit_for_each64(to, tmp2, movebits) {
moves.move[moves.nmoves++] = move_make(from, to); moves.move[moves.nmoves++] = move_make(from, to);
} }
} }
/* king */ /* king */
movebits = bb_king_moves(occ, pos->king[me]) & notmine; movebits = bb_king_moves(occ, pos->king[me]) & not_my_pieces;
bit_for_each64(to, tmp2, movebits) { bit_for_each64(to, tmp2, movebits) {
moves.move[moves.nmoves++] = move_make(from, to); moves.move[moves.nmoves++] = move_make(from, to);
} }
/* TODO /* pawn: relative rank and files */
* pawn ranks 2-6 advance (1 push, + 2 squares for rank 2) bitboard_t rel_rank7 = (me == WHITE ? RANK_7bb : RANK_2bb);
* pawns ranks 2-6 capture bitboard_t rel_rank3 = (me == WHITE ? RANK_3bb : RANK_6bb);
* pawns rank 7 advance + promotion bitboard_t rel_filea = (me == WHITE ? FILE_Abb : FILE_Hbb);
* pawns rank 7 capture + promotion bitboard_t rel_fileh = (me == WHITE ? FILE_Hbb : FILE_Abb);
* pawns en-passant int en_passant = pos->en_passant == SQUARE_NONE? 0: pos->en_passant;
* castle bitboard_t enemy_avail = bb_sq[en_passant] | enemy_pieces;
*/
/* pawn: ranks 2-6 push 1 and 2 squares */
movebits = pawn_push(pos->bb[me][PAWN] & ~rel_rank7, me) & empty;
bit_for_each64(to, tmp1, movebits) {
from = pawn_push(to, enemy); /* reverse push */
moves.move[moves.nmoves++] = move_make(from, to);
}
movebits = pawn_push(movebits & rel_rank3, me) & empty;
bit_for_each64(to, tmp1, movebits) {
from = pawn_push(pawn_push(to, enemy), enemy);
moves.move[moves.nmoves++] = move_make(from, to);
}
/* pawn: rank 7 push */
movebits = pawn_push(pos->bb[me][PAWN] & rel_rank7, me) & empty;
bit_for_each64(to, tmp1, movebits) {
from = pawn_push(to, enemy); /* reverse push */
moves.move[moves.nmoves++] = move_make_promote(from, to, QUEEN);
moves.move[moves.nmoves++] = move_make_promote(from, to, ROOK);
moves.move[moves.nmoves++] = move_make_promote(from, to, BISHOP);
moves.move[moves.nmoves++] = move_make_promote(from, to, KNIGHT);
}
/* pawn: ranks 2-6 captures left, including en-passant */
from_pawns = pos->bb[me][PAWN] & ~rel_rank7 & ~rel_filea;
movebits = pawn_take_left(from_pawns, me) & enemy_avail;
bit_for_each64(to, tmp1, movebits) {
from = pawn_take_left(to, enemy); /* reverse capture */
moves.move[moves.nmoves++] = move_make(from, to);
}
/* pawn: rank 7 captures left */
from_pawns = pos->bb[me][PAWN] & rel_rank7 & ~rel_filea;
movebits = pawn_take_left(from_pawns, me) & enemy_avail;
bit_for_each64(to, tmp1, movebits) {
from = pawn_take_left(to, enemy); /* reverse capture */
moves.move[moves.nmoves++] = move_make_promote(from, to, QUEEN);
moves.move[moves.nmoves++] = move_make_promote(from, to, ROOK);
moves.move[moves.nmoves++] = move_make_promote(from, to, BISHOP);
moves.move[moves.nmoves++] = move_make_promote(from, to, KNIGHT);
}
/* pawn: ranks 2-6 captures right, including en-passant */
from_pawns = pos->bb[me][PAWN] & ~rel_rank7 & ~rel_fileh;
movebits = pawn_take_right(from_pawns, me) & enemy_avail;
bit_for_each64(to, tmp1, movebits) {
from = pawn_take_right(to, enemy);
moves.move[moves.nmoves++] = move_make(from, to);
}
/* pawn: rank 7 captures right */
from_pawns = pos->bb[me][PAWN] & rel_rank7 & ~rel_fileh;
movebits = pawn_take_right(from_pawns, me) & enemy_pieces;
bit_for_each64(to, tmp1, movebits) {
from = pawn_take_right(to, enemy); /* reverse capture */
moves.move[moves.nmoves++] = move_make_promote(from, to, QUEEN);
moves.move[moves.nmoves++] = move_make_promote(from, to, ROOK);
moves.move[moves.nmoves++] = move_make_promote(from, to, BISHOP);
moves.move[moves.nmoves++] = move_make_promote(from, to, KNIGHT);
}
/* TODO
* DONE. pawn ranks 2-6 advance (1 push, + 2 squares for rank 2)
* DONE. pawns rank 7 advance + promotions
* DONE. pawns ranks 2-6 captures, left and right
* DONE. pawns en-passant (with capture)
* DONE. pawns rank 7 capture + promotion
* castle
*
* add function per piece, and type, for easier debug
*
*/
return moves.nmoves;
} }

View File

@@ -4,10 +4,11 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "../src/position.h" #include "bug.h"
#include "../src/piece.h" #include "position.h"
#include "../src/bitboard.h" #include "piece.h"
#include "../src/hyperbola-quintessence.h" #include "bitboard.h"
#include "hyperbola-quintessence.h"
int main(int __unused ac, __unused char**av) int main(int __unused ac, __unused char**av)
{ {
@@ -21,11 +22,25 @@ int main(int __unused ac, __unused char**av)
); );
bitboard_print_multi(str, 7, bitboard_print_multi(str, 7,
bb_file[i] | bb_rank[i] | bb_file[i] | bb_rank[i] |
bb_diagonal[i] | bb_antidiagonal[i], bb_diag[i] | bb_anti[i],
bb_diagonal[i], bb_antidiagonal[i], bb_diag[i], bb_anti[i],
bb_file[i], bb_rank[i], bb_file[i], bb_rank[i],
bb_knight[i], bb_king[i]); bb_knight[i], bb_king[i]);
} }
bitboard_print_multi("a1-a8 a1-h8 a1-h1 a2-a7 a2-g7 a2-g2", 6,
bb_between[A1][A8], bb_between[A1][H8],
bb_between[A1][H1], bb_between[A2][A7],
bb_between[A2][G7], bb_between[A2][G2]);
bitboard_print_multi("c3-c6 c3-f6 c3-f3 c3-e1 c3-c1 c3-a1 c3-a3 c3-a5", 8,
bb_between[C3][C6], bb_between[C3][F6],
bb_between[C3][F3], bb_between[C3][E1],
bb_between[C3][C1], bb_between[C3][A1],
bb_between[C3][A3], bb_between[C3][A5]);
bitboard_print_multi("c4-c6 c4-f6 c4-f3 c4-e1 c4-c1 c4-a1 c4-a3 c4-a5", 8,
bb_between[C4][C6], bb_between[C4][F6],
bb_between[C4][F3], bb_between[C4][E1],
bb_between[C4][C1], bb_between[C4][A1],
bb_between[C4][A3], bb_between[C4][A5]);
/* /*
* for (square_t sq = 0; sq < 64; ++sq) { * for (square_t sq = 0; sq < 64; ++sq) {
* sprintf(str, "%2d %#lx %#lx knight", sq, bb_sq[sq], bb_knight[sq]); * sprintf(str, "%2d %#lx %#lx knight", sq, bb_sq[sq], bb_knight[sq]);

View File

@@ -1,10 +1,11 @@
#include "debug.h" //#include <stdio.h>
#include "pool.h"
#include "../src/chessdefs.h" #include "bug.h"
#include "../src/bitboard.h"
#include "../src/position.h" #include "chessdefs.h"
#include "../src/fen.h" #include "bitboard.h"
#include "position.h"
#include "fen.h"
int main(int ac, char**av) int main(int ac, char**av)
{ {
@@ -13,7 +14,6 @@ int main(int ac, char**av)
const char *fen; const char *fen;
char revfen[128]; char revfen[128];
int comp; int comp;
//debug_init(5, stderr, true); //debug_init(5, stderr, true);
//pos_pool_init(); //pos_pool_init();
bitboard_init(); bitboard_init();