Compare commits
4 Commits
568b39e366
...
fa5c9bb8ab
Author | SHA1 | Date | |
---|---|---|---|
fa5c9bb8ab | |||
d00eab54e7 | |||
9c02a02c1e | |||
4d8f69e8c9 |
@@ -101,6 +101,6 @@ extern bitboard_t bb_king_moves(bitboard_t occ, square_t sq);
|
|||||||
|
|
||||||
extern void bitboard_print(const char *title, const bitboard_t bitboard);
|
extern void bitboard_print(const char *title, const bitboard_t bitboard);
|
||||||
extern void bitboard_print_multi(const char *title, const int n, ...);
|
extern void bitboard_print_multi(const char *title, const int n, ...);
|
||||||
extern char *bitboard8_sprint(char *str, const uchar bb8);
|
extern char *bitboard_rank_sprint(char *str, const uchar bb8);
|
||||||
|
|
||||||
#endif /* _BITBOARD_H */
|
#endif /* _BITBOARD_H */
|
||||||
|
@@ -73,7 +73,7 @@ typedef enum {
|
|||||||
/* TODO: revert to macros after bitboard migration */
|
/* TODO: revert to macros after bitboard migration */
|
||||||
static __always_inline square_t sq_make(file_t file, rank_t rank)
|
static __always_inline square_t sq_make(file_t file, rank_t rank)
|
||||||
{
|
{
|
||||||
return (rank << 6) + file;
|
return (rank << 3) + file;
|
||||||
}
|
}
|
||||||
static __always_inline file_t sq_file(square_t square)
|
static __always_inline file_t sq_file(square_t square)
|
||||||
{
|
{
|
||||||
@@ -81,7 +81,7 @@ static __always_inline file_t sq_file(square_t square)
|
|||||||
}
|
}
|
||||||
static __always_inline rank_t sq_rank(square_t square)
|
static __always_inline rank_t sq_rank(square_t square)
|
||||||
{
|
{
|
||||||
return square >> 6;
|
return square >> 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sq_ok(sq) ((sq) >= A1 && (sq) <= H8)
|
#define sq_ok(sq) ((sq) >= A1 && (sq) <= H8)
|
||||||
|
@@ -47,6 +47,8 @@ typedef enum {
|
|||||||
#define MIDDLEGAME 1
|
#define MIDDLEGAME 1
|
||||||
#define ENDGAME 2
|
#define ENDGAME 2
|
||||||
|
|
||||||
|
/* forward defs */
|
||||||
|
typedef struct _pos_s pos_t;
|
||||||
/* bitboard
|
/* bitboard
|
||||||
*/
|
*/
|
||||||
//typedef u64 bitboard_t;
|
//typedef u64 bitboard_t;
|
||||||
|
101
src/fen.c
101
src/fen.c
@@ -21,10 +21,11 @@
|
|||||||
#include <bug.h>
|
#include <bug.h>
|
||||||
|
|
||||||
#include "chessdefs.h"
|
#include "chessdefs.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "piece.h"
|
||||||
|
#include "bitboard.h"
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
#include "fen.h"
|
#include "fen.h"
|
||||||
#include "piece.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
/* FEN description:
|
/* FEN description:
|
||||||
* 1 : pieces on board (no space allowed):
|
* 1 : pieces on board (no space allowed):
|
||||||
@@ -59,6 +60,90 @@ static const char *castle_str = "KQkq";
|
|||||||
|
|
||||||
#define SKIP_BLANK(p) for(;isspace(*(p)); (p)++)
|
#define SKIP_BLANK(p) for(;isspace(*(p)); (p)++)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fen_test(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)
|
||||||
|
*
|
||||||
|
* @return: 0 if OK, 1 if OK after fix, -1 if fatal issue.
|
||||||
|
*/
|
||||||
|
static int fen_test(pos_t *pos)
|
||||||
|
{
|
||||||
|
char *colstr[2] = { "white", "black"};
|
||||||
|
int error = 0, warning = 0;
|
||||||
|
|
||||||
|
/* en passant, depends on who plays next */
|
||||||
|
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;
|
||||||
|
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")) {
|
||||||
|
printf("ep5=%o ep6=%o ep7=%o\n", sq_make(epfile, rank5),
|
||||||
|
sq_make(epfile, rank6), sq_make(epfile, rank6));
|
||||||
|
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 */
|
||||||
|
/* where K and R should be for valid castle flag */
|
||||||
|
bitboard_t k = bb_sq[sq_make(FILE_E, rank1)];
|
||||||
|
bitboard_t r_k = bb_sq[sq_make(FILE_H, rank1)];
|
||||||
|
bitboard_t r_q = bb_sq[sq_make(FILE_A, rank1)];
|
||||||
|
|
||||||
|
/* where they are */
|
||||||
|
bitboard_t kings = pos->bb[color][KING];
|
||||||
|
bitboard_t rooks = pos->bb[color][ROOK];
|
||||||
|
castle_rights_t castle_k = color == WHITE? CASTLE_WK: CASTLE_BK;
|
||||||
|
castle_rights_t castle_q = color == WHITE? CASTLE_WQ: CASTLE_BQ;
|
||||||
|
if (pos->castle & castle_k) {
|
||||||
|
if (warn(!(k & kings && r_k & rooks),
|
||||||
|
"fen warn: wrong %s short castling K or R position (fixed)\n",
|
||||||
|
colstr[color])) {
|
||||||
|
warning++;
|
||||||
|
pos->castle &= ~castle_k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pos->castle & castle_q) {
|
||||||
|
if (warn(!(k & kings && r_q & rooks),
|
||||||
|
"fen warn: wrong %s long castling K or R position (fixed)\n",
|
||||||
|
colstr[color])) {
|
||||||
|
warning++;
|
||||||
|
pos->castle &= ~castle_q;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* startpos - create a game start position
|
* startpos - create a game start position
|
||||||
* @pos: a position pointer or NULL
|
* @pos: a position pointer or NULL
|
||||||
@@ -92,7 +177,6 @@ pos_t *fen2pos(pos_t *pos, const char *fen)
|
|||||||
pos_t tmppos;
|
pos_t tmppos;
|
||||||
|
|
||||||
pos_clear(&tmppos);
|
pos_clear(&tmppos);
|
||||||
|
|
||||||
/* 1) get piece placement information
|
/* 1) get piece placement information
|
||||||
*/
|
*/
|
||||||
for (rank = 7, file = 0; *cur && !isspace(*cur); ++cur) {
|
for (rank = 7, file = 0; *cur && !isspace(*cur); ++cur) {
|
||||||
@@ -142,7 +226,6 @@ pos_t *fen2pos(pos_t *pos, const char *fen)
|
|||||||
|
|
||||||
/* 4) en passant
|
/* 4) en passant
|
||||||
*/
|
*/
|
||||||
tmppos.en_passant = 0;
|
|
||||||
if (*cur == '-') {
|
if (*cur == '-') {
|
||||||
cur++;
|
cur++;
|
||||||
} else {
|
} else {
|
||||||
@@ -175,9 +258,11 @@ end:
|
|||||||
err_line, err_pos, err_char, err_char)) {
|
err_line, err_pos, err_char, err_char)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!pos)
|
if (fen_test(&tmppos) >= 0) {
|
||||||
pos = pos_new();
|
if (!pos)
|
||||||
*pos = tmppos;
|
pos = pos_new();
|
||||||
|
*pos = tmppos;
|
||||||
|
}
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +325,7 @@ char *pos2fen(const pos_t *pos, char *fen)
|
|||||||
|
|
||||||
/* 4) en passant
|
/* 4) en passant
|
||||||
*/
|
*/
|
||||||
if (!pos->en_passant) {
|
if (pos->en_passant == SQUARE_NONE) {
|
||||||
fen[cur++] = '-';
|
fen[cur++] = '-';
|
||||||
} else {
|
} else {
|
||||||
fen[cur++] = FILE2C(sq_file(pos->en_passant));
|
fen[cur++] = FILE2C(sq_file(pos->en_passant));
|
||||||
|
17
src/move.h
17
src/move.h
@@ -34,7 +34,6 @@
|
|||||||
*/
|
*/
|
||||||
#define move_t u32
|
#define move_t u32
|
||||||
|
|
||||||
#define M_
|
|
||||||
/* 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 */
|
||||||
@@ -88,16 +87,16 @@ typedef struct {
|
|||||||
int pseudo_moves_castle(pos_t *pos, bool color, bool doit, bool do_king);
|
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);
|
||||||
//int pseudo_moves_pawn(pos_t *pos, piece_list_t *piece, bool doit);
|
//int pseudo_moves_pawn(pos_t *pos, piece_list_t *piece, bool doit);
|
||||||
int moves_gen(pos_t *pos, bool color, bool doit, bool do_king);
|
//extern int moves_gen(pos_t *pos, bool color, bool doit, bool do_king);
|
||||||
int moves_gen_king_moves(pos_t *pos, bool color, bool doit);
|
//extern int moves_gen_king_moves(pos_t *pos, bool color, bool doit);
|
||||||
|
|
||||||
void moves_sort(pos_t *pos);
|
//extern void moves_sort(pos_t *pos);
|
||||||
void moves_gen_eval_sort(pos_t *pos);
|
//extern void moves_gen_eval_sort(pos_t *pos);
|
||||||
|
|
||||||
void moves_gen_all(pos_t *pos);
|
//extern void moves_gen_all(pos_t *pos);
|
||||||
void moves_gen_all_nomoves(pos_t *pos);
|
//extern void moves_gen_all_nomoves(pos_t *pos);
|
||||||
|
|
||||||
pos_t *move_do(pos_t *pos, move_t *move);
|
//extern pos_t *move_do(pos_t *pos, move_t *move);
|
||||||
void move_undo(pos_t *pos, move_t *move);
|
//extern void move_undo(pos_t *pos, move_t *move);
|
||||||
|
|
||||||
#endif /* MOVE_H */
|
#endif /* MOVE_H */
|
||||||
|
@@ -112,7 +112,7 @@ pos_t *pos_clear(pos_t *pos)
|
|||||||
pos->turn = 0;
|
pos->turn = 0;
|
||||||
pos->clock_50 = 0;
|
pos->clock_50 = 0;
|
||||||
pos->plycount = 0;
|
pos->plycount = 0;
|
||||||
pos->en_passant = 0;
|
pos->en_passant = SQUARE_NONE;
|
||||||
pos->castle = 0;
|
pos->castle = 0;
|
||||||
memset(pos->board, 0, sizeof(pos->board));
|
memset(pos->board, 0, sizeof(pos->board));
|
||||||
//pos->curmove = 0;
|
//pos->curmove = 0;
|
||||||
@@ -237,7 +237,7 @@ void raw_board_print(const pos_t *pos)
|
|||||||
|
|
||||||
for (rank_t r = RANK_8; r >= RANK_1; --r) {
|
for (rank_t r = RANK_8; r >= RANK_1; --r) {
|
||||||
for (file_t f = FILE_A; f <= FILE_H; ++f)
|
for (file_t f = FILE_A; f <= FILE_H; ++f)
|
||||||
printf("%02x ", pos->board[sq_make(f, r)]);
|
printf("%02o ", pos->board[sq_make(f, r)]);
|
||||||
printf(" \n");
|
printf(" \n");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
#include "piece.h"
|
#include "piece.h"
|
||||||
#include "move.h"
|
#include "move.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct _pos_s {
|
||||||
u64 node_count; /* evaluated nodes */
|
u64 node_count; /* evaluated nodes */
|
||||||
int turn; /* WHITE or BLACK */
|
int turn; /* WHITE or BLACK */
|
||||||
u16 clock_50;
|
u16 clock_50;
|
||||||
@@ -64,8 +64,8 @@ static inline void pos_set_sq(pos_t *pos, square_t square, piece_t piece)
|
|||||||
color_t color = COLOR(piece);
|
color_t color = COLOR(piece);
|
||||||
piece_type_t type = PIECE(piece);
|
piece_type_t type = PIECE(piece);
|
||||||
pos->board[square] = piece;
|
pos->board[square] = piece;
|
||||||
pos->bb[color][type] |= 1 << square;
|
pos->bb[color][type] |= mask(square);
|
||||||
pos->bb[color][ALL_PIECES] |= 1 << square;
|
pos->bb[color][ALL_PIECES] |= mask(square);
|
||||||
if (type == KING)
|
if (type == KING)
|
||||||
pos->king[color] = square;
|
pos->king[color] = square;
|
||||||
}
|
}
|
||||||
@@ -83,8 +83,8 @@ static inline void pos_clr_sq(pos_t *pos, square_t square)
|
|||||||
piece_type_t type = PIECE(piece);
|
piece_type_t type = PIECE(piece);
|
||||||
color_t color = COLOR(piece);
|
color_t color = COLOR(piece);
|
||||||
pos->board[square] = EMPTY;
|
pos->board[square] = EMPTY;
|
||||||
pos->bb[color][type] &= ~(1 << square);
|
pos->bb[color][type] &= ~mask(square);
|
||||||
pos->bb[color][ALL_PIECES] &= ~(1 << square);
|
pos->bb[color][ALL_PIECES] &= ~mask(square);
|
||||||
}
|
}
|
||||||
|
|
||||||
//void bitboard_print(bitboard_t bb, char *title);
|
//void bitboard_print(bitboard_t bb, char *title);
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
|
|
||||||
|
#include "../src/chessdefs.h"
|
||||||
|
#include "../src/bitboard.h"
|
||||||
#include "../src/position.h"
|
#include "../src/position.h"
|
||||||
#include "../src/fen.h"
|
#include "../src/fen.h"
|
||||||
|
|
||||||
@@ -14,6 +16,7 @@ int main(int ac, char**av)
|
|||||||
|
|
||||||
//debug_init(5, stderr, true);
|
//debug_init(5, stderr, true);
|
||||||
//pos_pool_init();
|
//pos_pool_init();
|
||||||
|
bitboard_init();
|
||||||
pos = pos_new();
|
pos = pos_new();
|
||||||
if (ac == 1) {
|
if (ac == 1) {
|
||||||
fen = startfen;
|
fen = startfen;
|
||||||
|
Reference in New Issue
Block a user