Improve move gen, delete ling pos, 3 steps moves generation
This commit is contained in:
@@ -30,11 +30,11 @@
|
|||||||
#include "fen.h"
|
#include "fen.h"
|
||||||
#include "eval.h"
|
#include "eval.h"
|
||||||
|
|
||||||
typedef struct {
|
struct command {
|
||||||
char *name; /* User printable name */
|
char *name; /* User printable name */
|
||||||
int (*func)(pos_t *, char *); /* function doing the job */
|
int (*func)(pos_t *, char *); /* function doing the job */
|
||||||
char *doc; /* function doc */
|
char *doc; /* function doc */
|
||||||
} COMMAND;
|
};
|
||||||
|
|
||||||
/* readline example inspired by :
|
/* readline example inspired by :
|
||||||
* - https://thoughtbot.com/blog/tab-completion-in-gnu-readline
|
* - https://thoughtbot.com/blog/tab-completion-in-gnu-readline
|
||||||
@@ -45,7 +45,7 @@ char *commands_generator(const char *, int);
|
|||||||
char *escape(const char *);
|
char *escape(const char *);
|
||||||
int quote_detector(char *, int);
|
int quote_detector(char *, int);
|
||||||
int execute_line (pos_t *, char *line);
|
int execute_line (pos_t *, char *line);
|
||||||
COMMAND *find_command (char *);
|
struct command *find_command (char *);
|
||||||
char *stripwhite (char *string);
|
char *stripwhite (char *string);
|
||||||
|
|
||||||
/* The names of functions that actually do the manipulation. */
|
/* The names of functions that actually do the manipulation. */
|
||||||
@@ -63,7 +63,7 @@ int do_move(pos_t *, char*);
|
|||||||
int do_quit(pos_t *, char*);
|
int do_quit(pos_t *, char*);
|
||||||
int do_debug(pos_t *, char*);
|
int do_debug(pos_t *, char*);
|
||||||
|
|
||||||
COMMAND commands[] = {
|
struct command commands[] = {
|
||||||
{ "help", do_help, "Display this text" },
|
{ "help", do_help, "Display this text" },
|
||||||
{ "?", do_help, "Synonym for 'help'" },
|
{ "?", do_help, "Synonym for 'help'" },
|
||||||
{ "fen", do_fen, "Set position to FEN" },
|
{ "fen", do_fen, "Set position to FEN" },
|
||||||
@@ -190,7 +190,7 @@ int quote_detector(char *line, int index)
|
|||||||
int execute_line(pos_t *pos, char *line)
|
int execute_line(pos_t *pos, char *line)
|
||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
COMMAND *command;
|
struct command *command;
|
||||||
char *word;
|
char *word;
|
||||||
|
|
||||||
/* Isolate the command word. */
|
/* Isolate the command word. */
|
||||||
@@ -224,7 +224,7 @@ int execute_line(pos_t *pos, char *line)
|
|||||||
|
|
||||||
/* Look up NAME as the name of a command, and return a pointer to that
|
/* Look up NAME as the name of a command, and return a pointer to that
|
||||||
command. Return a NULL pointer if NAME isn't a command name. */
|
command. Return a NULL pointer if NAME isn't a command name. */
|
||||||
COMMAND *find_command(char *name)
|
struct command *find_command(char *name)
|
||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
@@ -232,7 +232,7 @@ COMMAND *find_command(char *name)
|
|||||||
if (strcmp(name, commands[i].name) == 0)
|
if (strcmp(name, commands[i].name) == 0)
|
||||||
return &commands[i];
|
return &commands[i];
|
||||||
|
|
||||||
return (COMMAND *)NULL;
|
return (struct command *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Strip whitespace from the start and end of STRING. Return a pointer
|
/* Strip whitespace from the start and end of STRING. Return a pointer
|
||||||
@@ -292,15 +292,14 @@ int do_pos(pos_t *pos, __unused char *arg)
|
|||||||
int do_genmoves(pos_t *pos, __unused char *arg)
|
int do_genmoves(pos_t *pos, __unused char *arg)
|
||||||
{
|
{
|
||||||
log_f(1, "%s\n", arg);
|
log_f(1, "%s\n", arg);
|
||||||
moves_gen(pos, OPPONENT(pos->turn), false);
|
moves_gen_all(pos);
|
||||||
moves_gen(pos, pos->turn, true);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_prmoves(pos_t *pos, __unused char *arg)
|
int do_prmoves(pos_t *pos, __unused char *arg)
|
||||||
{
|
{
|
||||||
log_f(1, "%s\n", arg);
|
log_f(1, "%s\n", arg);
|
||||||
moves_print(pos, M_PR_SEPARATE);
|
moves_print(pos, M_PR_SEPARATE | M_PR_NUM);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
src/eval.c
11
src/eval.c
@@ -40,12 +40,12 @@ inline eval_t eval_material(pos_t *pos, bool color)
|
|||||||
|
|
||||||
inline eval_t eval_mobility(pos_t *pos, bool color)
|
inline eval_t eval_mobility(pos_t *pos, bool color)
|
||||||
{
|
{
|
||||||
return popcount64(pos->controlled[color]);
|
return pos->mobility[color];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline eval_t eval_square_control(pos_t *pos, bool color)
|
inline eval_t eval_square_control(pos_t *pos, bool color)
|
||||||
{
|
{
|
||||||
return pos->mobility[color];
|
return popcount64(pos->controlled[color]);
|
||||||
}
|
}
|
||||||
|
|
||||||
eval_t eval(pos_t *pos)
|
eval_t eval(pos_t *pos)
|
||||||
@@ -114,11 +114,8 @@ int main(int ac, char**av)
|
|||||||
pos_print(pos);
|
pos_print(pos);
|
||||||
pos_pieces_print(pos);
|
pos_pieces_print(pos);
|
||||||
|
|
||||||
moves_gen(pos, OPPONENT(pos->turn), false);
|
moves_gen_all(pos);
|
||||||
//moves_print(pos, M_PR_SEPARATE);
|
|
||||||
//pos_print(pos);
|
|
||||||
//pos_pieces_print(pos);
|
|
||||||
moves_gen(pos, pos->turn, true);
|
|
||||||
pos_print(pos);
|
pos_print(pos);
|
||||||
moves_print(pos, M_PR_SEPARATE);
|
moves_print(pos, M_PR_SEPARATE);
|
||||||
res = eval(pos);
|
res = eval(pos);
|
||||||
|
161
src/move.c
161
src/move.c
@@ -62,7 +62,7 @@ void moves_pool_stats()
|
|||||||
pool_stats(moves_pool);
|
pool_stats(moves_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
int move_print(move_t *move, move_flags_t flags)
|
int move_print(int movenum, move_t *move, move_flags_t flags)
|
||||||
{
|
{
|
||||||
if (flags & M_PR_CAPT && !(move->flags & M_CAPTURE)) {
|
if (flags & M_PR_CAPT && !(move->flags & M_CAPTURE)) {
|
||||||
# ifdef DEBUG_MOVE
|
# ifdef DEBUG_MOVE
|
||||||
@@ -76,6 +76,8 @@ int move_print(move_t *move, move_flags_t flags)
|
|||||||
# endif
|
# endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (flags & M_PR_NUM)
|
||||||
|
printf("%d:", movenum);
|
||||||
if (move->flags & M_CASTLE_K) {
|
if (move->flags & M_CASTLE_K) {
|
||||||
printf("O-O");
|
printf("O-O");
|
||||||
goto end;
|
goto end;
|
||||||
@@ -110,26 +112,30 @@ void moves_print(pos_t *pos, move_flags_t flags)
|
|||||||
{
|
{
|
||||||
struct list_head *p_cur, *tmp;
|
struct list_head *p_cur, *tmp;
|
||||||
move_t *move;
|
move_t *move;
|
||||||
move_flags_t details = flags & M_PR_LONG;
|
//move_flags_t details = flags & M_PR_LONG;
|
||||||
|
int movenum;
|
||||||
|
|
||||||
for (int color=WHITE; color <= BLACK; ++color) {
|
for (int color=WHITE; color <= BLACK; ++color) {
|
||||||
int verif = 0;
|
int verif = 0;
|
||||||
printf("%s pseudo-moves:\n\t", color == WHITE? "White": "Black");
|
printf("%s pseudo-moves:\n\t", color == WHITE? "White": "Black");
|
||||||
if (! (flags & M_PR_SEPARATE)) {
|
if (! (flags & M_PR_SEPARATE)) {
|
||||||
|
movenum = 1;
|
||||||
list_for_each_safe(p_cur, tmp, &pos->moves[color]) {
|
list_for_each_safe(p_cur, tmp, &pos->moves[color]) {
|
||||||
move = list_entry(p_cur, move_t, list);
|
move = list_entry(p_cur, move_t, list);
|
||||||
verif += move_print(move, details);
|
verif += move_print(movenum++, move, flags);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("captures: ");
|
printf("captures: ");
|
||||||
|
movenum = 1;
|
||||||
list_for_each_safe(p_cur, tmp, &pos->moves[color]) {
|
list_for_each_safe(p_cur, tmp, &pos->moves[color]) {
|
||||||
move = list_entry(p_cur, move_t, list);
|
move = list_entry(p_cur, move_t, list);
|
||||||
verif += move_print(move, details | M_PR_CAPT);
|
verif += move_print(movenum++, move, flags | M_PR_CAPT);
|
||||||
}
|
}
|
||||||
|
movenum = 1;
|
||||||
printf("\n\tothers : ");
|
printf("\n\tothers : ");
|
||||||
list_for_each_safe(p_cur, tmp, &pos->moves[color]) {
|
list_for_each_safe(p_cur, tmp, &pos->moves[color]) {
|
||||||
move = list_entry(p_cur, move_t, list);
|
move = list_entry(p_cur, move_t, list);
|
||||||
verif += move_print(move, details | M_PR_NCAPT);
|
verif += move_print(movenum++, move, flags | M_PR_NCAPT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n\tTotal moves = %d mobility=%u\n", verif, pos->mobility[color]);
|
printf("\n\tTotal moves = %d mobility=%u\n", verif, pos->mobility[color]);
|
||||||
@@ -250,28 +256,16 @@ static move_t *move_pawn_add(pos_t *pos, piece_t piece, square_t from,
|
|||||||
move_t *move;
|
move_t *move;
|
||||||
piece_t promote;
|
piece_t promote;
|
||||||
unsigned char color = COLOR(piece);
|
unsigned char color = COLOR(piece);
|
||||||
//pos_t *newpos;
|
|
||||||
|
|
||||||
//if (color != pos->turn)
|
|
||||||
// return NULL;
|
|
||||||
if (R88(from) == rank7) { /* promotion */
|
if (R88(from) == rank7) { /* promotion */
|
||||||
for (promote = QUEEN; promote > PAWN; promote >>= 1) {
|
for (promote = QUEEN; promote > PAWN; promote >>= 1) {
|
||||||
if ((move = move_add(pos, piece, from, to))) {
|
if ((move = move_add(pos, piece, from, to))) {
|
||||||
move->flags |= M_PROMOTION;
|
move->flags |= M_PROMOTION;
|
||||||
move->promotion = promote | color;
|
move->promotion = promote | color;
|
||||||
/* fix piece on board and piece list */
|
|
||||||
//newpos = move->newpos;
|
|
||||||
//newpos->board[to].piece = promote|color;
|
|
||||||
//newpos->board[to].s_piece->piece = piece|color;
|
|
||||||
//newpos->board[to].s_piece->value = piece_details[PIECE(piece)].value;
|
|
||||||
|
|
||||||
//piece_del(&newpos->board[from].s_piece);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
move = move_add(pos, piece, from, to);
|
move = move_add(pos, piece, from, to);
|
||||||
//newpos = move->newpos;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return move;
|
return move;
|
||||||
}
|
}
|
||||||
@@ -360,12 +354,6 @@ int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece, bool doit)
|
|||||||
move = move_pawn_add(pos, piece | color , square, pos->en_passant, rank7);
|
move = move_pawn_add(pos, piece | color , square, pos->en_passant, rank7);
|
||||||
move->flags |= M_EN_PASSANT | M_CAPTURE;
|
move->flags |= M_EN_PASSANT | M_CAPTURE;
|
||||||
move->taken = taken;
|
move->taken = taken;
|
||||||
|
|
||||||
/* remove taken pawn from board */
|
|
||||||
//piece_del(&move->newpos->board[t_square].s_piece->list);
|
|
||||||
//move->newpos->board[t_square].piece = 0;
|
|
||||||
//move->newpos->board[t_square].s_piece = NULL;
|
|
||||||
|
|
||||||
pos->mobility[color]++;
|
pos->mobility[color]++;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -403,9 +391,8 @@ int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece, bool doit)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pseudo_moves_castle(pos_t *pos, bool color, bool doit)
|
int pseudo_moves_castle(pos_t *pos, bool color, bool doit, bool doking)
|
||||||
{
|
{
|
||||||
//unsigned char color = pos->turn;
|
|
||||||
board_t *board = pos->board;
|
board_t *board = pos->board;
|
||||||
unsigned char rank1, castle_K, castle_Q;
|
unsigned char rank1, castle_K, castle_Q;
|
||||||
move_t *move = NULL;
|
move_t *move = NULL;
|
||||||
@@ -448,22 +435,15 @@ int pseudo_moves_castle(pos_t *pos, bool color, bool doit)
|
|||||||
# endif
|
# endif
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
if (doking) {
|
||||||
pos->mobility[color]++;
|
pos->mobility[color]++;
|
||||||
count++;
|
count++;
|
||||||
|
}
|
||||||
if (doit) {
|
if (doit) {
|
||||||
move = move_add(pos, board[SQ88(4, rank1)].piece,
|
move = move_add(pos, board[SQ88(4, rank1)].piece,
|
||||||
SQ88(4, rank1), SQ88(6, rank1));
|
SQ88(4, rank1), SQ88(6, rank1));
|
||||||
if (move) {
|
if (move)
|
||||||
//newpos = move->newpos;
|
|
||||||
move->flags |= M_CASTLE_K;
|
move->flags |= M_CASTLE_K;
|
||||||
|
|
||||||
/* move King rook to column F */
|
|
||||||
//newpos->board[SQ88(5, rank1)] = newpos->board[SQ88(7, rank1)];
|
|
||||||
//SETF88(newpos->board[SQ88(5, rank1)].s_piece->square, 5);
|
|
||||||
//newpos->board[SQ88(7, rank1)].piece = 0;
|
|
||||||
//newpos->board[SQ88(7, rank1)].s_piece = NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,29 +461,33 @@ next:
|
|||||||
# endif
|
# endif
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
if (doking) {
|
||||||
pos->mobility[color]++;
|
pos->mobility[color]++;
|
||||||
count++;
|
count++;
|
||||||
|
}
|
||||||
if (doit) {
|
if (doit) {
|
||||||
move = move_add(pos, board[SQ88(4, rank1)].piece,
|
move = move_add(pos, board[SQ88(4, rank1)].piece,
|
||||||
SQ88(4, rank1), SQ88(2, rank1));
|
SQ88(4, rank1), SQ88(2, rank1));
|
||||||
if (move) {
|
if (move)
|
||||||
//newpos = move->newpos;
|
|
||||||
move->flags |= M_CASTLE_Q;
|
move->flags |= M_CASTLE_Q;
|
||||||
/* move King rook to column F */
|
|
||||||
//newpos->board[SQ88(3, rank1)] = newpos->board[SQ88(0, rank1)];
|
|
||||||
//SETF88(newpos->board[SQ88(3, rank1)].s_piece->square, 3);
|
|
||||||
//newpos->board[SQ88(0, rank1)].piece = 0;
|
|
||||||
//newpos->board[SQ88(0, rank1)].s_piece = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* general rule moves for non pawn pieces
|
/**
|
||||||
|
* pseudo_moves_gen() - general move generation for non pawn pieces
|
||||||
|
* @pos: &position
|
||||||
|
* @ppiece: &piece_list structure pointer
|
||||||
|
* @doit: add move to moves list
|
||||||
|
* @doking: count king moves
|
||||||
|
*
|
||||||
|
* Calculate all possible moves for @ppiece.
|
||||||
|
* If @doit is true, add moves to @pos' moves list.
|
||||||
|
* If @doking is true, account king moves (incl. castle) to mobility.
|
||||||
*/
|
*/
|
||||||
int pseudo_moves_gen(pos_t *pos, piece_list_t *ppiece, bool doit)
|
int pseudo_moves_gen(pos_t *pos, piece_list_t *ppiece, bool doit, bool doking)
|
||||||
{
|
{
|
||||||
piece_t piece = PIECE(ppiece->piece);
|
piece_t piece = PIECE(ppiece->piece);
|
||||||
unsigned char color = COLOR(ppiece->piece);
|
unsigned char color = COLOR(ppiece->piece);
|
||||||
@@ -569,9 +553,10 @@ int pseudo_moves_gen(pos_t *pos, piece_list_t *ppiece, bool doit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* we are sure the move is valid : we create move */
|
/* we are sure the move is valid : we create move */
|
||||||
//log_f(2, "piece mobility\n");
|
if (piece != KING || doking) {
|
||||||
pos->mobility[color]++;
|
pos->mobility[color]++;
|
||||||
count++;
|
count++;
|
||||||
|
}
|
||||||
if (doit) {
|
if (doit) {
|
||||||
//move = move_add(pos, ppiece->piece, square, new);
|
//move = move_add(pos, ppiece->piece, square, new);
|
||||||
move_add(pos, ppiece->piece, square, new);
|
move_add(pos, ppiece->piece, square, new);
|
||||||
@@ -596,7 +581,18 @@ int pseudo_moves_gen(pos_t *pos, piece_list_t *ppiece, bool doit)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int moves_gen(pos_t *pos, bool color, bool doit)
|
/**
|
||||||
|
* moves_gen() - move generation for one color
|
||||||
|
* @pos: &position
|
||||||
|
* @color: side
|
||||||
|
* @doit: add move to moves list
|
||||||
|
* @doking: count king moves
|
||||||
|
*
|
||||||
|
* Calculate all possible moves for @color.
|
||||||
|
* If @doit is true, add moves to @pos' moves list.
|
||||||
|
* If @doking is true, account king moves (incl. castle) to mobility.
|
||||||
|
*/
|
||||||
|
int moves_gen(pos_t *pos, bool color, bool doit, bool doking)
|
||||||
{
|
{
|
||||||
struct list_head *p_cur, *tmp, *piece_list;
|
struct list_head *p_cur, *tmp, *piece_list;
|
||||||
piece_list_t *piece;
|
piece_list_t *piece;
|
||||||
@@ -609,11 +605,11 @@ int moves_gen(pos_t *pos, bool color, bool doit)
|
|||||||
|
|
||||||
pos->mobility[color] = 0;
|
pos->mobility[color] = 0;
|
||||||
pos->controlled[color] = 0;
|
pos->controlled[color] = 0;
|
||||||
count += pseudo_moves_castle(pos, color, doit);
|
count += pseudo_moves_castle(pos, color, doit, doking);
|
||||||
list_for_each_safe(p_cur, tmp, piece_list) {
|
list_for_each_safe(p_cur, tmp, piece_list) {
|
||||||
piece = list_entry(p_cur, piece_list_t, list);
|
piece = list_entry(p_cur, piece_list_t, list);
|
||||||
if (PIECE(piece->piece) != PAWN)
|
if (PIECE(piece->piece) != PAWN)
|
||||||
count += pseudo_moves_gen(pos, piece, doit);
|
count += pseudo_moves_gen(pos, piece, doit, doking);
|
||||||
else
|
else
|
||||||
count += pseudo_moves_pawn(pos, piece, doit);
|
count += pseudo_moves_pawn(pos, piece, doit);
|
||||||
|
|
||||||
@@ -622,6 +618,40 @@ int moves_gen(pos_t *pos, bool color, bool doit)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* moves_gen_king_moves() - adjust king mobility
|
||||||
|
* @pos: &position
|
||||||
|
* @color: king color
|
||||||
|
* @doit: add move to moves list
|
||||||
|
*
|
||||||
|
* Compute the number of king moves (incl. castle), after opponent controlled
|
||||||
|
* are known.
|
||||||
|
* If @doit is true, add moves to @pos' moves list.
|
||||||
|
*
|
||||||
|
* @return: The number of possible king moves.
|
||||||
|
*/
|
||||||
|
int moves_gen_king_moves(pos_t *pos, bool color, bool doit)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
piece_list_t *king = list_first_entry(&pos->pieces[color], piece_list_t, list);
|
||||||
|
count = pseudo_moves_castle(pos, king, doit, true);
|
||||||
|
count += pseudo_moves_gen(pos, king, doit, true);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* moves_gen_all() - calculate all moves
|
||||||
|
* @pos: &position
|
||||||
|
*
|
||||||
|
* Compute pseudo moves for both sides.
|
||||||
|
*/
|
||||||
|
void moves_gen_all(pos_t *pos)
|
||||||
|
{
|
||||||
|
moves_gen(pos, OPPONENT(pos->turn), false, false);
|
||||||
|
moves_gen(pos, pos->turn, false, true);
|
||||||
|
moves_gen_king_moves(pos, OPPONENT(pos->turn), true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* move_do() - execute move in a duplicated position.
|
* move_do() - execute move in a duplicated position.
|
||||||
* @pos: &pos_t struct on which move will be applied
|
* @pos: &pos_t struct on which move will be applied
|
||||||
@@ -632,7 +662,7 @@ pos_t *move_do(pos_t *pos, move_t *move)
|
|||||||
{
|
{
|
||||||
# ifdef DEBUG_MOVE
|
# ifdef DEBUG_MOVE
|
||||||
log_f(3, "++++++++++");
|
log_f(3, "++++++++++");
|
||||||
move_print(move, 0);
|
move_print(0, move, 0);
|
||||||
log(3, "\n");
|
log(3, "\n");
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@@ -650,14 +680,14 @@ pos_t *move_do(pos_t *pos, move_t *move)
|
|||||||
else
|
else
|
||||||
new->clock_50++;
|
new->clock_50++;
|
||||||
|
|
||||||
if (move->taken) { /* capture */
|
if (move->flags & M_CAPTURE) { /* capture */
|
||||||
if (!(move->flags & M_EN_PASSANT)) {
|
if (!(move->flags & M_EN_PASSANT)) {
|
||||||
piece_del(&new->board[to].s_piece->list);
|
piece_del(&new->board[to].s_piece->list);
|
||||||
new->board[to].piece = 0;
|
new->board[to].piece = 0;
|
||||||
new->occupied[OPPONENT(color)] ^= SQ88_2_BB(to);
|
new->occupied[OPPONENT(color)] ^= SQ88_2_BB(to);
|
||||||
new->bb[OPPONENT(color)][PIECETOBB(piece)] ^= SQ88_2_BB(to);
|
new->bb[OPPONENT(color)][PIECETOBB(piece)] ^= SQ88_2_BB(to);
|
||||||
} else {
|
} else {
|
||||||
unsigned char ep_file = F88(pos->en_passant);
|
uchar ep_file = F88(pos->en_passant);
|
||||||
square_t ep_grab = color == WHITE ? SQ88(ep_file, 4): SQ88(ep_file, 3);
|
square_t ep_grab = color == WHITE ? SQ88(ep_file, 4): SQ88(ep_file, 3);
|
||||||
log_f(1, "en-passant=%d,%d\n", ep_file, color == WHITE ? 4 : 3);
|
log_f(1, "en-passant=%d,%d\n", ep_file, color == WHITE ? 4 : 3);
|
||||||
piece_del(&new->board[ep_grab].s_piece->list);
|
piece_del(&new->board[ep_grab].s_piece->list);
|
||||||
@@ -666,6 +696,30 @@ pos_t *move_do(pos_t *pos, move_t *move)
|
|||||||
new->bb[OPPONENT(color)][PIECETOBB(piece)] ^= SQ88_2_BB(ep_grab);
|
new->bb[OPPONENT(color)][PIECETOBB(piece)] ^= SQ88_2_BB(ep_grab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (move->flags & M_CASTLE_Q) {
|
||||||
|
uchar row = R88(from);
|
||||||
|
square_t rook_from = SQ88(0, row);
|
||||||
|
square_t rook_to = SQ88(3, row);
|
||||||
|
new->board[rook_to] = new->board[rook_from];
|
||||||
|
new->board[rook_to].s_piece->square = rook_to;
|
||||||
|
new->occupied[color] ^= SQ88_2_BB(rook_from);
|
||||||
|
new->occupied[color] |= SQ88_2_BB(rook_to);
|
||||||
|
new->bb[color][PIECETOBB(BB_ROOK)] ^= SQ88_2_BB(rook_from);
|
||||||
|
new->bb[color][PIECETOBB(BB_ROOK)] |= SQ88_2_BB(rook_to);
|
||||||
|
new->board[rook_from].piece = 0;
|
||||||
|
new->board[rook_from].s_piece = NULL;
|
||||||
|
} else if (move->flags & M_CASTLE_K) {
|
||||||
|
uchar row = R88(from);
|
||||||
|
square_t rook_from = SQ88(7, row);
|
||||||
|
square_t rook_to = SQ88(5, row);
|
||||||
|
new->board[rook_to] = new->board[rook_from];
|
||||||
|
new->board[rook_to].s_piece->square = rook_to;
|
||||||
|
new->occupied[color] ^= SQ88_2_BB(rook_from);
|
||||||
|
new->occupied[color] |= SQ88_2_BB(rook_to);
|
||||||
|
new->bb[color][PIECETOBB(BB_ROOK)] ^= SQ88_2_BB(rook_from);
|
||||||
|
new->bb[color][PIECETOBB(BB_ROOK)] |= SQ88_2_BB(rook_to);
|
||||||
|
new->board[rook_from].piece = 0;
|
||||||
|
new->board[rook_from].s_piece = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
new->board[to] = new->board[from];
|
new->board[to] = new->board[from];
|
||||||
@@ -708,8 +762,7 @@ int main(int ac, char**av)
|
|||||||
fen2pos(pos, av[1]);
|
fen2pos(pos, av[1]);
|
||||||
}
|
}
|
||||||
//printf("turn = %d opponent = %d\n", pos->turn, OPPONENT(pos->turn));
|
//printf("turn = %d opponent = %d\n", pos->turn, OPPONENT(pos->turn));
|
||||||
moves_gen(pos, WHITE, false);
|
moves_gen_all(pos);
|
||||||
moves_gen(pos, BLACK, false);
|
|
||||||
pos_print(pos);
|
pos_print(pos);
|
||||||
pos_pieces_print(pos);
|
pos_pieces_print(pos);
|
||||||
moves_print(pos, M_PR_SEPARATE);
|
moves_print(pos, M_PR_SEPARATE);
|
||||||
|
15
src/move.h
15
src/move.h
@@ -32,10 +32,11 @@ typedef unsigned char move_flags_t;
|
|||||||
|
|
||||||
/* moves_print flags
|
/* moves_print flags
|
||||||
*/
|
*/
|
||||||
#define M_PR_SEPARATE 0x40 /* separate capture/non capture */
|
|
||||||
#define M_PR_LONG 0x80
|
|
||||||
#define M_PR_CAPT 0x01
|
#define M_PR_CAPT 0x01
|
||||||
#define M_PR_NCAPT 0x02
|
#define M_PR_NCAPT 0x02
|
||||||
|
#define M_PR_NUM 0x04
|
||||||
|
#define M_PR_SEPARATE 0x40 /* separate captures */
|
||||||
|
#define M_PR_LONG 0x80
|
||||||
|
|
||||||
typedef struct move_s {
|
typedef struct move_s {
|
||||||
piece_t piece;
|
piece_t piece;
|
||||||
@@ -49,16 +50,18 @@ typedef struct move_s {
|
|||||||
|
|
||||||
pool_t *moves_pool_init();
|
pool_t *moves_pool_init();
|
||||||
void moves_pool_stats();
|
void moves_pool_stats();
|
||||||
int move_print(move_t *move, move_flags_t flags);
|
int move_print(int movenum, move_t *move, move_flags_t flags);
|
||||||
void moves_print(pos_t *move, move_flags_t flags);
|
void moves_print(pos_t *move, move_flags_t flags);
|
||||||
|
|
||||||
void move_del(struct list_head *ptr);
|
void move_del(struct list_head *ptr);
|
||||||
int moves_del(pos_t *pos);
|
int moves_del(pos_t *pos);
|
||||||
|
|
||||||
int pseudo_moves_castle(pos_t *pos, bool color, bool doit);
|
int pseudo_moves_castle(pos_t *pos, bool color, bool doit, bool doking);
|
||||||
int pseudo_moves_gen(pos_t *pos, piece_list_t *piece, bool doit);
|
int pseudo_moves_gen(pos_t *pos, piece_list_t *piece, bool doit, bool doking);
|
||||||
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);
|
int moves_gen(pos_t *pos, bool color, bool doit, bool doking);
|
||||||
|
int moves_gen_king_moves(pos_t *pos, bool color, bool doit);
|
||||||
|
void moves_gen_all(pos_t *pos);
|
||||||
|
|
||||||
pos_t *move_do(pos_t *pos, move_t *move);
|
pos_t *move_do(pos_t *pos, move_t *move);
|
||||||
void move_undo(pos_t *pos, move_t *move);
|
void move_undo(pos_t *pos, move_t *move);
|
||||||
|
@@ -74,8 +74,11 @@ piece_list_t *piece_add(pos_t *pos, piece_t piece, square_t square)
|
|||||||
P_NAME(piece), FILE2C(F88(square)), RANK2C(R88(square)));
|
P_NAME(piece), FILE2C(F88(square)), RANK2C(R88(square)));
|
||||||
# endif
|
# endif
|
||||||
if ((new = pool_get(pieces_pool))) {
|
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]);
|
list_add_tail(&new->list, &pos->pieces[color]);
|
||||||
//color? &pos->pieces_black: &pos->pieces_white);
|
|
||||||
new->piece = piece;
|
new->piece = piece;
|
||||||
new->square = square;
|
new->square = square;
|
||||||
new->castle = 0;
|
new->castle = 0;
|
||||||
|
@@ -72,6 +72,9 @@ void pos_print(pos_t *pos)
|
|||||||
int rank, file;
|
int rank, file;
|
||||||
piece_t piece;
|
piece_t piece;
|
||||||
board_t *board = pos->board;
|
board_t *board = pos->board;
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
printf(" +---+---+---+---+---+---+---+---+\n");
|
printf(" +---+---+---+---+---+---+---+---+\n");
|
||||||
for (rank = 7; rank >= 0; --rank) {
|
for (rank = 7; rank >= 0; --rank) {
|
||||||
@@ -85,10 +88,10 @@ void pos_print(pos_t *pos)
|
|||||||
printf(" A B C D E F G H\n\n");
|
printf(" A B C D E F G H\n\n");
|
||||||
printf("Turn: %s.\n", IS_WHITE(pos->turn) ? "white" : "black");
|
printf("Turn: %s.\n", IS_WHITE(pos->turn) ? "white" : "black");
|
||||||
printf("Kings: W:%c%c B:%c%c\n",
|
printf("Kings: W:%c%c B:%c%c\n",
|
||||||
FILE2C(F88(pos->king[WHITE])),
|
FILE2C(F88(wk->square)),
|
||||||
RANK2C(R88(pos->king[WHITE])),
|
RANK2C(R88(wk->square)),
|
||||||
FILE2C(F88(pos->king[BLACK])),
|
FILE2C(F88(bk->square)),
|
||||||
RANK2C(R88(pos->king[BLACK])));
|
RANK2C(R88(bk->square)));
|
||||||
printf("Possible en-passant: [%#x] ", pos->en_passant);
|
printf("Possible en-passant: [%#x] ", pos->en_passant);
|
||||||
if (pos->en_passant == 0)
|
if (pos->en_passant == 0)
|
||||||
printf("None.\n");
|
printf("None.\n");
|
||||||
@@ -143,8 +146,6 @@ pos_t *pos_clear(pos_t *pos)
|
|||||||
pos->curmove = 0;
|
pos->curmove = 0;
|
||||||
pos->eval = 0;
|
pos->eval = 0;
|
||||||
pos->en_passant = 0;
|
pos->en_passant = 0;
|
||||||
pos->king[WHITE] = 0;
|
|
||||||
pos->king[BLACK] = 0;
|
|
||||||
pos->occupied[WHITE] = 0;
|
pos->occupied[WHITE] = 0;
|
||||||
pos->occupied[BLACK] = 0;
|
pos->occupied[BLACK] = 0;
|
||||||
for (int color=0; color<2; ++color)
|
for (int color=0; color<2; ++color)
|
||||||
|
@@ -15,11 +15,11 @@
|
|||||||
#define POSITION_H
|
#define POSITION_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "board.h"
|
|
||||||
#include <pool.h>
|
#include <pool.h>
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
#include <bits.h>
|
#include <bits.h>
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
#include "chessdefs.h"
|
#include "chessdefs.h"
|
||||||
|
|
||||||
typedef struct pos_s {
|
typedef struct pos_s {
|
||||||
@@ -31,13 +31,12 @@ typedef struct pos_s {
|
|||||||
board_t board[BOARDSIZE];
|
board_t board[BOARDSIZE];
|
||||||
|
|
||||||
square_t en_passant;
|
square_t en_passant;
|
||||||
square_t king[2]; /* obsolete by bb array */
|
|
||||||
|
|
||||||
bitboard_t bb[2][BB_END]; /* use: pieces[BLACK][BB_PAWN] */
|
bitboard_t bb[2][BB_END]; /* use: pieces[BLACK][BB_PAWN] */
|
||||||
bitboard_t occupied[2]; /* OR of bb[COLOR][x] */
|
bitboard_t occupied[2]; /* OR of bb[COLOR][x] */
|
||||||
bitboard_t controlled[2];
|
bitboard_t controlled[2];
|
||||||
u16 mobility[2];
|
u16 mobility[2];
|
||||||
struct list_head pieces[2];
|
struct list_head pieces[2]; /* pieces list, King is first */
|
||||||
struct list_head moves[2];
|
struct list_head moves[2];
|
||||||
} pos_t;
|
} pos_t;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user