sq_attackers() + others (see dedails). Ready for move do/undo ?

- add many "const" in func parameters
- attack.c: sq_attackers()
- move print_board_raw from position.c to to board.c
- move some fen_check() tests to pos_check()
- add REL_RANK() macro. TODO: add one more for bitboards
- fen.c: more tests for FEN validity
- position.c: add pos_checkers() and pos_check()
- tests: add common-test.h (for shared FEN positions access)
This commit is contained in:
2024-03-04 21:34:29 +01:00
parent a499893f32
commit b351d198b8
18 changed files with 584 additions and 482 deletions

View File

@@ -18,9 +18,10 @@
#include "bitboard.h"
#include "position.h"
#include "hyperbola-quintessence.h"
#include "attack.h"
/**
* square_attackers() - find attackers on a square
* sq_attackers() - find attackers on a square
* @pos: position
* @sq: square to test
* @c: attacker color
@@ -36,32 +37,69 @@
* @Return: a bitboard of attackers.
*
*/
bitboard_t sq_attackers(pos_t *pos, square_t sq, color_t c)
bitboard_t sq_attackers(const pos_t *pos, const square_t sq, const color_t c)
{
bitboard_t attackers = 0;
bitboard_t from = mask(sq);
bitboard_t sqbb = mask(sq);
bitboard_t c_pieces = pos->bb[c][ALL_PIECES];
bitboard_t occ = c_pieces | pos->bb[OPPONENT(c)][ALL_PIECES];
bitboard_t to;
color_t opp = OPPONENT(c);
/* pawn */
to = pos->bb[c][PAWN];
attackers |= pawn_push_upleft(from, c) & to;
attackers |= pawn_push_upright(from, c) & to;
attackers |= pawn_shift_upleft(sqbb, opp) & to;
# ifdef DEBUG_ATTACK
bitboard_print("sq_attackers after pawn upleft", attackers);
# endif
attackers |= pawn_shift_upright(sqbb, opp) & to;
# ifdef DEBUG_ATTACK
bitboard_print("sq_attackers pawn upright", attackers);
# endif
/* knight & king */
to = pos->bb[c][KNIGHT];
attackers |= bb_knight_moves(c_pieces, from);
attackers |= bb_knight_moves(to, sq);
# ifdef DEBUG_ATTACK
bitboard_print("sq_attackers after knight", attackers);
# endif
to = pos->bb[c][KING];
attackers |= bb_king_moves(c_pieces, from);
attackers |= bb_king_moves(to, sq);
# ifdef DEBUG_ATTACK
bitboard_print("sq_attackers after king", attackers);
# endif
/* bishop / queen */
to = pos->bb[c][BISHOP] | pos->bb[c][QUEEN];
attackers |= hyperbola_bishop_moves(occ, from) & to;
attackers |= hyperbola_bishop_moves(occ, sq) & to;
# ifdef DEBUG_ATTACK
bitboard_print("sq_attackers after bishop/queen", attackers);
# endif
/* rook / queen */
to = pos->bb[c][ROOK] | pos->bb[c][QUEEN];
attackers |= hyperbola_rook_moves(occ, from) & to;
# ifdef DEBUG_ATTACK
bitboard_print("sq_attackers after queen", attackers);
# endif
attackers |= hyperbola_rook_moves(occ, sq) & to;
# ifdef DEBUG_ATTACK
bitboard_print("sq_attackers after rook/queen", attackers);
# endif
return attackers;
}
/**
* sq_attackers() - find all attackers on a square
* @pos: position
* @sq: square to test
*
* Find all attacks on @sq. En-passant is not considered.
* Just a wrapper over @sq_attackers().
*
* @Return: a bitboard of attackers.
*/
bitboard_t sq_attackers_all(const pos_t *pos, const square_t sq)
{
return sq_attackers(pos, sq, WHITE) | sq_attackers(pos, sq, BLACK);
}

View File

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

View File

@@ -118,7 +118,9 @@ static __always_inline bitboard_t shift_nw(const bitboard_t bb)
#define pawn_shift_up(bb, c) ((c) == WHITE ? shift_n(bb): shift_s(bb))
#define pawn_shift_upleft(bb, c) ((c) == WHITE ? shift_nw(bb): shift_se(bb))
#define pawn_shift_upright(bb, c) ((c) == WHITE ? shift_ne(bb): shift_sw(bb))
/* pawn move (for single pawn) */
/* pawn move (for single pawn) - NO SQUARE CONTROL HERE !
* Need to make functions with control instead.
*/
#define pawn_push_up(sq, c) ((sq) + ((c) == WHITE ? NORTH: SOUTH))
#define pawn_push_upleft(sq, c) ((sq) + ((c) == WHITE ? NORTH_WEST: SOUTH_EAST))
#define pawn_push_upright(sq, c) ((sq) + ((c) == WHITE ? NORTH_EAST: SOUTH_WEST))

View File

@@ -1,4 +1,4 @@
/* board.c - 8x8 board.
/* board.c - 8x8 functions.
*
* Copyright (C) 2024 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
@@ -57,7 +57,7 @@ square_t sq_from_string(const char *sqstr)
* board_print() - Print a board
* @board: &board_t to print
*/
void board_print(piece_t *board)
void board_print(const piece_t *board)
{
printf(" +---+---+---+---+---+---+---+---+\n");
for (int rank = 7; rank >= 0; --rank) {
@@ -82,7 +82,7 @@ void board_print(piece_t *board)
*
* Squares corresponding to @mask will be displayed in reverse colors.
*/
void board_print_mask(piece_t *board, bitboard_t mask)
void board_print_mask(const piece_t *board, const bitboard_t mask)
{
// 6: blink
# define REVERSE "\e[7m▌"
@@ -106,3 +106,23 @@ void board_print_mask(piece_t *board, bitboard_t mask)
}
printf(" A B C D E F G H\n");
}
/**
* board_print_raw - print raw (octal or FEN symbol) board
* @bb: the bitboard
* @type: int, 0 for octal, 1 for fen symbol
*/
void board_print_raw(const piece_t *board, const int type)
{
for (rank_t r = RANK_8; r >= RANK_1; --r) {
for (file_t f = FILE_A; f <= FILE_H; ++f) {
piece_t p = board[sq_make(f, r)];
if (type) {
printf("%s ", p == EMPTY? ".": piece_to_char_color(p));
} else {
printf("%02o ", p);
}
}
printf("\n");
}
}

View File

@@ -65,7 +65,8 @@ static __always_inline rank_t sq_rank(square_t square)
extern const char *sq_to_string(const square_t sq);
extern square_t sq_from_string(const char *sq_string);
extern void board_print(piece_t *board);
extern void board_print_mask(piece_t *board, bitboard_t mask);
extern void board_print(const piece_t *board);
extern void board_print_mask(const piece_t *board, const bitboard_t mask);
extern void board_print_raw(const piece_t *board, const int type);
#endif /* _BOARD_H */

View File

@@ -16,19 +16,21 @@
#include "brlib.h" /* brlib types */
#define ONE 1ull
#define C64(const_u64) const_u64##ULL
#define mask(i) ( (unsigned long long) (ONE << (i)) )
#define ONE 1ull
#define C64(const_u64) const_u64##ULL
#define mask(i) ( (unsigned long long) (ONE << (i)) )
//typedef ushort board;
#define BOARDSIZE (8*8)
/* from human to machine */
#define C2FILE(c) (tolower(c) - 'a')
#define C2RANK(c) (tolower(c) - '1')
/* from machine to human */
#define FILE2C(f) ((f) + 'a')
#define RANK2C(r) ((r) + '1')
#define BOARDSIZE (8*8)
/* from human to machin e */
#define C2FILE(c) (tolower(c) - 'a')
#define C2RANK(c) (tolower(c) - '1')
/* from machine to huma n */
#define FILE2C(f) ((f) + 'a')
#define RANK2C(r) ((r) + '1')
/* relative rank */
#define REL_RANK(r, c) ((7 * (c)) ^ r)
/* castle_t bits structure
*/
typedef enum {

View File

@@ -1,4 +1,4 @@
/* fen.c - fen notation.
/* fen.c - fen parsing/generation/test.
*
* Copyright (C) 2021-2024 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
@@ -22,8 +22,8 @@
#include "chessdefs.h"
#include "util.h"
#include "piece.h"
#include "bitboard.h"
//#include "piece.h"
//#include "bitboard.h"
#include "position.h"
#include "fen.h"
@@ -61,19 +61,18 @@ static const char *castle_str = "KQkq";
#define SKIP_BLANK(p) for(;isspace(*(p)); (p)++)
/**
* fen_test(pos_t *pos) - test (and try to fix) fen-generated position.
* fen_check(pos_t *pos) - test (and try to fix) fen-generated position.
* @pos: position
*
* fen_test() tests the following:
* - fatal: number of pawns > 8
* - fatal: number of pieces > 16
* - fatal: number of kings != 1
* - fixable: inconsistent castle flags (if K & R are not in correct position)
* - fixable: inconsistent en-passant square (turn, bad pawn position)
* Test and fix the following:
* - inconsistent castle flags (if K & R are not in correct position)
* - inconsistent en-passant square (turn, bad pawn position)
*
* pos_check() is also called, leading to fatal errors if something is wrong.
*
* @return: 0 if OK, 1 if OK after fix, -1 if fatal issue.
*/
static int fen_test(pos_t *pos)
static int fen_check(pos_t *pos)
{
char *colstr[2] = { "white", "black"};
int error = 0, warning = 0;
@@ -82,24 +81,25 @@ static int fen_test(pos_t *pos)
if (pos->en_passant != SQUARE_NONE) {
rank_t eprank = sq_rank(pos->en_passant);
file_t epfile = sq_file(pos->en_passant);
rank_t rank5 = pos->turn == WHITE? RANK_5: RANK_4;
rank_t rank6 = pos->turn == WHITE? RANK_6: RANK_3;
rank_t rank7 = pos->turn == WHITE? RANK_7: RANK_2;
rank_t rank5 = REL_RANK(RANK_5, pos->turn);
rank_t rank6 = REL_RANK(RANK_6, pos->turn);
rank_t rank7 = REL_RANK(RANK_7, pos->turn);
piece_t pawn = pos->turn == WHITE? B_PAWN: W_PAWN;
if (warn(eprank != rank6 ||
pos->board[sq_make(epfile, rank5)] != pawn ||
pos->board[sq_make(epfile, rank6)] != EMPTY ||
pos->board[sq_make(epfile, rank7)] != EMPTY,
"fen warn: wrong en-passant settings. (fixed)\n")) {
# ifdef DEBUG_FEN
printf("ep5=%o ep6=%o ep7=%o\n", sq_make(epfile, rank5),
sq_make(epfile, rank6), sq_make(epfile, rank6));
sq_make(epfile, rank6), sq_make(epfile, rank7));
# endif
warning++;
pos->en_passant = SQUARE_NONE;
}
}
for (int color = WHITE; color <= BLACK; ++color) {
int n;
rank_t rank1 = color == WHITE? RANK_1: RANK_8;
/* castling */
@@ -130,18 +130,12 @@ static int fen_test(pos_t *pos)
}
}
/* piece, pawn, anf king count */
n = popcount64(pos->bb[color][PAWN]);
error += warn(n > 8,
"fen err: %s has %d pawns\n", colstr[color], n);
n = popcount64(pos->bb[color][KING]);
error += warn(n != 1,
"fen err: %s has %d kings\n", colstr[color], n);
n = popcount64(pos->bb[color][ALL_PIECES]);
error += warn(n > 16,
"fen err: %s has %d pieces\n", colstr[color], n);
}
return error ? -1: warning ? 1: 0;
if (!(error = pos_check(pos, 0))) {
/* TODO: Should it really be here ? */
pos->checkers = pos_checkers(pos, pos->turn);
}
return error ? -1: warning;
}
/**
@@ -259,13 +253,13 @@ end:
err_line, err_pos, err_char, err_char)) {
return NULL;
}
if (fen_test(&tmppos) >= 0) {
if (!pos)
pos = pos_new();
*pos = tmppos;
}
if (fen_check(&tmppos) < 0)
return NULL;
if (!pos)
pos = pos_new();
*pos = tmppos;
# ifdef DEBUG_FEN
pos_print_board_raw(&tmppos, 1);
pos_print_raw(&tmppos, 1);
# endif
return pos;

View File

@@ -14,7 +14,7 @@
#ifndef FEN_H
#define FEN_H
#include "position.h"
#include "chessdefs.h"
#define FENSTRLEN 92 /* secure FEN string size */

View File

@@ -1,4 +1,4 @@
/* movegen.c - move generation
/* move-gen.c - move generation
*
* Copyright (C) 2024 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
@@ -21,7 +21,7 @@
#include "position.h"
#include "move.h"
#include "hyperbola-quintessence.h"
#include "movegen.h"
#include "move-gen.h"
/**
@@ -111,8 +111,8 @@ int gen_all_pseudomoves(pos_t *pos)
}
/* 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_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;

View File

@@ -1,4 +1,4 @@
/* movegen.h - move generation
/* move-gen.h - move generation
*
* Copyright (C) 2024 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.

View File

@@ -115,7 +115,7 @@ void moves_print(pos_t *pos, __unused int flags)
}
static int _moves_comp_square(const void *p1, const void *p2)
static int _moves_cmp_bysquare(const void *p1, const void *p2)
{
move_t m1 = *(move_t *)p1;
move_t m2 = *(move_t *)p2;
@@ -129,7 +129,7 @@ static int _moves_comp_square(const void *p1, const void *p2)
/* f1 == f2 */
if (t1 < t2) return -1;
if (t1 > t2) return 1;
return 0; /* DUP BUG ! */
return 0;
}
/**
* move_sort_by_sq() - sort moves by from/to squares ascending
@@ -139,7 +139,7 @@ static int _moves_comp_square(const void *p1, const void *p2)
*/
void move_sort_by_sq(pos_t *pos)
{
qsort(pos->moves.move, pos->moves.nmoves, sizeof(move_t), _moves_comp_square);
qsort(pos->moves.move, pos->moves.nmoves, sizeof(move_t), _moves_cmp_bysquare);
}
/*

View File

@@ -28,18 +28,7 @@
#include "piece.h"
#include "util.h"
#include "board.h"
/****************************************************
* #define BYTE_PRINT "%c%c%c%c%c%c%c%c" *
* #define BYTE2BIN(b) ((b) & 0x01 ? '1' : '0'), \ *
* ((b) & 0x02 ? '1' : '0'), \ *
* ((b) & 0x04 ? '1' : '0'), \ *
* ((b) & 0x08 ? '1' : '0'), \ *
* ((b) & 0x10 ? '1' : '0'), \ *
* ((b) & 0x20 ? '1' : '0'), \ *
* ((b) & 0x40 ? '1' : '0'), \ *
* ((b) & 0x80 ? '1' : '0') *
****************************************************/
#include "attack.h"
/**
* pos_new() - allocate a new position
@@ -71,7 +60,7 @@ pos_t *pos_new(void)
*
* TODO: merge with pos_new - NULL for init, non null for duplicate
*/
pos_t *pos_dup(pos_t *pos)
pos_t *pos_dup(const pos_t *pos)
{
pos_t *newpos = safe_malloc(sizeof(pos_t));
@@ -104,82 +93,143 @@ pos_t *pos_clear(pos_t *pos)
# ifdef DEBUG_POS
printf("size(pos_board=%lu elt=%lu\n", sizeof(pos->board), sizeof(int));
# endif
//for (square square = A1; square <= H8; ++square)
// pos->board[square] = EMPTY;
SET_WHITE(pos->turn);
pos->node_count = 0;
pos->turn = 0;
pos->turn = WHITE;
pos->clock_50 = 0;
pos->plycount = 0;
pos->en_passant = SQUARE_NONE;
pos->castle = 0;
memset(pos->board, EMPTY, sizeof(pos->board));
//pos->curmove = 0;
//pos->eval = 0;
//pos->occupied[WHITE] = 0;
//pos->occupied[BLACK] = 0;
for (color_t color = WHITE; color <= BLACK; ++color) {
for (piece_type_t piece = 0; piece <= KING; ++piece)
pos->bb[color][piece] = 0;
pos->controlled[WHITE] = 0;
pos->controlled[BLACK] = 0;
pos->controlled[color] = 0;
pos->king[color] = SQUARE_NONE;
}
pos->moves.curmove = pos->moves.nmoves = 0;
//pos->mobility[WHITE] = 0;
//pos->mobility[BLACK] = 0;
//pos->moves_generated = false;
//pos->moves_counted = false;
/* remove pieces / moves */
//pieces_del(pos, WHITE);
//pieces_del(pos, BLACK);
//moves_del(pos);
for (square_t sq = A1; sq <= H8; ++sq)
pos->board[sq] = EMPTY;
pos->moves.curmove = 0;
pos->moves.nmoves = 0;
return pos;
}
/**
* pos_checkers() - find all checkers on a king.
* @pos: &position
* @color: king color
*
* Get a bitboard of all checkers on @color king.
* Just a wrapper over @sq_attackers().
*
* @return: a bitboard of attackers.
*/
bitboard_t pos_checkers(const pos_t *pos, const color_t color)
{
return sq_attackers(pos, pos->king[color], OPPONENT(color));
}
/**
* pos_checkers2str() - convert checkers to string.
* @pos: &position
* @str: destination string (should be at least 2*3 + 1 = 7 length)
*
* @return: The string.
*/
char *pos_checkers2str(const pos_t *pos, char *str)
{
int sq, tmp;
char *p = str;
bit_for_each64(sq, tmp, pos->checkers) {
const char *sqstr = sq_to_string(sq);
*p++ = sqstr[0];
*p++ = sqstr[1];
*p++ = ' ';
}
*p = 0;
return str;
}
/**
* pos_check() - extensive position consistenci check.
* @pos: &position
* @strict: if not zero, call bug_on() on any error.
*
* Check (hopefully) if position is valid:
* - pawns on first or 8th rank
* - number of pawns per color > 8
* - total number of pieces per color > 16 or zero
* - number of kings per color != 1
* - discrepancy between bitboards per piece and ALL_PIECES per color
* - discrepancy between bitboards and board
* - side-to-move already checking opponent king.
*
* In case of errors, and @abort is true, @bug_on() is called, and program will
* be terminated.
* This function should be called with @abort == 0 during initialization phase
* (eg after fen parsing), and with @abort != 0 otherwise (as we have some data
* corruption).
*
* TODO: add more checks
* - en-prise king for side to move.
*
* @Return: 0 if no error detected
* the number of detected error if @abort == 0.
* this function does not return if @abort != 0 and errors are found.
*/
int pos_check(const pos_t *pos, const int fatal)
{
int n, count = 0, bbcount = 0, error = 0;
/* pawns on 1st ot 8th rank */
n = popcount64((pos->bb[WHITE][PAWN] | pos->bb[BLACK][PAWN]) &
(RANK_1bb | RANK_8bb));
error += warn_on(n != 0);
for (color_t color = WHITE; color <= BLACK; ++color) {
/* pawn count */
n = popcount64(pos->bb[color][PAWN]);
error += warn_on(n > 8);
/* king count */
n = popcount64(pos->bb[color][KING]);
error += warn_on(n != 1);
/* pieces count */
n = popcount64(pos->bb[color][ALL_PIECES]);
error += warn_on(n == 0 || n > 16);
bbcount += n;
}
for (square_t sq = 0; sq < 64; ++sq) {
piece_t piece = pos->board[sq];
bitboard_t match;
if (piece == EMPTY)
continue;
color_t c = COLOR(piece);
piece_type_t p = PIECE(piece);
match = pos->bb[c][p] & mask(sq);
error += warn_on(!match);
count++;
}
/* occupied occupation is different from bitboards */
error += warn_on(count != bbcount);
/* is color to play in check ? */
error += warn_on(pos_checkers(pos, OPPONENT(pos->turn)));
bug_on(fatal && error);
return error;
}
/**
* pos_print() - Print position and fen on stdout.
* @pos: &position
*/
void pos_print(pos_t *pos)
void pos_print(const pos_t *pos)
{
//int rank, file;
//piece_t *board = pos->board;
char fen[92];
char str[92];
//piece_list_t *wk = list_first_entry(&pos->pieces[WHITE], piece_list_t, list),
// *bk = list_first_entry(&pos->pieces[BLACK], piece_list_t, list);
board_print(pos->board);
/*
* printf(" +---+---+---+---+---+---+---+---+\n");
* for (rank = 7; rank >= 0; --rank) {
* printf("%c |", rank + '1');
* for (file = 0; file < 8; ++file) {
* pc = board[sq_make(file, rank)];
* printf(" %s |", pc? piece_to_sym_color(pc): " ");
* }
* printf("\n +---+---+---+---+---+---+---+---+\n");
* }
* printf(" A B C D E F G H\n");
*/
printf("fen %s\n", pos2fen(pos, fen));
//printf("Turn: %s.\n", IS_WHITE(pos->turn) ? "white" : "black");
/*
* printf("Kings: W:%c%c B:%c%c\n",
* FILE2C(F88(wk->square)),
* RANK2C(R88(wk->square)),
* FILE2C(F88(bk->square)),
* RANK2C(R88(bk->square)));
*/
//printf("plies=%d clock50=%d\n", pos->plycount, pos->clock_50);
//printf("Current move = %d\n", pos->curmove);
//printf("Squares controlled: W:%d B:%d\n", popcount64(pos->controlled[WHITE]),
// popcount64(pos->controlled[BLACK]));
//printf("Mobility: W:%u B:%u\n", pos->mobility[WHITE],
// pos->mobility[BLACK]);
printf("fen %s\n", pos2fen(pos, str));
printf("checkers %s\n", pos_checkers2str(pos, str));
}
/**
@@ -187,50 +237,30 @@ void pos_print(pos_t *pos)
* @pos: &position
* @mask: mask of highlighted squares.
*/
void pos_print_mask(pos_t *pos, bitboard_t mask)
void pos_print_mask(const pos_t *pos, const bitboard_t mask)
{
//int rank, file;
//piece_t pc, *board = pos->board;
char fen[92];
//piece_list_t *wk = list_first_entry(&pos->pieces[WHITE], piece_list_t, list),
// *bk = list_first_entry(&pos->pieces[BLACK], piece_list_t, list);
board_print_mask(pos->board, mask);
/*
* printf(" +---+---+---+---+---+---+---+---+\n");
* for (rank = 7; rank >= 0; --rank) {
* printf("%c |", rank + '1');
* for (file = 0; file < 8; ++file) {
* pc = board[sq_make(file, rank)];
* printf(" %s |", pc? piece_to_sym_color(pc): " ");
* }
* printf("\n +---+---+---+---+---+---+---+---+\n");
* }
* printf(" A B C D E F G H\n");
*/
printf("fen %s\n", pos2fen(pos, fen));
//printf("Turn: %s.\n", IS_WHITE(pos->turn) ? "white" : "black");
/*
* printf("Kings: W:%c%c B:%c%c\n",
* FILE2C(F88(wk->square)),
* RANK2C(R88(wk->square)),
* FILE2C(F88(bk->square)),
* RANK2C(R88(bk->square)));
*/
//printf("plies=%d clock50=%d\n", pos->plycount, pos->clock_50);
//printf("Current move = %d\n", pos->curmove);
//printf("Squares controlled: W:%d B:%d\n", popcount64(pos->controlled[WHITE]),
// popcount64(pos->controlled[BLACK]));
//printf("Mobility: W:%u B:%u\n", pos->mobility[WHITE],
// pos->mobility[BLACK]);
}
/**
* pos_pieces_print() - Print position pieces
* pos_print_board_raw - print simple position board (octal/FEN symbol values)
* @bb: the bitboard
* @type: int, 0 for octal, 1 for fen symbol
*/
void pos_print_raw(const pos_t *pos, const int type)
{
board_print_raw(pos->board, type);
return;
}
/**
* pos_print_pieces() - Print position pieces
* @pos: &position
*/
void pos_pieces_print(pos_t *pos)
void pos_print_pieces(const pos_t *pos)
{
int bit, count, cur;
char *pname;
@@ -254,123 +284,5 @@ void pos_pieces_print(pos_t *pos)
printf(" ");
}
printf("\n");
//printf("White pieces (%d): \t", popcount64(pos->occupied[WHITE]));
//piece_list_print(&pos->pieces[WHITE]);
//printf("Black pieces (%d): \t", popcount64(pos->occupied[BLACK]));
//piece_list_print(&pos->pieces[BLACK]);
}
}
/*
inline void bitboard_print2_raw(bitboard_t bb1, bitboard_t bb2, char *title)
{
int i;
printf("%s%s", title? title: "", title? ":\n": "");
printf("\tW: %#018lx\tB: %#018lx\n", bb1, bb2);
for (i=56; i>=0; i-=8)
printf("\t"BYTE_PRINT"\t\t"BYTE_PRINT"\n",
BYTE2BIN(bb1>>i),
BYTE2BIN(bb2>>i));
}
*/
/**
* pos_print_board_raw - print simple position board (octal/FEN symbol values)
* @bb: the bitboard
* @type: int, 0 for octal, 1 for fen symbol
*/
void pos_print_board_raw(const pos_t *pos, int type)
{
if (type == 0) {
for (rank_t r = RANK_8; r >= RANK_1; --r) {
for (file_t f = FILE_A; f <= FILE_H; ++f)
printf("%02o ", pos->board[sq_make(f, r)]);
printf(" \n");
}
} else {
for (rank_t r = RANK_8; r >= RANK_1; --r) {
for (file_t f = FILE_A; f <= FILE_H; ++f) {
square_t sq = sq_make(f, r);
if (pos->board[sq] == EMPTY)
printf(". ");
else
printf("%s ", piece_to_char_color(pos->board[sq]));
}
printf(" \n");
}
}
return;
}
/**
* pos_bitboards_print() - Print position bitboards
* @pos: &position
*/
//void pos_bitboards_print(pos_t *pos)
//{
// printf("Bitboards occupied :\n");
// bitboard_print2(pos->occupied[WHITE], pos->occupied[BLACK]);
// printf("Bitboards controlled :\n");
// bitboard_print2(pos->controlled[WHITE], pos->controlled[BLACK]);
//
//}
/**
* pos_check() - extensive position consistenci check.
* @pos: &position
*/
/*
* void pos_check(position *pos)
* {
* int rank, file;
* piece_t piece;
* board_t *board = pos->board;
*
* /\* check that board and bitboard reflect same information *\/
* for (rank = 7; rank >= 0; --rank) {
* for (file = 0; file < 8; ++file) {
* piece_list_t *ppiece;
* printf("checking %c%c ", file+'a', rank+'1');
*
* piece = board[SQ88(file, rank)].piece;
* ppiece= board[SQ88(file, rank)].s_piece;
* printf("piece=%s ", P_CSYM(piece));
* if (ppiece)
* printf("ppiece=%s/sq=%#x ", P_CSYM(ppiece->piece), ppiece->square);
* switch(PIECE(piece)) {
* case PAWN:
* printf("pawn" );
* break;
* case KNIGHT:
* printf("knight ");
* break;
* case BISHOP:
* printf("bishop ");
* break;
* case ROOK:
* printf("rook ");
* break;
* case QUEEN:
* printf("queen ");
* break;
* case KING:
* printf("king ");
* break;
* }
* printf("\n");
* }
* }
* }
*/
/*
* void pos_del(pos_t *pos)
* {
* pieces_del(pos, WHITE);
* pieces_del(pos, BLACK);
* moves_del(pos);
* pool_add(pos_pool, pos);
* }
*/

View File

@@ -35,22 +35,11 @@ typedef struct __pos_s {
square_t en_passant;
castle_rights_t castle;
//eval_t eval;
//int check[2];
//int eval_simple_phase;
//eval_t eval_simple;
//move_t *bestmove;
//bool moves_generated;
//bool moves_counted;
bitboard_t bb[2][PIECE_TYPE_MAX]; /* bb[0][PAWN], bb[1][ALL_PIECES] */
bitboard_t controlled[2];
//u16 mobility[2];
//struct list_head pieces[2]; /* pieces list, King is first */
//struct list_head moves[2];
bitboard_t controlled[2]; /* unsure */
bitboard_t checkers; /* opponent checkers */
piece_t board[BOARDSIZE];
movelist_t moves;
//int nmoves;
} pos_t;
/**
@@ -93,18 +82,20 @@ static inline void pos_clr_sq(pos_t *pos, square_t square)
//void bitboard_print2(bitboard_t bb1, bitboard_t bb2, char *title);
extern pos_t *pos_new();
extern pos_t *pos_dup(pos_t *pos);
extern pos_t *pos_dup(const pos_t *pos);
extern void pos_del(pos_t *pos);
extern pos_t *pos_clear(pos_t *pos);
extern void pos_print(pos_t *pos);
extern void pos_print_mask(pos_t *pos, bitboard_t mask);
extern void pos_pieces_print(pos_t *pos);
extern bitboard_t pos_checkers(const pos_t *pos, const color_t color);
extern char *pos_checkers2str(const pos_t *pos, char *str);
extern void pos_print_board_raw(const pos_t *pos, int type);
extern int pos_check(const pos_t *pos, const int strict);
//extern pos_t *pos_startpos(pos_t *pos);
extern void pos_print(const pos_t *pos);
extern void pos_print_mask(const pos_t *pos, const bitboard_t mask);
extern void pos_print_raw(const pos_t *pos, const int type);
extern void pos_print_pieces(const pos_t *pos);
//void pos_check(position *pos);
#endif /* POSITION_H */