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 */
#define M_FLAGS_BEG 18
#define M_HAS_FLAGS mask(_M_FLAGS_BEG + 0) /* probably unused */
#define M_CAPTURE mask(_M_FLAGS_BEG + 1)
#define M_ENPASSANT mask(_M_FLAGS_BEG + 2)
#define M_PROMOTION mask(_M_FLAGS_BEG + 3)
#define M_CASTLE_K mask(_M_FLAGS_BEG + 4)
#define M_CASTLE_Q mask(_M_FLAGS_BEG + 5)
#define M_CHECK mask(_M_FLAGS_BEG + 6) /* probably unknown/useless */
#define M_HAS_FLAGS mask(M_FLAGS_BEG + 0) /* probably unused */
#define M_CAPTURE mask(M_FLAGS_BEG + 1)
#define M_ENPASSANT mask(M_FLAGS_BEG + 2)
#define M_PROMOTION mask(M_FLAGS_BEG + 3)
#define M_CASTLE_K mask(M_FLAGS_BEG + 4)
#define M_CASTLE_Q mask(M_FLAGS_BEG + 5)
#define M_CHECK mask(M_FLAGS_BEG + 6) /* probably unknown/useless */
#define M_FLAGS (M_CAPTURE | M_ENPASSANT | M_PROMOTION | \
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;
}
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)
{
return move & 56;

View File

@@ -18,9 +18,16 @@
#include "piece.h"
#include "move.h"
//void add_pseudo_move(move_t *pmove, square_t from, square_t to)
//{
// pmov
/**
* gen_pawn_push() - generate pawn push
* @pos: position
*
* Generate all pseudo pawn pushes.
*/
//int gen_pawn_push(pos_t *pos, bitboard_t occ)
//{
//}
/**
@@ -32,29 +39,32 @@
*/
int gen_all_pseudomoves(pos_t *pos)
{
int me = pos->turn, other = OPPONENT(me);
bitboard_t my_pieces = pos->bb[me][ALL_PIECES], notmine = ~my_pieces,
other_pieces = pos->bb[other][ALL_PIECES],
occ = my_pieces | other_pieces, movebits;
color_t me = pos->turn, enemy = OPPONENT(me);
bitboard_t my_pieces = pos->bb[me][ALL_PIECES], not_my_pieces = ~my_pieces,
enemy_pieces = pos->bb[enemy][ALL_PIECES];
bitboard_t occ = my_pieces | enemy_pieces, empty = ~occ;
bitboard_t movebits, from_pawns;
int tmp1, tmp2, from, to;
movelist_t moves = pos->moves;
/* sliding pieces */
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) {
moves.move[moves.nmoves++] = move_make(from, to);
}
}
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) {
moves.move[moves.nmoves++] = move_make(from, to);
}
}
/* TODO: remove this one */
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) {
moves.move[moves.nmoves++] = move_make(from, to);
}
@@ -62,24 +72,93 @@ int gen_all_pseudomoves(pos_t *pos)
/* 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) {
moves.move[moves.nmoves++] = move_make(from, to);
}
}
/* 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) {
moves.move[moves.nmoves++] = move_make(from, to);
}
/* pawn: relative rank and files */
bitboard_t rel_rank7 = (me == WHITE ? RANK_7bb : RANK_2bb);
bitboard_t rel_rank3 = (me == WHITE ? RANK_3bb : RANK_6bb);
bitboard_t rel_filea = (me == WHITE ? FILE_Abb : FILE_Hbb);
bitboard_t rel_fileh = (me == WHITE ? FILE_Hbb : FILE_Abb);
int en_passant = pos->en_passant == SQUARE_NONE? 0: pos->en_passant;
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
* pawn ranks 2-6 advance (1 push, + 2 squares for rank 2)
* pawns ranks 2-6 capture
* pawns rank 7 advance + promotion
* pawns rank 7 capture + promotion
* pawns en-passant
* 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 <string.h>
#include "../src/position.h"
#include "../src/piece.h"
#include "../src/bitboard.h"
#include "../src/hyperbola-quintessence.h"
#include "bug.h"
#include "position.h"
#include "piece.h"
#include "bitboard.h"
#include "hyperbola-quintessence.h"
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,
bb_file[i] | bb_rank[i] |
bb_diagonal[i] | bb_antidiagonal[i],
bb_diagonal[i], bb_antidiagonal[i],
bb_diag[i] | bb_anti[i],
bb_diag[i], bb_anti[i],
bb_file[i], bb_rank[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) {
* sprintf(str, "%2d %#lx %#lx knight", sq, bb_sq[sq], bb_knight[sq]);

View File

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