8 Commits

16 changed files with 300 additions and 263 deletions

View File

@@ -1,3 +1,3 @@
((nil . ((compile-command . (concat "make -C " ((nil . ((compile-command . (concat "make -C "
(vc-root-dir) (vc-root-dir)
" -k -j2"))))) " -k -j2 testing")))))

View File

@@ -64,10 +64,12 @@ CPPFLAGS += -DWARN_ON # brlib bug.h
#CPPFLAGS += -DDEBUG_DEBUG # enable log() functions #CPPFLAGS += -DDEBUG_DEBUG # enable log() functions
#CPPFLAGS += -DDEBUG_DEBUG_C # enable log() settings #CPPFLAGS += -DDEBUG_DEBUG_C # enable log() settings
#CPPFLAGS += -DDEBUG_POOL # memory pools management #CPPFLAGS += -DDEBUG_POOL # memory pools management
#CPPFLAGS += -DDEBUG_FEN # FEN decoding
#CPPFLAGS += -DDEBUG_POS # position.c #CPPFLAGS += -DDEBUG_POS # position.c
#CPPFLAGS += -DDEBUG_MOVE # move generation #CPPFLAGS += -DDEBUG_MOVE # move generation
# fen.c
#CPPFLAGS += -DDEBUG_FEN # FEN decoding
# attack.c # attack.c
#CPPFLAGS += -DDEBUG_ATTACK_ATTACKERS1 # sq_attackers details #CPPFLAGS += -DDEBUG_ATTACK_ATTACKERS1 # sq_attackers details
CPPFLAGS += -DDEBUG_ATTACK_ATTACKERS # sq_attackers CPPFLAGS += -DDEBUG_ATTACK_ATTACKERS # sq_attackers
@@ -284,8 +286,9 @@ memcheck: targets
##################################### test binaries ##################################### test binaries
.PHONY: testing test .PHONY: testing test
TEST := fen-test bitboard-test movegen-test attack-test TEST :=piece-test fen-test bitboard-test movegen-test attack-test
PIECE_OBJS := piece.o
FEN_OBJS := fen.o position.o piece.o bitboard.o board.o hyperbola-quintessence.o \ FEN_OBJS := fen.o position.o piece.o bitboard.o board.o hyperbola-quintessence.o \
attack.o attack.o
BB_OBJS := fen.o position.o piece.o bitboard.o board.o hyperbola-quintessence.o \ BB_OBJS := fen.o position.o piece.o bitboard.o board.o hyperbola-quintessence.o \
@@ -297,6 +300,7 @@ ATTACK_OBJS := fen.o position.o piece.o bitboard.o board.o hyperbola-quintesse
TEST := $(addprefix $(BINDIR)/,$(TEST)) TEST := $(addprefix $(BINDIR)/,$(TEST))
PIECE_OBJS := $(addprefix $(OBJDIR)/,$(PIECE_OBJS))
FEN_OBJS := $(addprefix $(OBJDIR)/,$(FEN_OBJS)) FEN_OBJS := $(addprefix $(OBJDIR)/,$(FEN_OBJS))
BB_OBJS := $(addprefix $(OBJDIR)/,$(BB_OBJS)) BB_OBJS := $(addprefix $(OBJDIR)/,$(BB_OBJS))
MOVEGEN_OBJS := $(addprefix $(OBJDIR)/,$(MOVEGEN_OBJS)) MOVEGEN_OBJS := $(addprefix $(OBJDIR)/,$(MOVEGEN_OBJS))
@@ -308,6 +312,10 @@ test:
testing: $(TEST) testing: $(TEST)
bin/piece-test: test/piece-test.c $(FEN_OBJS)
@echo compiling $@ test executable.
@$(CC) $(ALL_CFLAGS) $< $(FEN_OBJS) $(ALL_LDFLAGS) -o $@
bin/fen-test: test/fen-test.c test/common-test.h $(FEN_OBJS) bin/fen-test: test/fen-test.c test/common-test.h $(FEN_OBJS)
@echo compiling $@ test executable. @echo compiling $@ test executable.
@$(CC) $(ALL_CFLAGS) $< $(FEN_OBJS) $(ALL_LDFLAGS) -o $@ @$(CC) $(ALL_CFLAGS) $< $(FEN_OBJS) $(ALL_LDFLAGS) -o $@

View File

@@ -26,6 +26,7 @@
/** /**
* sq_attackers() - find attackers on a square * sq_attackers() - find attackers on a square
* @pos: position * @pos: position
* @occ: occupation mask used
* @sq: square to test * @sq: square to test
* @c: attacker color * @c: attacker color
* *
@@ -39,11 +40,11 @@
* *
* @Return: a bitboard of attackers. * @Return: a bitboard of attackers.
*/ */
bitboard_t sq_attackers(const pos_t *pos, const square_t sq, const color_t c) bitboard_t sq_attackers(const pos_t *pos, const bitboard_t occ, const square_t sq, const color_t c)
{ {
bitboard_t attackers = 0, tmp; bitboard_t attackers = 0, tmp;
bitboard_t sqbb = mask(sq); bitboard_t sqbb = mask(sq);
bitboard_t occ = pos_occ(pos); //bitboard_t occ = pos_occ(pos);
bitboard_t to; bitboard_t to;
color_t opp = OPPONENT(c); color_t opp = OPPONENT(c);
@@ -151,5 +152,6 @@ bitboard_t sq_pinners(const pos_t *pos, const square_t sq, const color_t color)
*/ */
bitboard_t sq_attackers_all(const pos_t *pos, const square_t sq) bitboard_t sq_attackers_all(const pos_t *pos, const square_t sq)
{ {
return sq_attackers(pos, sq, WHITE) | sq_attackers(pos, sq, BLACK); bitboard_t occ = pos_occ(pos);
return sq_attackers(pos, occ, sq, WHITE) | sq_attackers(pos, occ, sq, BLACK);
} }

View File

@@ -17,7 +17,7 @@
#include "chessdefs.h" #include "chessdefs.h"
#include "bitboard.h" #include "bitboard.h"
extern bitboard_t sq_attackers(const pos_t *pos, const square_t sq, const color_t c); bitboard_t sq_attackers(const pos_t *pos, const bitboard_t occ, const square_t sq, const color_t c);
extern bitboard_t sq_attackers_all(const pos_t *pos, const square_t sq); bitboard_t sq_attackers_all(const pos_t *pos, const square_t sq);
extern bitboard_t sq_pinners(const pos_t *pos, const square_t sq, const color_t c); bitboard_t sq_pinners(const pos_t *pos, const square_t sq, const color_t c);
#endif #endif

View File

@@ -65,9 +65,9 @@ void board_print(const piece_t *board)
for (int file = 0; file < 8; ++file) { for (int file = 0; file < 8; ++file) {
piece_t pc = board[sq_make(file, rank)]; piece_t pc = board[sq_make(file, rank)];
# ifdef DIAGRAM_SYM # ifdef DIAGRAM_SYM
printf(" %s |", pc? piece_to_sym_color(pc): " "); printf(" %s |", pc? piece_to_sym(pc): " ");
# else # else
printf(" %s |", pc? piece_to_sym_color(pc): " "); printf(" %s |", pc? piece_to_fen(pc): " ");
# endif # endif
} }
printf("\n +---+---+---+---+---+---+---+---+\n"); printf("\n +---+---+---+---+---+---+---+---+\n");
@@ -96,7 +96,7 @@ void board_print_mask(const piece_t *board, const bitboard_t mask)
bitboard_t set = mask(sq) & mask; bitboard_t set = mask(sq) & mask;
printf("%s", set? REVERSE : " "); printf("%s", set? REVERSE : " ");
# ifdef DIAGRAM_SYM # ifdef DIAGRAM_SYM
printf("%s", pc? piece_to_sym_color(pc): " "); printf("%s", pc? piece_to_sym(pc): " ");
# else # else
printf("%s", pc? piece_to_char_color(pc): " "); printf("%s", pc? piece_to_char_color(pc): " ");
# endif # endif
@@ -118,7 +118,7 @@ void board_print_raw(const piece_t *board, const int type)
for (file_t f = FILE_A; f <= FILE_H; ++f) { for (file_t f = FILE_A; f <= FILE_H; ++f) {
piece_t p = board[sq_make(f, r)]; piece_t p = board[sq_make(f, r)];
if (type) { if (type) {
printf("%s ", p == EMPTY? ".": piece_to_char_color(p)); printf("%s ", p == EMPTY? ".": piece_to_char(p));
} else { } else {
printf("%02o ", p); printf("%02o ", p);
} }

View File

@@ -184,9 +184,9 @@ pos_t *fen2pos(pos_t *pos, const char *fen)
file += *cur - '0'; file += *cur - '0';
continue; continue;
} }
if ((piece = char_color_to_piece(*cur)) != EMPTY) { if ((piece = piece_from_fen(*cur)) != EMPTY) {
# ifdef DEBUG_FEN # ifdef DEBUG_FEN
log_i(5, "f=%d r=%d *p=%c piece=%#04x t=%d c=%d\n", file, rank, *cur, printf("f=%d r=%d *p=%c piece=%#04x t=%d c=%d\n", file, rank, *cur,
piece, PIECE(piece), COLOR(piece)); piece, PIECE(piece), COLOR(piece));
# endif # endif
pos_set_sq(&tmppos, sq_make(file, rank), piece); pos_set_sq(&tmppos, sq_make(file, rank), piece);
@@ -296,13 +296,23 @@ char *pos2fen(const pos_t *pos, char *fen)
for (file_t f = FILE_A; f <= FILE_H;) { for (file_t f = FILE_A; f <= FILE_H;) {
square_t sq = sq_make(f, r); square_t sq = sq_make(f, r);
piece_t piece = pos->board[sq]; piece_t piece = pos->board[sq];
if (pos->board[sq] == EMPTY) { # ifdef DEBUG_FEN
printf("r=%d f=%d p=%d pos=%d\n", r, f, piece, cur);
# endif
if (piece == EMPTY) {
int len = 0; int len = 0;
for (; f <= FILE_H && pos->board[sq_make(f, r)] == EMPTY; f++) for (; f <= FILE_H && pos->board[sq_make(f, r)] == EMPTY; f++)
len++; len++;
# ifdef DEBUG_FEN
printf("empty=%d char=%c\n", len, '0' + len);
# endif
fen[cur++] = '0' + len; fen[cur++] = '0' + len;
} else { } else {
fen[cur++] = *piece_to_char_color(piece); fen[cur++] = *piece_to_fen(piece);
# ifdef DEBUG_FEN
printf("f1=%d r=%d c=%c t=%d c=%d \n", f, r,
*(piece_to_fen(piece)), PIECE(piece), COLOR(piece));
# endif
f++; f++;
} }
} }

View File

@@ -37,43 +37,62 @@
bool pseudo_is_legal(pos_t *pos, move_t move) bool pseudo_is_legal(pos_t *pos, move_t move)
{ {
color_t us = pos->turn, them = OPPONENT(us); color_t us = pos->turn, them = OPPONENT(us);
square_t from = move_from(move), to = move_to(move); square_t from = move_from(move), to = move_to(move), king = pos->king[us], sq;
int piece = PIECE(pos->board[from]), sq; piece_type_t piece = PIECE(pos->board[from]);
bitboard_t tmp; bitboard_t kingbb = pos->bb[us][KING], tmp;
/* (1) - King /* (1) - King
* For castling, we already tested intermediate squares attacks * For castling, we already tested intermediate squares attacks
* in pseudo move generation, so we only care destination square here. * in pseudo move generation, so we only care destination square here.
* Attention: We need to exclude king from occupation bitboard !
*/ */
if (piece == KING) if (piece == KING) {
return !sq_attackers(pos, to, them); bitboard_t occ = pos_occ(pos) ^ kingbb;
return !sq_attackers(pos, occ, to, them);
}
/* (2) - pinned pieces /* (2) - King is in check
* Double-check is already handled, as only K moves were generated.
* Here, allowed moves are only on King-attacker line, including
* attacker.We can move a piece on
* in pseudo move generation, so we only care destination square here.
*/
if (pos->checkers) {
if (popcount64(pos->checkers) == 1) { /* one checker */
square_t checker = ctz64(pos->checkers);
bitboard_t between = bb_between[king][checker];
return mask(to) & between;
}
return false; /* double check */
}
/* (3) - pinned pieces
* We verify here that pinned piece P stays on line King-P. * We verify here that pinned piece P stays on line King-P.
*/ */
if (mask(from) & pos->blockers & pos->bb[us][ALL_PIECES]) { if (mask(from) & pos->blockers & pos->bb[us][ALL_PIECES]) {
bitboard_t line = bb_line[from][pos->king[us]]; bitboard_t line = bb_line[from][king];
return line & mask(to); /* to is not on pin line */ return line & mask(to); /* to is not on pin line */
} }
/* (3) - En-passant /* (4) - En-passant
* We only care the situation where our King and enemy R/Q are on * We only care the situation where our King and enemy R/Q are on
* from rank () * 5th relative rank. To do so, we create an occupation bb without
* the 2 pawns.
*/ */
if (move & M_CAPTURE && PIECE(pos->board[to]) == EMPTY) { if (move & M_CAPTURE && PIECE(pos->board[to]) == EMPTY) {
/* from square rank bitboard */ /* from rank bitboard */
bitboard_t rank5 = bb_sqrank[sq_rank(from)]; bitboard_t rank5 = bb_sqrank[from];
/* enemy rooks/queens on from rank */ /* enemy rooks/queens on from rank */
bitboard_t rooks = (pos->bb[them][ROOK] | pos->bb[them][QUEEN]) & rank5; bitboard_t rooks = (pos->bb[them][ROOK] | pos->bb[them][QUEEN]) & rank5;
if ((pos->bb[us][KING] & rank5) && rooks) { /* K and enemy R/Q on rank */ if ((kingbb & rank5) && rooks) { /* K and enemy R/Q on rank */
/* captured pawn square (beside from square) */ /* captured pawn square (beside from square) */
square_t captured = sq_make(sq_file(pos->en_passant), sq_rank(from)); square_t captured = sq_make(sq_file(pos->en_passant), sq_rank(from));
/* occupation bitboard without the two "disappearing" pawns */ /* occupation bitboard without the two "disappearing" pawns */
bitboard_t occ = pos_occ(pos) ^ mask(from) ^ mask(captured); bitboard_t occ = pos_occ(pos) ^ mask(from) ^ mask(captured);
bit_for_each64(sq, tmp, rooks) /* check all rooks/queens */ bit_for_each64(sq, tmp, rooks) /* check all rooks/queens */
if (hyperbola_rank_moves(occ, sq) & pos->bb[us][KING]) if (hyperbola_rank_moves(occ, sq) & kingbb)
return false; return false;
} }
return true; return true;
@@ -246,14 +265,14 @@ int pos_gen_pseudomoves(pos_t *pos)
if (CAN_OO(pos->castle, us)) { if (CAN_OO(pos->castle, us)) {
bitboard_t occmask = rel_rank1 & (FILE_Fbb | FILE_Gbb); bitboard_t occmask = rel_rank1 & (FILE_Fbb | FILE_Gbb);
if (!(occ & occmask) && if (!(occ & occmask) &&
!sq_attackers(pos, from+1, them)) { /* f1/f8 */ !sq_attackers(pos, occ, from+1, them)) { /* f1/f8 */
moves[nmoves++] = move_make_flags(from, from + 2, M_CASTLE_K); moves[nmoves++] = move_make_flags(from, from + 2, M_CASTLE_K);
} }
} }
if (CAN_OOO(pos->castle, us)) { if (CAN_OOO(pos->castle, us)) {
bitboard_t occmask = rel_rank1 & (FILE_Bbb | FILE_Cbb | FILE_Dbb); bitboard_t occmask = rel_rank1 & (FILE_Bbb | FILE_Cbb | FILE_Dbb);
if (!(occ & occmask) && if (!(occ & occmask) &&
!sq_attackers(pos, from-1, them)) { /* d1/d8 */ !sq_attackers(pos, occ, from-1, them)) { /* d1/d8 */
moves[nmoves++] = move_make_flags(from, from - 2, M_CASTLE_Q); moves[nmoves++] = move_make_flags(from, from - 2, M_CASTLE_Q);
} }
} }

View File

@@ -88,6 +88,35 @@
* } * }
*/ */
/**
* move_str() - get a move string
* @dst: destination memory
* @move: move
* @flags: moves selection and display options.
*
* Possible flags are:
* M_PR_CAPT: print move if capture
* M_PR_NCAPT: print move if non capture
* M_PR_NUM: print also move number
* M_PR_LONG: print long notation
* M_PR_NL: print a newline after move
* M_PR_EVAL: print move eval
*/
char *move_str(char *dst, const move_t move, __unused const int flags)
{
square_t from = move_from(move);
square_t to = move_to(move);
int len;
sprintf(dst, "%s-%s%n", sq_to_string(from), sq_to_string(to), &len);
if (move & M_PROMOTION) {
piece_t promoted = move_promoted(move);
sprintf(dst + len, "=%s", piece_to_low(promoted));
}
return dst;
}
/** /**
* moves_print() - print movelist moves. * moves_print() - print movelist moves.
* @moves: &movelist_t moves list * @moves: &movelist_t moves list
@@ -103,12 +132,10 @@
*/ */
void moves_print(movelist_t *moves, __unused int flags) void moves_print(movelist_t *moves, __unused int flags)
{ {
printf("%2d:", moves->nmoves); char str[16];
for (int m = 0; m < moves->nmoves; ++m) { //printf("%2d:", moves->nmoves);
square_t from = move_from(moves->move[m]); for (int m = 0; m < moves->nmoves; ++m)
square_t to = move_to(moves->move[m]); printf("%s ", move_str(str, moves->move[m], flags));
printf(" %s-%s", sq_to_string(from), sq_to_string(to));
}
printf("\n"); printf("\n");
} }
@@ -120,12 +147,16 @@ static int _moves_cmp_bysquare(const void *p1, const void *p2)
square_t t1 = move_to(m1); square_t t1 = move_to(m1);
square_t f2 = move_from(m2); square_t f2 = move_from(m2);
square_t t2 = move_to(m2); square_t t2 = move_to(m2);
piece_t prom1 = move_promoted(m1);
piece_t prom2 = move_promoted(m2);
if (f1 < f2) return -1; if (f1 < f2) return -1;
if (f1 > f2) return 1; if (f1 > f2) return 1;
/* f1 == f2 */ /* f1 == f2 */
if (t1 < t2) return -1; if (t1 < t2) return -1;
if (t1 > t2) return 1; if (t1 > t2) return 1;
/* t1 == t2 */
if (prom1 < prom2) return -1;
if (prom1 > prom2) return 1;
return 0; return 0;
} }

View File

@@ -21,13 +21,13 @@
/* move structure: /* move structure:
* 3 2 2 1 1 1 1 1 1 * 3 2 2 1 1 1 1 1 1
* 1 5 3 8 7 5 4 2 1 6 5 0 * 1 5 3 8 7 5 4 2 1 6 5 0
* UUUUUUUU FFFFFF ppp ccc tttttt ffffff * UUUUUUUU FFFFFF ccc ppp tttttt ffffff
* *
* bits len range type mask get desc * bits len range type mask get desc
* ffffff 6 0-5 square_t 3f &63 from * ffffff 6 0-5 square_t 3f &63 from
* tttttt 6 6-11 square_t fc0 (>>6)&63 to * tttttt 6 6-11 square_t fc0 (>>6)&63 to
* ccc 3 12-14 piece_type_t 7000 (>>12)&7 captured
* ppp 3 15-17 piece_type_t 38000 (>>15)&7 promoted * ppp 3 15-17 piece_type_t 38000 (>>15)&7 promoted
* ccc 3 12-14 piece_type_t 7000 (>>12)&7 captured
* FFFFFF 6 18-23 move_flags_t fc0000 N/A flags * FFFFFF 6 18-23 move_flags_t fc0000 N/A flags
* UUUUUUUU 8 24-31 unused fe000000 N/A future usage ? * UUUUUUUU 8 24-31 unused fe000000 N/A future usage ?
*/ */
@@ -51,25 +51,11 @@ typedef struct __movelist_s {
int curmove; /* current move (use) */ int curmove; /* current move (use) */
} movelist_t; } movelist_t;
/* move flags */
//#define M_FLAGS_BEG 18
//#define M_HAS_FLAGS mask(M_FLAGS_BEG + 0) /* probably useless */
//#define M_CAPTURE mask(M_FLAGS_BEG + 0)
//#define M_EN_PASSANT mask(M_FLAGS_BEG + 1)
//#define M_PROMOTION mask(M_FLAGS_BEG + 2)
//#define M_CASTLE_K mask(M_FLAGS_BEG + 3) /* maybe only one ? */
//#define M_CASTLE_Q mask(M_FLAGS_BEG + 4) /* maybe only one ? */
//#define M_CHECK mask(M_FLAGS_BEG + 5) /* probably unknown/useless */
//#define M_FLAGS (M_CAPTURE | M_ENPASSANT | M_PROMOTION |
// M_CASTLE_K | M_CASTLE_Q | M_CHECK)
//#define M_NORMAL (~M_FLAGS)
static inline square_t move_from(move_t move) static inline square_t move_from(move_t move)
{ {
return move & 077; return move & 077;
} }
static inline square_t move_to(move_t move) static inline square_t move_to(move_t move)
{ {
return (move >> 6) & 077; return (move >> 6) & 077;
@@ -77,12 +63,12 @@ static inline square_t move_to(move_t move)
static inline piece_t move_promoted(move_t move) static inline piece_t move_promoted(move_t move)
{ {
return (move >> 15) & 07; return (move >> 12) & 07;
} }
static inline piece_t move_captured(move_t move) static inline piece_type_t move_captured(move_t move)
{ {
return (move >> 12) & 07; return (move >> 15) & 07;
} }
static inline move_t move_make(square_t from, square_t to) static inline move_t move_make(square_t from, square_t to)
@@ -103,13 +89,13 @@ static inline move_t move_make_capture(square_t from, square_t to)
static inline move_t move_make_promote(square_t from, square_t to, static inline move_t move_make_promote(square_t from, square_t to,
piece_type_t promoted) piece_type_t promoted)
{ {
return move_make_flags(from, to, M_PROMOTION) | (promoted << 15); return move_make_flags(from, to, M_PROMOTION) | (promoted << 12);
} }
static inline move_t move_make_promote_capture(square_t from, square_t to, static inline move_t move_make_promote_capture(square_t from, square_t to,
piece_type_t promoted) piece_type_t promoted)
{ {
return move_make_flags(from, to, M_CAPTURE | M_PROMOTION) | (promoted << 15); return move_make_flags(from, to, M_CAPTURE | M_PROMOTION) | (promoted << 12);
} }
/* moves_print flags /* moves_print flags
@@ -118,6 +104,7 @@ static inline move_t move_make_promote_capture(square_t from, square_t to,
#define M_PR_NCAPT 0x02 #define M_PR_NCAPT 0x02
#define M_PR_NUM 0x04 #define M_PR_NUM 0x04
#define M_PR_NL 0x08 #define M_PR_NL 0x08
#define M_UCI 0x10 /* UCI style - e7e8q */
#define M_PR_EVAL 0x20 /* separate captures */ #define M_PR_EVAL 0x20 /* separate captures */
#define M_PR_SEPARATE 0x40 /* separate captures */ #define M_PR_SEPARATE 0x40 /* separate captures */
#define M_PR_LONG 0x80 #define M_PR_LONG 0x80
@@ -126,9 +113,9 @@ static inline move_t move_make_promote_capture(square_t from, square_t to,
//void moves_pool_stats(); //void moves_pool_stats();
//int move_print(int movenum, move_t *move, move_flags_t flags); //int move_print(int movenum, move_t *move, move_flags_t flags);
char *move_str(char *dst, const move_t move, __unused const int flags);
extern void moves_print(movelist_t *moves, int flags); void moves_print(movelist_t *moves, int flags);
extern void move_sort_by_sq(movelist_t *moves); void move_sort_by_sq(movelist_t *moves);
//extern int pseudo_moves_castle(pos_t *pos, bool color, bool doit, bool do_king); //extern int pseudo_moves_castle(pos_t *pos, bool color, bool doit, bool do_king);
//int pseudo_moves_gen(pos_t *pos, piece_list_t *piece, bool doit, bool do_king); //int pseudo_moves_gen(pos_t *pos, piece_list_t *piece, bool doit, bool do_king);

View File

@@ -25,22 +25,22 @@
* piece_details * piece_details
*/ */
const struct piece_details piece_details[PIECE_MAX] = { const struct piece_details piece_details[PIECE_MAX] = {
/* Abb Fen Sym SymC Name start value */ /* cap low fen sym name values */
[EMPTY] = { "", "", "", "", "", 0, 0, 0 }, [EMPTY] = { "", "", "", "", "", 0, 0, 0 },
[W_PAWN] = { "", "P", "", "", "Pawn", P_VAL_OPN, P_VAL_MID, P_VAL_END }, [W_PAWN] = { "", "", "P", "", "Pawn", P_VAL_OPN, P_VAL_MID, P_VAL_END },
[W_KNIGHT] = { "N", "N", "", "", "Knight", N_VAL_OPN, N_VAL_MID, N_VAL_END }, [W_KNIGHT] = { "N", "n", "N", "", "Knight", N_VAL_OPN, N_VAL_MID, N_VAL_END },
[W_BISHOP] = { "B", "B", "", "", "Bishop", B_VAL_OPN, B_VAL_MID, B_VAL_END }, [W_BISHOP] = { "B", "b", "B", "", "Bishop", B_VAL_OPN, B_VAL_MID, B_VAL_END },
[W_ROOK] = { "R", "R", "", "", "Rook", R_VAL_OPN, R_VAL_MID, R_VAL_END }, [W_ROOK] = { "R", "r", "R", "", "Rook", R_VAL_OPN, R_VAL_MID, R_VAL_END },
[W_QUEEN] = { "Q", "Q", "", "", "Queen", Q_VAL_OPN, Q_VAL_MID, Q_VAL_END }, [W_QUEEN] = { "Q", "q", "Q", "", "Queen", Q_VAL_OPN, Q_VAL_MID, Q_VAL_END },
[W_KING] = { "K", "K", "", "", "King", K_VAL_OPN, K_VAL_MID, K_VAL_END }, [W_KING] = { "K", "k", "K", "", "King", K_VAL_OPN, K_VAL_MID, K_VAL_END },
[7] = { "", "", "", "", "", 0, 0, 0 }, [7] = { "", "", "", "", "", 0, 0, 0 },
[8] = { "", "", "", "", "", 0, 0, 0 }, [8] = { "", "", "", "", "", 0, 0, 0 },
[B_PAWN] = { "", "p", "", "", "Pawn", P_VAL_OPN, P_VAL_MID, P_VAL_END }, [B_PAWN] = { "", "", "p", "", "Pawn", P_VAL_OPN, P_VAL_MID, P_VAL_END },
[B_KNIGHT] = { "N", "n", "", "", "Knight", P_VAL_OPN, N_VAL_MID, N_VAL_END }, [B_KNIGHT] = { "N", "n", "n", "", "Knight", P_VAL_OPN, N_VAL_MID, N_VAL_END },
[B_BISHOP] = { "B", "b", "", "", "Bishop", P_VAL_OPN, B_VAL_MID, B_VAL_END }, [B_BISHOP] = { "B", "b", "b", "", "Bishop", P_VAL_OPN, B_VAL_MID, B_VAL_END },
[B_ROOK] = { "R", "r", "", "", "Rook", P_VAL_OPN, R_VAL_MID, R_VAL_END }, [B_ROOK] = { "R", "r", "r", "", "Rook", P_VAL_OPN, R_VAL_MID, R_VAL_END },
[B_QUEEN] = { "Q", "q", "", "", "Queen", P_VAL_OPN, Q_VAL_MID, Q_VAL_END }, [B_QUEEN] = { "Q", "q", "q", "", "Queen", P_VAL_OPN, Q_VAL_MID, Q_VAL_END },
[B_KING] = { "K", "k", "", "", "King", P_VAL_OPN, K_VAL_MID, K_VAL_END }, [B_KING] = { "K", "k", "k", "", "King", P_VAL_OPN, K_VAL_MID, K_VAL_END },
}; };
const char pieces_str[6+6+1] = "PNBRQKpnbrqk"; const char pieces_str[6+6+1] = "PNBRQKpnbrqk";
@@ -51,24 +51,28 @@ bool piece_ok(piece_t p)
return !(p & ~(MASK_COLOR | MASK_PIECE)) && pt && (pt <= KING); return !(p & ~(MASK_COLOR | MASK_PIECE)) && pt && (pt <= KING);
} }
char *piece_to_char(piece_t p) char *piece_to_cap(piece_t p)
{ {
return piece_details[p].abbr; return piece_details[p].cap;
} }
char *piece_to_char_color(piece_t p) char *piece_to_char(piece_t p)
{ {
return piece_details[p].c_abbr; return piece_details[p].fen;
} }
char *piece_to_low(piece_t p)
{
return piece_details[p].low;
}
//char *piece_to_sym(piece_t p)
//{
// return piece_details[PIECE(p)].sym;
//}
char *piece_to_sym(piece_t p) char *piece_to_sym(piece_t p)
{ {
return piece_details[PIECE(p)].sym; return piece_details[p].sym;
}
char *piece_to_sym_color(piece_t p)
{
return piece_details[p].c_sym;
} }
char *piece_to_name(piece_t p) char *piece_to_name(piece_t p)
@@ -76,98 +80,20 @@ char *piece_to_name(piece_t p)
return piece_details[p].name; return piece_details[p].name;
} }
piece_t char_to_piece(char c) piece_type_t piece_t_from_char(char c)
{ {
char *p = strchr(pieces_str, c); char *p = strchr(pieces_str, c);
return p? (p - pieces_str) % 6 + 1: EMPTY; return p? (p - pieces_str) % 6 + 1: NO_PIECE_TYPE;
} }
piece_t char_color_to_piece(char c) //piece_type_t piece_from_promotion(char c, color_t color)
//{
// piece_type_t piece = piece_t_from_char(c);
// return piece? SET_COLOR()p? (p - pieces_str) % 6 + 1: NO_PIECE_TYPE;
//}
piece_t piece_from_char(char c)
{ {
piece_t piece = char_to_piece(c); piece_type_t piece = piece_t_from_char(c);
return isupper(c)? piece: SET_BLACK(piece); return isupper(c)? SET_WHITE(piece): SET_BLACK(piece);
} }
/*
* void piece_list_print(struct list_head *list)
* {
* struct list_head *p_cur, *tmp;
* piece_list_t *piece;
*
* list_for_each_safe(p_cur, tmp, list) {
* piece = list_entry(p_cur, piece_list_t, list);
*
* printf("%s%c%c ", P_SYM(piece->piece),
* FILE2C(F88(piece->square)),
* RANK2C(R88(piece->square)));
* }
* printf("\n");
* }
*
* pool_t *piece_pool_init()
* {
* if (!pieces_pool)
* pieces_pool = pool_create("pieces", 128, sizeof(piece_list_t));
* return pieces_pool;
* }
*
* void piece_pool_stats()
* {
* if (pieces_pool)
* pool_stats(pieces_pool);
* }
*
* piece_list_t *piece_add(pos_t *pos, piece_t piece, square_t square)
* {
* piece_list_t *new;
* short color = COLOR(piece);
*
* # ifdef DEBUG_PIECE
* log_f(3, "piece=%02x square=%02x\n", piece, square);
* log_f(5, "Adding %s %s on %c%c\n", color? "Black": "White",
* P_NAME(piece), FILE2C(F88(square)), RANK2C(R88(square)));
* # endif
* if ((new = pool_get(pieces_pool))) {
* /\* first piece is always king *\/
* if (PIECE(piece) == KING)
* list_add(&new->list, &pos->pieces[color]);
* else
* list_add_tail(&new->list, &pos->pieces[color]);
* new->piece = piece;
* new->square = square;
* new->castle = 0;
* new-> value = piece_details[PIECE(piece)].value;
* }
*
* return new;
* }
*
* void piece_del(struct list_head *ptr)
* {
* piece_list_t *piece = list_entry(ptr, piece_list_t, list);
* # ifdef DEBUG_PIECE
* log_f(3, "piece=%02x square=%02x\n", piece->piece, piece->square);
* # endif
* list_del(ptr);
* pool_add(pieces_pool, piece);
* return;
* }
*
* int pieces_del(pos_t *pos, short color)
* {
* struct list_head *p_cur, *tmp, *head;
* int count = 0;
*
* head = &pos->pieces[color];
*
* list_for_each_safe(p_cur, tmp, head) {
* piece_del(p_cur);
* count++;
* }
* # ifdef DEBUG_PIECE
* log_f(3, "color=%d removed=%d\n", color, count);
* # endif
* return count;
* }
*/

View File

@@ -31,6 +31,7 @@ typedef enum {
typedef enum { typedef enum {
ALL_PIECES = 0, /* 'all pieces' bitboard */ ALL_PIECES = 0, /* 'all pieces' bitboard */
NO_PIECE_TYPE = 0,
PAWN = 1, KNIGHT, BISHOP, ROOK, QUEEN, KING, PAWN = 1, KNIGHT, BISHOP, ROOK, QUEEN, KING,
PIECE_TYPE_MAX = 7 /* bit 4 */ PIECE_TYPE_MAX = 7 /* bit 4 */
} piece_type_t; } piece_type_t;
@@ -80,10 +81,10 @@ typedef enum __piece_e {
* s64 end_value; * s64 end_value;
*/ */
extern const struct piece_details { extern const struct piece_details {
char *abbr; /* used for game notation */ char *cap; /* used for game notation */
char *c_abbr; /* lowercase = black */ char *low; /* used also for UCI promotion */
char *sym; /* used for game notation */ char *fen; /* cap=white, low=black */
char *c_sym; /* different W & B */ char *sym; /* UTF-8 symbol */
char *name; /* piece name */ char *name; /* piece name */
s64 opn_value; /* value opening */ s64 opn_value; /* value opening */
s64 mid_value; /* value midgame */ s64 mid_value; /* value midgame */
@@ -104,20 +105,26 @@ extern const char pieces_str[6+6+1]; /* to search from fen/user inp
#define IS_WHITE(p) (!COLOR(p)) #define IS_WHITE(p) (!COLOR(p))
#define IS_BLACK(p) (COLOR(p)) #define IS_BLACK(p) (COLOR(p))
#define SET_WHITE(p) ((p) &= ~MASK_COLOR) #define SET_WHITE(p) (piece_t)((p) &= ~MASK_COLOR)
#define SET_BLACK(p) ((p) |= MASK_COLOR) #define SET_BLACK(p) (piece_t)((p) |= MASK_COLOR)
#define SET_COLOR(p, c) (!(c)? SET_WHITE(p): SET_BLACK(p)) #define SET_COLOR(p, c) (piece_t)(!(c)? SET_WHITE(p): SET_BLACK(p))
extern bool piece_ok(piece_t p); bool piece_ok(piece_t p);
extern char *piece_to_char(piece_t p); char *piece_to_cap(piece_t p);
extern char *piece_to_char_color(piece_t p); char *piece_to_low(piece_t p);
extern char *piece_to_sym(piece_t p); char *piece_to_fen(piece_t p);
extern char *piece_to_sym_color(piece_t p); char *piece_to_sym(piece_t p);
extern char *piece_to_name(piece_t p); char *piece_to_name(piece_t p);
extern piece_t char_to_piece(char c); #define piece_to_char(c) piece_to_fen(c)
extern piece_t char_color_to_piece(char c); //#define piece_to_char_t(p) piece_to_uci(p)
//piece_type_t char_to_piece(char c);
piece_type_t piece_t_from_char(char c);
piece_t piece_from_fen(char c);
#define piece_from_char(c) piece_from_fen(c)
/* use short name or symbol - no effect /* use short name or symbol - no effect
*/ */

View File

@@ -128,7 +128,8 @@ pos_t *pos_clear(pos_t *pos)
*/ */
bitboard_t pos_checkers(const pos_t *pos, const color_t color) bitboard_t pos_checkers(const pos_t *pos, const color_t color)
{ {
return sq_attackers(pos, pos->king[color], OPPONENT(color)); bitboard_t occ = pos_occ(pos);
return sq_attackers(pos, occ, pos->king[color], OPPONENT(color));
} }
/** /**
@@ -303,7 +304,7 @@ void pos_print_pieces(const pos_t *pos)
p = pos->bb[color][piece]; p = pos->bb[color][piece];
count = popcount64(p); count = popcount64(p);
cur = 0; cur = 0;
pname = piece_to_char(piece); pname = piece_to_cap(piece);
printf("%s(0)%s", pname, count? ":": ""); printf("%s(0)%s", pname, count? ":": "");
if (count) { if (count) {
bit_for_each64(bit, tmp, p) { bit_for_each64(bit, tmp, p) {
@@ -311,7 +312,6 @@ void pos_print_pieces(const pos_t *pos)
printf("%s%c%c", cur? ",": "", FILE2C(cf), RANK2C(cr)); printf("%s%c%c", cur? ",": "", FILE2C(cf), RANK2C(cr));
cur++; cur++;
} }
} }
printf(" "); printf(" ");
} }

View File

@@ -35,6 +35,41 @@ struct fentest {
*/ */
//"4k3/pppppppp/8/8/8/8/PPPPPPPP/2BRK3 w - - 0 1", //"4k3/pppppppp/8/8/8/8/PPPPPPPP/2BRK3 w - - 0 1",
//"4k3/pppppppp/8/8/8/8/PPPPPPPP/1B1R1K2 w - - 0 1", //"4k3/pppppppp/8/8/8/8/PPPPPPPP/1B1R1K2 w - - 0 1",
{ MOVEGEN,
"illegal white e.p.",
"3k4/8/8/2qpPK2/8/8/8/8 w - d6 0 1",
},
{ MOVEGEN,
"illegal black e.p.",
"8/8/8/8/2QPpk2/8/8/3K4 b - d3 0 1",
},
{ MOVEGEN,
"illegal white e.p.",
"3k4/8/5K2/3pP3/8/2b5/8/8 w - d6 0 1",
},
{ MOVEGEN,
"illegal black e.p.",
"8/8/2B5/8/3Pp3/5k2/8/3K4 b - d3 0 1",
},
{ MOVEGEN,
"legal white e.p.",
"1K1k4/8/8/3pP3/8/6b1/8/8 w - d6 0 1",
},
{ MOVEGEN,
"legal black e.p.",
"8/8/6B1/8/3Pp3/8/8/1k1K4 b - d3 0 1",
},
{ MOVEGEN,
"white mate.",
"1nbqkbn1/ppp1pppp/8/r1rpP1K1/8/8/PPPP1PPP/RNBQ1BNR w - d6 0 1",
},
{ MOVEGEN,
"illegal e.p.",
"1nbqkbn1/ppp1pppp/8/r1rpP1K1/8/8/PPPP1PPP/RNBQ1BNR w - d6 0 1",
},
{ ATTACK, { ATTACK,
"checkers: a1 h1", "checkers: a1 h1",
"1k6/8/8/8/8/8/8/r2K3r w - - 1 1" "1k6/8/8/8/8/8/8/r2K3r w - - 1 1"
@@ -163,7 +198,7 @@ struct fentest {
"6k1/6pp/R2p4/p1p5/8/1P1r3P/6P1/6K1 b - - 3 3" "6k1/6pp/R2p4/p1p5/8/1P1r3P/6P1/6K1 b - - 3 3"
}, },
// below tests are from: // some of tests below are from:
// - Rodent IV // - Rodent IV
// - https://www.chessprogramming.net/perfect-perft/ // - https://www.chessprogramming.net/perfect-perft/
{ FEN | MOVEGEN, { FEN | MOVEGEN,
@@ -174,6 +209,10 @@ struct fentest {
"", "",
"8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 1" "8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 1"
}, },
{ FEN | MOVEGEN,
"",
"8/2p5/3p4/Kp5r/1R3p1k/8/4P1P1/8 w - - 0 1"
},
{ FEN | MOVEGEN, { FEN | MOVEGEN,
"", "",
"4rrk1/pp1n3p/3q2pQ/2p1pb2/2PP4/2P3N1/P2B2PP/4RRK1 b - - 7 19" "4rrk1/pp1n3p/3q2pQ/2p1pb2/2PP4/2P3N1/P2B2PP/4RRK1 b - - 7 19"

View File

@@ -31,17 +31,19 @@ int main(__unused int ac, __unused char**av)
bitboard_init(); bitboard_init();
while ((fen = next_fen(FEN))) { while ((fen = next_fen(FEN))) {
printf("***** [%s] ", fen);
fflush(stdout);
if (!(pos = fen2pos(NULL, fen))) { if (!(pos = fen2pos(NULL, fen))) {
printf("[%s] **INVALID\n", fen); printf("**INVALID\n");
} else { } else {
pos_print(pos); //pos_print(pos);
pos2fen(pos, revfen); pos2fen(pos, revfen);
if (!strcmp(fen, revfen)) { if (!strcmp(fen, revfen)) {
printf("[%s] OK\n", fen); printf("OK\n");
} else { } else {
//printf("fen = [%s]\nrev = [%s]", fen, revfen); //printf("fen = [%s]\nrev = [%s]", fen, revfen);
//pos_print_raw(pos, 1); printf("-> [%s] **FIXED\n",revfen);
printf("[%s] -> [%s] **FIXED\n", fen, revfen); pos_print_raw(pos, 1);
} }
pos_del(pos); pos_del(pos);
} }

View File

@@ -88,7 +88,7 @@ static void send_stockfish_fen(FILE *desc, pos_t *pos, char *fen)
move_t *moves = pos->moves.move; move_t *moves = pos->moves.move;
int nmoves = pos->moves.nmoves; int nmoves = pos->moves.nmoves;
//char nodescount[] = "Nodes searched"; //char nodescount[] = "Nodes searched";
printf("nmoves = %d\n", nmoves); //printf("nmoves = %d\n", nmoves);
fflush(stdout); fflush(stdout);
//sprintf(str, "stockfish \"position fen %s\ngo perft depth\n\"", fen); //sprintf(str, "stockfish \"position fen %s\ngo perft depth\n\"", fen);
fprintf(desc, "position fen %s\ngo perft 1\n", fen); fprintf(desc, "position fen %s\ngo perft 1\n", fen);
@@ -111,22 +111,46 @@ static void send_stockfish_fen(FILE *desc, pos_t *pos, char *fen)
// count); // count);
moves[nmoves++] = move_make(from, to); moves[nmoves++] = move_make(from, to);
} else if (sscanf(buf, "%*5s: %d", &count) == 1) {
square_t from = sq_from_string(buf);
square_t to = sq_from_string(buf + 2);
piece_type_t promoted = piece_t_from_char(*(buf + 4));
mycount += count;
//printf("move found: %c%c->%c%c %s->%s count=%d\n",
// buf[0], buf[1], buf[2], buf[3],
// sq_to_string(from), sq_to_string(to),
// count);
moves[nmoves++] = move_make_promote(from, to, promoted);
} }
} }
pos->moves.nmoves = nmoves; pos->moves.nmoves = nmoves;
// printf("fishcount=%d mycount=%d\n", fishcount, mycount); // printf("fishcount=%d mycount=%d\n", fishcount, mycount);
free(buf); free(buf);
} }
static void compare_moves(pos_t *fish, pos_t *me) static __unused bool movelists_equal(movelist_t *fish, movelist_t *me)
{
move_t *m1 = fish->move, *m2 = me->move;
int n1 = fish->nmoves, n2 = me->nmoves;
int mask = 077777;
if (n1 != n2)
return false;
for (int cur = 0; cur < n1; ++cur) {
if ((m1[cur] & mask) != (m2[cur] & mask))
return false;
}
return true;
}
static __unused void compare_moves(movelist_t *fish, movelist_t *me)
{ {
char str1[1024] = {0}, str2[1024] = {0}, tmpstr[1024]; char str1[1024] = {0}, str2[1024] = {0}, tmpstr[1024];
char *skip = " "; char *skip = " ";
move_t *m1 = fish->moves.move; move_t *m1 = fish->move;
move_t *m2 = me->moves.move; move_t *m2 = me->move;
int n1 = fish->moves.nmoves; int n1 = fish->nmoves;
int n2 = me->moves.nmoves; int n2 = me->nmoves;
#define f(c) move_from(c) #define f(c) move_from(c)
#define t(c) move_to(c) #define t(c) move_to(c)
@@ -191,9 +215,13 @@ int main(int __unused ac, __unused char**av)
FILE *outfd; FILE *outfd;
char *fen; char *fen;
pos_t *pos, *fishpos = pos_new(); pos_t *pos, *fishpos = pos_new();
movelist_t legal;
//bitboard_t wrong = 0x5088000040, tmp, loop; //bitboard_t wrong = 0x5088000040, tmp, loop;
//bit_for_each64(loop, tmp, ) //bit_for_each64(loop, tmp, )
//printf("fishpos 1=%p\n", fishpos); //printf("fishpos 1=%p\n", fishpos);
setlinebuf(stdout); /* line-buffered stdout */
bitboard_init(); bitboard_init();
hyperbola_init(); hyperbola_init();
outfd = open_stockfish(); outfd = open_stockfish();
@@ -201,15 +229,15 @@ int main(int __unused ac, __unused char**av)
while ((fen = next_fen(MOVEGEN))) { while ((fen = next_fen(MOVEGEN))) {
//printf(">>>>> %s\n", test[i]); //printf(">>>>> %s\n", test[i]);
//printf("fishpos 2=%p\n", fishpos); //printf("fishpos 2=%p\n", fishpos);
printf("original fen %d: [%p][%s]\n", i, fen, fen); //printf("original fen %d: [%p][%s]\n", i, fen, fen);
if (!(pos = fen2pos(NULL, fen))) { if (!(pos = fen2pos(NULL, fen))) {
printf("wrong fen %d: [%s]\n", i, fen); printf("wrong fen %d: [%s]\n", i, fen);
continue; continue;
} }
pos_print(pos);
/* print movelists */ /* print movelists */
send_stockfish_fen(outfd, fishpos, fen); send_stockfish_fen(outfd, fishpos, fen);
gen_all_pseudomoves(pos); pos_gen_pseudomoves(pos);
pos_legalmoves(pos, &legal);
//printf("Fu "); //printf("Fu ");
//moves_print(fishpos, 0); //moves_print(fishpos, 0);
//fflush(stdout); //fflush(stdout);
@@ -218,8 +246,8 @@ int main(int __unused ac, __unused char**av)
//fflush(stdout); //fflush(stdout);
/* sort and print movelists */ /* sort and print movelists */
move_sort_by_sq(fishpos); move_sort_by_sq(&fishpos->moves);
move_sort_by_sq(pos); move_sort_by_sq(&legal);
// printf("\nFs "); // printf("\nFs ");
// moves_print(fishpos, 0); // moves_print(fishpos, 0);
// fflush(stdout); // fflush(stdout);
@@ -228,7 +256,20 @@ int main(int __unused ac, __unused char**av)
// fflush(stdout); // fflush(stdout);
/* compare movelists */ /* compare movelists */
compare_moves(fishpos, pos); if (!movelists_equal(&fishpos->moves, &legal)) {
pos_print(pos);
printf("F: ");
moves_print(&fishpos->moves, 0);
printf("M: ");
moves_print(&legal, 0);
} else {
printf("[%s]\n\tMoves (OK): ", fen);
moves_print(&fishpos->moves, 0);
}
//compare_moves(&fishpos->moves, &legal);
//} else {
//printf("fen %d: [%s] - OK (%d moves)\n", i, fen, legal.nmoves);
//}
//pos_print_board_raw(pos, 1); //pos_print_board_raw(pos, 1);
//printf("%s\n", pos2fen(pos, str)); //printf("%s\n", pos2fen(pos, str));
//get_stockfish_moves(test[i]); //get_stockfish_moves(test[i]);

View File

@@ -1,55 +1,20 @@
#include <stdio.h> #include <stdio.h>
#include "debug.h" #include "brlib.h"
#include "../src/fen.h" #include "piece.h"
#include "../src/position.h"
#include "../src/bitboard.h"
int main(int ac, char**av) int main(__unused int ac, __unused char**av)
{ {
pos_t *pos;
printf("zobi\n");fflush(stdout);
debug_init(6, stderr, true);
log_f(5, "kfsjdhg\n");
pos_pool_init();
pos = pos_get();
piece_pool_init();
if (ac == 1) { piece_t p;
printf("zoba\n");fflush(stdout); char *test="PNBRQKpnbrqk";
pos_startpos(pos);
} else { for (u64 i = 0; i < sizeof(test); ++i) {
fen2pos(pos, av[1]); char c1 = test[i], *c2;
p = piece_from_fen(c1);
c2 = piece_to_fen(p);
printf("c1=%c c2=%c\n", c1, *c2);
} }
pos_print(pos); return 0;
pos_pieces_print(pos);
printf("0x1c = 11100 = C1-E1:\n");
bitboard_print(0x1c);
printf("0x70 = 111 = A1-C1\n");
bitboard_print(0x70);
printf("0x0e = 1110 = B1-D1\n");
bitboard_print(0x0e);
printf("0x60 = 1100000 = F1-G1\n");
bitboard_print(0x60);
printf("A1:\n");
bitboard_print(A1);
printf("1:\n");
bitboard_print(1L);
printf("H1:\n");
bitboard_print(H1);
printf("C1:\n");
bitboard_print(C1);
printf("D1:\n");
bitboard_print(D1);
printf("C1|D1:\n");
bitboard_print(C1|D1);
printf("H8:\n");
bitboard_print(H8);
} }