Add pos negamax function
This commit is contained in:
1
Makefile
1
Makefile
@@ -61,6 +61,7 @@ CPPFLAGS += -DDEBUG_FEN # FEN decoding
|
|||||||
CPPFLAGS += -DDEBUG_MOVE # move generation
|
CPPFLAGS += -DDEBUG_MOVE # move generation
|
||||||
CPPFLAGS += -DDEBUG_EVAL # eval functions
|
CPPFLAGS += -DDEBUG_EVAL # eval functions
|
||||||
CPPFLAGS += -DDEBUG_PIECE # piece list management
|
CPPFLAGS += -DDEBUG_PIECE # piece list management
|
||||||
|
CPPFLAGS += -DDEBUG_SEARCH # move search
|
||||||
|
|
||||||
##################################### General targets
|
##################################### General targets
|
||||||
.PHONY: compile cflags all clean cleanall
|
.PHONY: compile cflags all clean cleanall
|
||||||
|
36
src/move.c
36
src/move.c
@@ -62,6 +62,20 @@ void moves_pool_stats()
|
|||||||
pool_stats(moves_pool);
|
pool_stats(moves_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* move_print() - print a move
|
||||||
|
* @movenum: move number
|
||||||
|
* @move: &move to display
|
||||||
|
* @flags: options to display
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* @return: 0 if nothing printed, 1 otherwise
|
||||||
|
*/
|
||||||
int move_print(int movenum, 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)) {
|
||||||
@@ -88,10 +102,10 @@ int move_print(int movenum, move_t *move, move_flags_t flags)
|
|||||||
printf("%s%c%c", P_SYM(move->piece),
|
printf("%s%c%c", P_SYM(move->piece),
|
||||||
FILE2C(F88(move->from)),
|
FILE2C(F88(move->from)),
|
||||||
RANK2C(R88(move->from)));
|
RANK2C(R88(move->from)));
|
||||||
if (move->taken) {
|
if (move->flags & M_CAPTURE) {
|
||||||
printf("x");
|
printf("x");
|
||||||
if (flags & M_PR_LONG)
|
if (flags & M_PR_LONG)
|
||||||
printf("%s", P_SYM(move->taken));
|
printf("%s", P_SYM(move->capture));
|
||||||
} else {
|
} else {
|
||||||
printf("-");
|
printf("-");
|
||||||
}
|
}
|
||||||
@@ -172,9 +186,9 @@ static move_t *move_add(pos_t *pos, piece_t piece, square_t from,
|
|||||||
move->piece = piece;
|
move->piece = piece;
|
||||||
move->from = from;
|
move->from = from;
|
||||||
move->to = to;
|
move->to = to;
|
||||||
move->taken = board[to].piece;
|
move->capture = board[to].piece;
|
||||||
move->flags = M_NORMAL;
|
move->flags = M_NORMAL;
|
||||||
if (move->taken)
|
if (move->capture)
|
||||||
move->flags |= M_CAPTURE;
|
move->flags |= M_CAPTURE;
|
||||||
# ifdef DEBUG_MOVE
|
# ifdef DEBUG_MOVE
|
||||||
log_i(3, "added move from %c%c to %c%c\n",
|
log_i(3, "added move from %c%c to %c%c\n",
|
||||||
@@ -336,10 +350,10 @@ int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece, bool doit)
|
|||||||
# endif
|
# endif
|
||||||
if (sq_file == ep_file - 1 || sq_file == ep_file + 1) {
|
if (sq_file == ep_file - 1 || sq_file == ep_file + 1) {
|
||||||
square_t t_square = SQ88(ep_file, rank5); /* taken pawn square */
|
square_t t_square = SQ88(ep_file, rank5); /* taken pawn square */
|
||||||
piece_t taken = board[t_square].piece;
|
piece_t captured = board[t_square].piece;
|
||||||
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->capture = captured;
|
||||||
pos->mobility[color]++;
|
pos->mobility[color]++;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -668,11 +682,7 @@ pos_t *move_do(pos_t *pos, move_t *move)
|
|||||||
int color = COLOR(piece);
|
int color = COLOR(piece);
|
||||||
square_t from = move->from, to = move->to;
|
square_t from = move->from, to = move->to;
|
||||||
|
|
||||||
/* todo: en passant, castle
|
if (move->capture || PIECE(piece) == PAWN) /* 50 moves */
|
||||||
*/
|
|
||||||
SET_COLOR(new->turn, OPPONENT(color)); /* pos color */
|
|
||||||
|
|
||||||
if (move->taken || PIECE(piece) == PAWN) /* 50 moves */
|
|
||||||
new->clock_50 = 0;
|
new->clock_50 = 0;
|
||||||
else
|
else
|
||||||
new->clock_50++;
|
new->clock_50++;
|
||||||
@@ -739,12 +749,14 @@ pos_t *move_do(pos_t *pos, move_t *move)
|
|||||||
new->board[from].piece = 0;
|
new->board[from].piece = 0;
|
||||||
new->board[from].s_piece = NULL;
|
new->board[from].s_piece = NULL;
|
||||||
|
|
||||||
|
SET_COLOR(new->turn, OPPONENT(color)); /* pos color */
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
void move_undo(pos_t *pos, __unused move_t *move)
|
void move_undo(pos_t *pos, __unused move_t *move)
|
||||||
{
|
{
|
||||||
pos_clear(pos);
|
pos_del(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BIN_move
|
#ifdef BIN_move
|
||||||
|
@@ -41,7 +41,7 @@ typedef unsigned char move_flags_t;
|
|||||||
typedef struct move_s {
|
typedef struct move_s {
|
||||||
piece_t piece;
|
piece_t piece;
|
||||||
square_t from, to;
|
square_t from, to;
|
||||||
piece_t taken; /* captured piece */
|
piece_t capture; /* captured piece */
|
||||||
piece_t promotion; /* promoted piece */
|
piece_t promotion; /* promoted piece */
|
||||||
move_flags_t flags;
|
move_flags_t flags;
|
||||||
struct list_head list; /* next move */
|
struct list_head list; /* next move */
|
||||||
|
51
src/search.c
Normal file
51
src/search.c
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/* search.c - search good moves.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <br.h>
|
||||||
|
#include <list.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include "move.h"
|
||||||
|
#include "eval.h"
|
||||||
|
#include "search.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* negamax() - the negamax tree.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
eval_t negamax(pos_t *pos, int depth)
|
||||||
|
{
|
||||||
|
move_t *move, *bestmove;
|
||||||
|
pos_t *newpos;
|
||||||
|
eval_t best = EVAL_MIN, score;
|
||||||
|
|
||||||
|
moves_gen_all(pos);
|
||||||
|
if (depth == 0)
|
||||||
|
return eval(pos) * pos->turn == WHITE? 1: -1;
|
||||||
|
|
||||||
|
list_for_each_entry(move, &pos->moves[pos->turn], list) {
|
||||||
|
newpos = move_do(pos, move);
|
||||||
|
score = -negamax(newpos, depth - 1 );
|
||||||
|
if(score > best) {
|
||||||
|
best = score;
|
||||||
|
bestmove = move;
|
||||||
|
# ifdef DEBUG_SEARCH
|
||||||
|
log_f(2, "depth=%d best move=", best);
|
||||||
|
move_print(0, bestmove, M_PR_LONG);
|
||||||
|
log_f(2, " eval=%d\n", best);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
25
src/search.h
Normal file
25
src/search.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/* search.h - search for perfect move.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEARCH_H
|
||||||
|
#define SEARCH_H
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include "position.h"
|
||||||
|
|
||||||
|
#define EVAL_MIN INT_MIN
|
||||||
|
#define EVAL_MAX INT_MAX
|
||||||
|
|
||||||
|
eval_t negamax(pos_t *pos, int depth);
|
||||||
|
|
||||||
|
#endif /* SEARCH_H */
|
Reference in New Issue
Block a user