Compare commits
5 Commits
9b25a6ba8c
...
09ceca44e5
| Author | SHA1 | Date | |
|---|---|---|---|
| 09ceca44e5 | |||
| 1e4af66379 | |||
| 5bd8f9042a | |||
| 373a73cb52 | |||
| 9c6830bc56 |
@@ -19,12 +19,14 @@
|
|||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
|
|
||||||
|
#include <br.h>
|
||||||
|
#include <list.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
#include "chessdefs.h"
|
#include "chessdefs.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "piece.h"
|
#include "piece.h"
|
||||||
#include "move.h"
|
#include "move.h"
|
||||||
#include "list.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "fen.h"
|
#include "fen.h"
|
||||||
#include "eval.h"
|
#include "eval.h"
|
||||||
#include "brchess.h"
|
#include "brchess.h"
|
||||||
@@ -50,6 +52,7 @@ char *stripwhite (char *string);
|
|||||||
/* The names of functions that actually do the manipulation. */
|
/* The names of functions that actually do the manipulation. */
|
||||||
int do_help(pos_t *, char*);
|
int do_help(pos_t *, char*);
|
||||||
int do_fen(pos_t *, char*);
|
int do_fen(pos_t *, char*);
|
||||||
|
int do_init(pos_t *, char*);
|
||||||
int do_pos(pos_t *, char*);
|
int do_pos(pos_t *, char*);
|
||||||
int do_genmoves(pos_t *, char*);
|
int do_genmoves(pos_t *, char*);
|
||||||
int do_prmoves(pos_t *, char*);
|
int do_prmoves(pos_t *, char*);
|
||||||
@@ -64,9 +67,10 @@ 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" },
|
||||||
|
{ "init", do_init, "Set position to normal start position" },
|
||||||
{ "pos", do_pos, "Print current position" },
|
{ "pos", do_pos, "Print current position" },
|
||||||
{ "quit", do_quit, "Quit" },
|
{ "quit", do_quit, "Quit" },
|
||||||
{ "genmove", do_genmoves, "Generate next move list" },
|
{ "genmove", do_genmoves, "Generate move list for " },
|
||||||
{ "prmoves", do_prmoves, "Print position move list" },
|
{ "prmoves", do_prmoves, "Print position move list" },
|
||||||
{ "prmovepos", do_prmovepos, "Print Nth move resulting position" },
|
{ "prmovepos", do_prmovepos, "Print Nth move resulting position" },
|
||||||
{ "prpieces", do_prpieces, "Print Pieces (from pieces lists)" },
|
{ "prpieces", do_prpieces, "Print Pieces (from pieces lists)" },
|
||||||
@@ -108,9 +112,7 @@ int brchess(pos_t *pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//char **commands_completion(const char *text, int start, int end)
|
//char **commands_completion(const char *text, int start, int end)
|
||||||
char **commands_completion(const char *text,
|
char **commands_completion(const char *text, __unused int start, __unused int end)
|
||||||
__attribute__((unused)) int start,
|
|
||||||
__attribute__((unused)) int end)
|
|
||||||
{
|
{
|
||||||
rl_attempted_completion_over = 1;
|
rl_attempted_completion_over = 1;
|
||||||
return rl_completion_matches(text, commands_generator);
|
return rl_completion_matches(text, commands_generator);
|
||||||
@@ -252,31 +254,41 @@ char *stripwhite(char *string)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_eval(__attribute__((unused)) pos_t *pos,
|
int do_eval(__unused pos_t *pos, __unused char *arg)
|
||||||
__attribute__((unused)) char *arg)
|
|
||||||
{
|
{
|
||||||
|
eval_t material[2], control[2], mobility[2];
|
||||||
|
for (int color = WHITE; color <= BLACK; ++color) {
|
||||||
|
material[color] = eval_material(pos, color);
|
||||||
|
control[color] = eval_square_control(pos, color);
|
||||||
|
mobility[color] = eval_mobility(pos, color);
|
||||||
|
printf("%s: material=%d mobility=%d controlled=%d\n",
|
||||||
|
color? "Black": "White", material[color],
|
||||||
|
mobility[color], control[color]);
|
||||||
|
}
|
||||||
eval_t res = eval(pos);
|
eval_t res = eval(pos);
|
||||||
printf("eval=%ld (%.3f pawns)\n", res, (float)res/100);
|
printf("eval = %d centipawns\n", res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_fen(pos_t *pos, char *arg)
|
int do_fen(pos_t *pos, char *arg)
|
||||||
{
|
{
|
||||||
log_f(1, "%s\n", arg);
|
|
||||||
fen2pos(pos, arg);
|
fen2pos(pos, arg);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_pos(pos_t *pos,
|
int do_init(pos_t *pos, __unused char *arg)
|
||||||
__attribute__((unused)) char *arg)
|
{
|
||||||
|
pos_startpos(pos);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_pos(pos_t *pos, __unused char *arg)
|
||||||
{
|
{
|
||||||
log_f(1, "%s\n", arg);
|
|
||||||
pos_print(pos);
|
pos_print(pos);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_genmoves(pos_t *pos,
|
int do_genmoves(pos_t *pos, __unused char *arg)
|
||||||
__attribute__((unused)) char *arg)
|
|
||||||
{
|
{
|
||||||
log_f(1, "%s\n", arg);
|
log_f(1, "%s\n", arg);
|
||||||
moves_gen(pos, OPPONENT(pos->turn), false);
|
moves_gen(pos, OPPONENT(pos->turn), false);
|
||||||
@@ -284,8 +296,7 @@ int do_genmoves(pos_t *pos,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_prmoves(pos_t *pos,
|
int do_prmoves(pos_t *pos, __unused char *arg)
|
||||||
__attribute__((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);
|
||||||
@@ -299,16 +310,18 @@ int do_prmovepos(pos_t *pos, char *arg)
|
|||||||
move_t *move;
|
move_t *move;
|
||||||
|
|
||||||
log_f(1, "%s\n", arg);
|
log_f(1, "%s\n", arg);
|
||||||
list_for_each_safe(p_cur, tmp, &pos->moves) {
|
list_for_each_safe(p_cur, tmp, &pos->moves[pos->turn]) {
|
||||||
move = list_entry(p_cur, move_t, list);
|
move = list_entry(p_cur, move_t, list);
|
||||||
if (cur++ == movenum)
|
if (cur++ == movenum) {
|
||||||
|
pos_print(move->newpos);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pos_print(move->newpos);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_prpieces(pos_t *pos, __attribute__((unused)) char *arg)
|
int do_prpieces(pos_t *pos, __unused char *arg)
|
||||||
{
|
{
|
||||||
log_f(1, "%s\n", arg);
|
log_f(1, "%s\n", arg);
|
||||||
pos_pieces_print(pos);
|
pos_pieces_print(pos);
|
||||||
@@ -347,7 +360,7 @@ int do_help(__attribute__((unused)) pos_t *pos,
|
|||||||
|
|
||||||
for (i = 0; commands[i].name; i++) {
|
for (i = 0; commands[i].name; i++) {
|
||||||
if (!*arg || (strcmp(arg, commands[i].name) == 0)) {
|
if (!*arg || (strcmp(arg, commands[i].name) == 0)) {
|
||||||
printf("%s\t\t%s.\n", commands[i].name, commands[i].doc);
|
printf("%-11.11s%s.\n", commands[i].name, commands[i].doc);
|
||||||
printed++;
|
printed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -409,7 +422,6 @@ int main(int ac, char **av)
|
|||||||
return usage(*av);
|
return usage(*av);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("optind = %d ac = %d\n", optind, ac);
|
|
||||||
if (optind < ac)
|
if (optind < ac)
|
||||||
return usage(*av);
|
return usage(*av);
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ typedef u64 bitboard_t;
|
|||||||
|
|
||||||
/* eval type
|
/* eval type
|
||||||
*/
|
*/
|
||||||
typedef u64 eval_t;
|
typedef s32 eval_t;
|
||||||
|
|
||||||
/* forward typedefs
|
/* forward typedefs
|
||||||
*/
|
*/
|
||||||
|
|||||||
90
src/eval.c
90
src/eval.c
@@ -18,64 +18,72 @@
|
|||||||
|
|
||||||
#include "eval.h"
|
#include "eval.h"
|
||||||
|
|
||||||
eval_t eval(pos_t *pos)
|
inline eval_t eval_material(pos_t *pos, bool color)
|
||||||
{
|
{
|
||||||
eval_t material[2] = {0};
|
|
||||||
eval_t control[2] = {0};
|
|
||||||
eval_t res = 0;
|
eval_t res = 0;
|
||||||
|
|
||||||
//printf("val(%d-%c) = %lu\n", PAWN, P_LETTER(PAWN), P_VALUE(PAWN));
|
/* I need to do something about the king, if it can be potentially taken
|
||||||
//printf("val(%d-%c) = %lu\n", KNIGHT, P_LETTER(KNIGHT), P_VALUE(KNIGHT));
|
* if pseudo-moves include a pinned piece on King.
|
||||||
//bitboard_print2(pos->bb[0][BB_PAWN], pos->bb[1][BB_PAWN]);
|
|
||||||
//bitboard_print2(pos->bb[0][BB_QUEEN], pos->bb[1][BB_QUEEN]);
|
|
||||||
/* 1) pieces value
|
|
||||||
*/
|
*/
|
||||||
for (uint color = 0; color < 2; ++color) {
|
for (uint piece = PAWN; piece < KING; piece <<= 1) {
|
||||||
for (uint piece = PAWN; piece <= KING; piece <<= 1) {
|
uint bb = PIECETOBB(piece);
|
||||||
uint bb = PIECETOBB(piece);
|
# ifdef DEBUG_EVAL
|
||||||
# ifdef DEBUG_EVAL
|
log_f(2, "color=%u piece=%u bb=%u=%c count=%ul val=%ld\n",
|
||||||
log_f(2, "color=%u piece=%u bb=%u=%c count=%ul val=%ld\n",
|
color, piece, bb, P_LETTER(piece), popcount64(pos->bb[color][bb]),
|
||||||
color, piece, bb, P_LETTER(piece), popcount64(pos->bb[color][bb]),
|
P_VALUE(piece));
|
||||||
P_VALUE(piece));
|
# endif
|
||||||
# endif
|
/* attention here */
|
||||||
/* attention here */
|
res += popcount64(pos->bb[color][bb]) * P_VALUE(piece);
|
||||||
material[color] += popcount64(pos->bb[color][bb]) * P_VALUE(piece);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline eval_t eval_mobility(pos_t *pos, bool color)
|
||||||
|
{
|
||||||
|
return popcount64(pos->controlled[color]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline eval_t eval_square_control(pos_t *pos, bool color)
|
||||||
|
{
|
||||||
|
return pos->mobility[color];
|
||||||
|
}
|
||||||
|
|
||||||
|
eval_t eval(pos_t *pos)
|
||||||
|
{
|
||||||
|
eval_t material[2] = {0}, control[2] = {0};
|
||||||
|
|
||||||
|
/* 1) pieces value */
|
||||||
|
material[WHITE] = eval_material(pos, WHITE);
|
||||||
|
material[BLACK] = eval_material(pos, BLACK);
|
||||||
|
|
||||||
res = material[WHITE] - material[BLACK];
|
|
||||||
# ifdef DEBUG_EVAL
|
# ifdef DEBUG_EVAL
|
||||||
log_f(2, "material: W:%ld B:%ld eval=%ld (%.3f pawns)\n",
|
log_f(2, "material: W:%d B:%d diff=%d\n",
|
||||||
material[WHITE], material[BLACK],
|
material[WHITE], material[BLACK], material[WHITE] - material[BLACK]);
|
||||||
material[WHITE] - material[BLACK], (float)res/100);
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* 2) square control: 10 square controls diff = 1 pawn
|
/* 2) square control: 10 square controls diff = 1 pawn */
|
||||||
*/
|
control[WHITE] = eval_square_control(pos, WHITE);
|
||||||
control[WHITE] = popcount64(pos->controlled[WHITE]);
|
control[BLACK] = eval_square_control(pos, BLACK);
|
||||||
control[BLACK] = popcount64(pos->controlled[BLACK]);
|
|
||||||
res = control[WHITE] - control[BLACK];
|
|
||||||
# ifdef DEBUG_EVAL
|
# ifdef DEBUG_EVAL
|
||||||
log_f(2, "square control: W:%ld B:%ld eval=%ld (%.3f pawns)\n",
|
log_f(2, "square control: W:%d B:%d diff=%d\n",
|
||||||
control[WHITE], control[BLACK],
|
control[WHITE], control[BLACK],
|
||||||
res, (float)res/10);
|
(control[WHITE] - control[BLACK]) * 10);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* 3) mobility: 10 mobility diff = 1 pawn
|
/* 3) mobility: 10 mobility diff = 1 pawn
|
||||||
*/
|
*/
|
||||||
res = pos->mobility[WHITE] - pos->mobility[BLACK];
|
|
||||||
# ifdef DEBUG_EVAL
|
# ifdef DEBUG_EVAL
|
||||||
log_f(2, "mobility: W:%ud B:%ud eval=%ld (%.3f pawns)\n",
|
log_f(2, "mobility: W:%u B:%u diff=%d\n",
|
||||||
pos->mobility[WHITE], pos->mobility[BLACK],
|
pos->mobility[WHITE], pos->mobility[BLACK],
|
||||||
res, (float)res/5);
|
(pos->mobility[WHITE] - pos->mobility[BLACK]) * 10);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
res = material[WHITE] - material[BLACK] +
|
eval_t res = material[WHITE] - material[BLACK] +
|
||||||
(control[WHITE] - control[BLACK]) * 10 +
|
(control[WHITE] - control[BLACK]) * 10 +
|
||||||
(pos->mobility[WHITE] - pos->mobility[BLACK]) * 20;
|
(pos->mobility[WHITE] - pos->mobility[BLACK]) * 10;
|
||||||
# ifdef DEBUG_EVAL
|
# ifdef DEBUG_EVAL
|
||||||
log_f(2, "eval: %ld (%.3f pawns)\n",
|
log_f(2, "eval: %d\n", res);
|
||||||
res, (float)res/100);
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -90,7 +98,7 @@ int main(int ac, char**av)
|
|||||||
pos_t *pos;
|
pos_t *pos;
|
||||||
eval_t res;
|
eval_t res;
|
||||||
|
|
||||||
debug_level_set(9);
|
debug_init(5);
|
||||||
piece_pool_init();
|
piece_pool_init();
|
||||||
moves_pool_init();
|
moves_pool_init();
|
||||||
pos_pool_init();
|
pos_pool_init();
|
||||||
@@ -106,12 +114,12 @@ int main(int ac, char**av)
|
|||||||
pos_pieces_print(pos);
|
pos_pieces_print(pos);
|
||||||
|
|
||||||
moves_gen(pos, OPPONENT(pos->turn), false);
|
moves_gen(pos, OPPONENT(pos->turn), false);
|
||||||
moves_print(pos, M_PR_SEPARATE);
|
//moves_print(pos, M_PR_SEPARATE);
|
||||||
//pos_print(pos);
|
//pos_print(pos);
|
||||||
//pos_pieces_print(pos);
|
//pos_pieces_print(pos);
|
||||||
moves_gen(pos, pos->turn, false);
|
moves_gen(pos, pos->turn, true);
|
||||||
moves_print(pos, M_PR_SEPARATE);
|
moves_print(pos, M_PR_SEPARATE);
|
||||||
res = eval(pos);
|
res = eval(pos);
|
||||||
printf("eval=%ld (%.3f pawns)\n", res, (float)res/100);
|
printf("eval=%d centipawns)\n", res);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
|
|
||||||
|
eval_t eval_material(pos_t *pos, bool color);
|
||||||
|
eval_t eval_mobility(pos_t *pos, bool color);
|
||||||
|
eval_t eval_square_control(pos_t *pos, bool color);
|
||||||
|
|
||||||
eval_t eval(pos_t *pos);
|
eval_t eval(pos_t *pos);
|
||||||
|
|
||||||
#endif /* EVAL_H */
|
#endif /* EVAL_H */
|
||||||
|
|||||||
215
src/move.c
215
src/move.c
@@ -65,13 +65,13 @@ int move_print(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
|
||||||
log_i(5, "capture & %#04x\n", move->flags);
|
log_i(9, "skipping capture & %#04x\n", move->flags);
|
||||||
# endif
|
# endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (flags & M_PR_NCAPT && move->flags & M_CAPTURE) {
|
if (flags & M_PR_NCAPT && move->flags & M_CAPTURE) {
|
||||||
# ifdef DEBUG_MOVE
|
# ifdef DEBUG_MOVE
|
||||||
log_i(5, "!capture & %#04x\n", move->flags);
|
log_i(9, "skipping !capture & %#04x\n", move->flags);
|
||||||
# endif
|
# endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -109,28 +109,29 @@ 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;
|
||||||
int i = 0;
|
|
||||||
move_flags_t details = flags & M_PR_LONG;
|
move_flags_t details = flags & M_PR_LONG;
|
||||||
|
|
||||||
printf("%s pseudo-moves:\n\t", pos->turn == WHITE? "White": "Black");
|
for (int color=WHITE; color <= BLACK; ++color) {
|
||||||
if (! (flags & M_PR_SEPARATE)) {
|
int verif = 0;
|
||||||
list_for_each_safe(p_cur, tmp, &pos->moves) {
|
printf("%s pseudo-moves:\n\t", color == WHITE? "White": "Black");
|
||||||
move = list_entry(p_cur, move_t, list);
|
if (! (flags & M_PR_SEPARATE)) {
|
||||||
i += move_print(move, details);
|
list_for_each_safe(p_cur, tmp, &pos->moves[color]) {
|
||||||
|
move = list_entry(p_cur, move_t, list);
|
||||||
|
verif += move_print(move, details);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("captures: ");
|
||||||
|
list_for_each_safe(p_cur, tmp, &pos->moves[color]) {
|
||||||
|
move = list_entry(p_cur, move_t, list);
|
||||||
|
verif += move_print(move, details | M_PR_CAPT);
|
||||||
|
}
|
||||||
|
printf("\n\tothers : ");
|
||||||
|
list_for_each_safe(p_cur, tmp, &pos->moves[color]) {
|
||||||
|
move = list_entry(p_cur, move_t, list);
|
||||||
|
verif += move_print(move, details | M_PR_NCAPT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
printf("\n\tTotal moves = %d\n", i);
|
printf("\n\tTotal moves = %d mobility=%u\n", verif, pos->mobility[color]);
|
||||||
} else {
|
|
||||||
printf("captures: ");
|
|
||||||
list_for_each_safe(p_cur, tmp, &pos->moves) {
|
|
||||||
move = list_entry(p_cur, move_t, list);
|
|
||||||
i += move_print(move, details | M_PR_CAPT);
|
|
||||||
}
|
|
||||||
printf("\n\tothers : ");
|
|
||||||
list_for_each_safe(p_cur, tmp, &pos->moves) {
|
|
||||||
move = list_entry(p_cur, move_t, list);
|
|
||||||
i += move_print(move, details | M_PR_NCAPT);
|
|
||||||
}
|
|
||||||
printf("\n\tTotal moves = %d\n", i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,17 +141,18 @@ static move_t *move_add(pos_t *pos, piece_t piece, square_t from,
|
|||||||
board_t *board = pos->board;
|
board_t *board = pos->board;
|
||||||
pos_t *newpos;
|
pos_t *newpos;
|
||||||
move_t *move;
|
move_t *move;
|
||||||
|
int color = COLOR(piece);
|
||||||
|
|
||||||
# ifdef DEBUG_MOVE
|
# ifdef DEBUG_MOVE
|
||||||
log_i(3, "piece_color=%d turn=%d from=%c%c to=%c%c\n",
|
log_i(3, "piece_color=%d turn=%d from=%c%c to=%c%c\n",
|
||||||
COLOR(piece), pos->turn,
|
color, pos->turn,
|
||||||
FILE2C(F88(from)),
|
FILE2C(F88(from)),
|
||||||
RANK2C(R88(from)),
|
RANK2C(R88(from)),
|
||||||
FILE2C(F88(to)),
|
FILE2C(F88(to)),
|
||||||
RANK2C(R88(to)));
|
RANK2C(R88(to)));
|
||||||
# endif
|
# endif
|
||||||
if (COLOR(piece) != pos->turn)
|
//if (COLOR(piece) != pos->turn)
|
||||||
return NULL;
|
// return NULL;
|
||||||
/* invalid position if opponent king is attacked
|
/* invalid position if opponent king is attacked
|
||||||
*/
|
*/
|
||||||
if (board[to].piece & KING) {
|
if (board[to].piece & KING) {
|
||||||
@@ -162,7 +164,7 @@ static move_t *move_add(pos_t *pos, piece_t piece, square_t from,
|
|||||||
}
|
}
|
||||||
if (!(move = pool_get(moves_pool)))
|
if (!(move = pool_get(moves_pool)))
|
||||||
return NULL;
|
return NULL;
|
||||||
list_add(&move->list, &pos->moves);
|
list_add(&move->list, &pos->moves[color]);
|
||||||
|
|
||||||
move->piece = piece;
|
move->piece = piece;
|
||||||
move->from = from;
|
move->from = from;
|
||||||
@@ -226,11 +228,13 @@ int moves_del(pos_t *pos)
|
|||||||
struct list_head *p_cur, *tmp, *head;
|
struct list_head *p_cur, *tmp, *head;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
head = &pos->moves;
|
for (int color = WHITE; color <= BLACK; ++color) {
|
||||||
|
head = &pos->moves[color];
|
||||||
|
|
||||||
list_for_each_safe(p_cur, tmp, head) {
|
list_for_each_safe(p_cur, tmp, head) {
|
||||||
move_del(p_cur);
|
move_del(p_cur);
|
||||||
count++;
|
count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
# ifdef DEBUG_PIECE
|
# ifdef DEBUG_PIECE
|
||||||
log_f(3, "removed=%d\n", count);
|
log_f(3, "removed=%d\n", count);
|
||||||
@@ -247,8 +251,8 @@ static move_t *move_pawn_add(pos_t *pos, piece_t piece, square_t from,
|
|||||||
unsigned char color = COLOR(piece);
|
unsigned char color = COLOR(piece);
|
||||||
pos_t *newpos;
|
pos_t *newpos;
|
||||||
|
|
||||||
if (color != pos->turn)
|
//if (color != pos->turn)
|
||||||
return NULL;
|
// 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))) {
|
||||||
@@ -320,10 +324,12 @@ int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece, bool doit)
|
|||||||
# endif
|
# endif
|
||||||
//log_f(4, "pawn move mobility\n");
|
//log_f(4, "pawn move mobility\n");
|
||||||
pos->mobility[color]++;
|
pos->mobility[color]++;
|
||||||
if (doit && (move = move_pawn_add(pos, piece | color, square, new, rank7)))
|
count++;
|
||||||
count++;
|
if (doit)
|
||||||
|
move_pawn_add(pos, piece | color, square, new, rank7);
|
||||||
/* push 2 squares */
|
/* push 2 squares */
|
||||||
if (move && R88(square) == rank2) {
|
log(4, "R88(%#x)=%d R2=%d \n", square, R88(square), rank2);
|
||||||
|
if (R88(square) == rank2) {
|
||||||
new += dir * 16;
|
new += dir * 16;
|
||||||
if (SQ88_OK(new) && !board[new].piece) {
|
if (SQ88_OK(new) && !board[new].piece) {
|
||||||
# ifdef DEBUG_MOVE
|
# ifdef DEBUG_MOVE
|
||||||
@@ -331,16 +337,15 @@ int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece, bool doit)
|
|||||||
# endif
|
# endif
|
||||||
//log_f(2, "pawn move2 mobility\n");
|
//log_f(2, "pawn move2 mobility\n");
|
||||||
pos->mobility[color]++;
|
pos->mobility[color]++;
|
||||||
if (doit &&
|
count++;
|
||||||
(move = move_pawn_add(pos, piece | color, square, new, rank7))) {
|
if (doit)
|
||||||
count++;
|
move_pawn_add(pos, piece | color, square, new, rank7);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* en passant - not accounted for mobility. Correct ? */
|
/* en passant - not accounted for mobility. Correct ? */
|
||||||
if (doit && pos->en_passant && R88(square) == rank5) {
|
if (pos->en_passant && R88(square) == rank5) {
|
||||||
unsigned char ep_file = F88(pos->en_passant);
|
unsigned char ep_file = F88(pos->en_passant);
|
||||||
unsigned char sq_file = F88(square);
|
unsigned char sq_file = F88(square);
|
||||||
|
|
||||||
@@ -352,7 +357,6 @@ int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece, bool doit)
|
|||||||
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 taken = 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);
|
||||||
count++;
|
|
||||||
move->flags |= M_EN_PASSANT | M_CAPTURE;
|
move->flags |= M_EN_PASSANT | M_CAPTURE;
|
||||||
move->taken = taken;
|
move->taken = taken;
|
||||||
|
|
||||||
@@ -361,6 +365,7 @@ int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece, bool doit)
|
|||||||
move->newpos->board[t_square].piece = 0;
|
move->newpos->board[t_square].piece = 0;
|
||||||
move->newpos->board[t_square].s_piece = NULL;
|
move->newpos->board[t_square].s_piece = NULL;
|
||||||
|
|
||||||
|
pos->mobility[color]++;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,17 +383,28 @@ int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece, bool doit)
|
|||||||
if (board[new].piece && COLOR(board[new].piece) != color) {
|
if (board[new].piece && COLOR(board[new].piece) != color) {
|
||||||
//log_f(2, "pawn capture mobility\n");
|
//log_f(2, "pawn capture mobility\n");
|
||||||
pos->mobility[color]++;
|
pos->mobility[color]++;
|
||||||
if (doit &&
|
count++;
|
||||||
((move = move_pawn_add(pos, piece | color, square, new, rank7))))
|
if (doit)
|
||||||
count++;
|
move_pawn_add(pos, piece | color, square, new, rank7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# ifdef DEBUG_MOVE
|
||||||
|
log_f(2, "pos:%p turn:%s piece:%d [%s %s] dir:%d at %#04x[%c%c] count=%d\n",
|
||||||
|
pos,
|
||||||
|
IS_WHITE(pos->turn)? "white": "black",
|
||||||
|
piece,
|
||||||
|
IS_WHITE(color)? "white": "black",
|
||||||
|
P_NAME(piece),
|
||||||
|
dir,
|
||||||
|
square,
|
||||||
|
FILE2C(F88(square)), RANK2C(R88(square)), count);
|
||||||
|
# endif
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pseudo_moves_castle(pos_t *pos)
|
int pseudo_moves_castle(pos_t *pos, bool color, bool doit)
|
||||||
{
|
{
|
||||||
unsigned char color = pos->turn;
|
//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;
|
||||||
@@ -399,9 +415,10 @@ int pseudo_moves_castle(pos_t *pos)
|
|||||||
pos_t *newpos;
|
pos_t *newpos;
|
||||||
|
|
||||||
# ifdef DEBUG_MOVE
|
# ifdef DEBUG_MOVE
|
||||||
log_f(2, "pos:%p turn:%s\n",
|
log_f(2, "pos:%p turn:%s color:%s\n",
|
||||||
pos,
|
pos,
|
||||||
IS_WHITE(pos->turn)? "white": "black");
|
IS_WHITE(pos->turn)? "white": "black",
|
||||||
|
IS_WHITE(color)? "white": "black");
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
if (IS_WHITE(color)) {
|
if (IS_WHITE(color)) {
|
||||||
@@ -419,51 +436,64 @@ int pseudo_moves_castle(pos_t *pos)
|
|||||||
}
|
}
|
||||||
if (castle_K) {
|
if (castle_K) {
|
||||||
if (occupied & can_castle->occupied[1]) {
|
if (occupied & can_castle->occupied[1]) {
|
||||||
printf("Cannot castle K side: occupied\n");
|
# ifdef DEBUG_MOVE
|
||||||
|
log(5, "Cannot castle K side: occupied\n");
|
||||||
|
# endif
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
if (controlled & can_castle->controlled[1]) {
|
if (controlled & can_castle->controlled[1]) {
|
||||||
printf("Cannot castle K side: controlled\n");
|
# ifdef DEBUG_MOVE
|
||||||
|
log(5, "Cannot castle K side: controlled\n");
|
||||||
|
# endif
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
move = move_add(pos, board[SQ88(4, rank1)].piece,
|
pos->mobility[color]++;
|
||||||
SQ88(4, rank1), SQ88(6, rank1));
|
count++;
|
||||||
if (move) {
|
if (doit) {
|
||||||
newpos = move->newpos;
|
move = move_add(pos, board[SQ88(4, rank1)].piece,
|
||||||
move->flags |= M_CASTLE_K;
|
SQ88(4, rank1), SQ88(6, rank1));
|
||||||
|
if (move) {
|
||||||
|
newpos = move->newpos;
|
||||||
|
move->flags |= M_CASTLE_K;
|
||||||
|
|
||||||
/* move King rook to column F */
|
/* move King rook to column F */
|
||||||
newpos->board[SQ88(5, rank1)] = newpos->board[SQ88(7, rank1)];
|
newpos->board[SQ88(5, rank1)] = newpos->board[SQ88(7, rank1)];
|
||||||
SETF88(newpos->board[SQ88(5, rank1)].s_piece->square, 5);
|
SETF88(newpos->board[SQ88(5, rank1)].s_piece->square, 5);
|
||||||
newpos->board[SQ88(7, rank1)].piece = 0;
|
newpos->board[SQ88(7, rank1)].piece = 0;
|
||||||
newpos->board[SQ88(7, rank1)].s_piece = NULL;
|
newpos->board[SQ88(7, rank1)].s_piece = NULL;
|
||||||
|
|
||||||
count++;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
next:
|
||||||
if (castle_Q) {
|
if (castle_Q) {
|
||||||
if (occupied & can_castle->occupied[0]) {
|
if (occupied & can_castle->occupied[0]) {
|
||||||
printf("Cannot castle Q side: occupied\n");
|
# ifdef DEBUG_MOVE
|
||||||
|
log(5, "Cannot castle Q side: occupied\n");
|
||||||
|
# endif
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (controlled & can_castle->controlled[0]) {
|
if (controlled & can_castle->controlled[0]) {
|
||||||
printf("Cannot castle Q side: controlled\n");
|
# ifdef DEBUG_MOVE
|
||||||
|
log(5, "Cannot castle Q side: controlled\n");
|
||||||
|
# endif
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
move = move_add(pos, board[SQ88(4, rank1)].piece,
|
pos->mobility[color]++;
|
||||||
SQ88(4, rank1), SQ88(2, rank1));
|
count++;
|
||||||
if (move) {
|
if (doit) {
|
||||||
newpos = move->newpos;
|
move = move_add(pos, board[SQ88(4, rank1)].piece,
|
||||||
move->flags |= M_CASTLE_Q;
|
SQ88(4, rank1), SQ88(2, rank1));
|
||||||
/* move King rook to column F */
|
if (move) {
|
||||||
newpos->board[SQ88(3, rank1)] = newpos->board[SQ88(0, rank1)];
|
newpos = move->newpos;
|
||||||
SETF88(newpos->board[SQ88(3, rank1)].s_piece->square, 3);
|
move->flags |= M_CASTLE_Q;
|
||||||
newpos->board[SQ88(0, rank1)].piece = 0;
|
/* move King rook to column F */
|
||||||
newpos->board[SQ88(0, rank1)].s_piece = NULL;
|
newpos->board[SQ88(3, rank1)] = newpos->board[SQ88(0, rank1)];
|
||||||
|
SETF88(newpos->board[SQ88(3, rank1)].s_piece->square, 3);
|
||||||
count++;
|
newpos->board[SQ88(0, rank1)].piece = 0;
|
||||||
|
newpos->board[SQ88(0, rank1)].s_piece = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
@@ -481,7 +511,7 @@ int pseudo_moves_gen(pos_t *pos, piece_list_t *ppiece, bool doit)
|
|||||||
unsigned char ndirs = vector->ndirs;
|
unsigned char ndirs = vector->ndirs;
|
||||||
char slide = vector->slide;
|
char slide = vector->slide;
|
||||||
board_t *board = pos->board;
|
board_t *board = pos->board;
|
||||||
move_t *move;
|
//move_t *move;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
u64 bb_new;
|
u64 bb_new;
|
||||||
|
|
||||||
@@ -540,10 +570,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");
|
//log_f(2, "piece mobility\n");
|
||||||
pos->mobility[color]++;
|
pos->mobility[color]++;
|
||||||
if (doit && color == pos->turn) {
|
count++;
|
||||||
if ((move = move_add(pos, ppiece->piece, square, new))) {
|
if (doit) {
|
||||||
count++;
|
//move = move_add(pos, ppiece->piece, square, new);
|
||||||
}
|
move_add(pos, ppiece->piece, square, new);
|
||||||
}
|
}
|
||||||
if (board[new].piece) { /* stopper move */
|
if (board[new].piece) { /* stopper move */
|
||||||
break;
|
break;
|
||||||
@@ -552,6 +582,16 @@ int pseudo_moves_gen(pos_t *pos, piece_list_t *ppiece, bool doit)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# ifdef DEBUG_MOVE
|
||||||
|
log_f(2, "pos:%p turn:%s piece:%d [%s %s] at %#04x[%c%c] count=%d\n",
|
||||||
|
pos,
|
||||||
|
IS_WHITE(pos->turn)? "white": "black",
|
||||||
|
piece,
|
||||||
|
IS_WHITE(color)? "white": "black",
|
||||||
|
P_NAME(piece),
|
||||||
|
square,
|
||||||
|
FILE2C(F88(square)), RANK2C(R88(square)), count);
|
||||||
|
# endif
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,15 +608,13 @@ 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;
|
||||||
if (doit)
|
count += pseudo_moves_castle(pos, color, doit);
|
||||||
pseudo_moves_castle(pos);
|
|
||||||
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)
|
||||||
pseudo_moves_gen(pos, piece, doit);
|
count += pseudo_moves_gen(pos, piece, doit);
|
||||||
else
|
else
|
||||||
pseudo_moves_pawn(pos, piece, doit);
|
count += pseudo_moves_pawn(pos, piece, doit);
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -599,20 +637,21 @@ int main(int ac, char**av)
|
|||||||
{
|
{
|
||||||
pos_t *pos;
|
pos_t *pos;
|
||||||
|
|
||||||
debug_init(1);
|
debug_level_set(5);
|
||||||
piece_pool_init();
|
piece_pool_init();
|
||||||
moves_pool_init();
|
moves_pool_init();
|
||||||
pos_pool_init();
|
pos_pool_init();
|
||||||
pos = pos_get();
|
pos = pos_get();
|
||||||
|
|
||||||
if (ac == 1) {
|
if (ac == 1) {
|
||||||
pos_startpos(pos);
|
fen2pos(pos, "rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2");
|
||||||
|
//pos_startpos(pos);
|
||||||
} else {
|
} else {
|
||||||
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, OPPONENT(pos->turn), false);
|
moves_gen(pos, WHITE, false);
|
||||||
moves_gen(pos, pos->turn, true);
|
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);
|
||||||
|
|||||||
@@ -51,11 +51,11 @@ 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(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);
|
||||||
int pseudo_moves_castle(pos_t *pos);
|
|
||||||
|
|
||||||
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_gen(pos_t *pos, piece_list_t *piece, bool doit);
|
int pseudo_moves_gen(pos_t *pos, piece_list_t *piece, bool doit);
|
||||||
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);
|
||||||
|
|||||||
@@ -176,7 +176,8 @@ pos_t *pos_get()
|
|||||||
INIT_LIST_HEAD(&pos->pieces[WHITE]);
|
INIT_LIST_HEAD(&pos->pieces[WHITE]);
|
||||||
INIT_LIST_HEAD(&pos->pieces[BLACK]);
|
INIT_LIST_HEAD(&pos->pieces[BLACK]);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&pos->moves);
|
INIT_LIST_HEAD(&pos->moves[WHITE]);
|
||||||
|
INIT_LIST_HEAD(&pos->moves[BLACK]);
|
||||||
pos_clear(pos);
|
pos_clear(pos);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "zobaaa\n");
|
fprintf(stderr, "zobaaa\n");
|
||||||
@@ -197,7 +198,8 @@ pos_t *pos_dup(pos_t *pos)
|
|||||||
*new = *pos;
|
*new = *pos;
|
||||||
INIT_LIST_HEAD(&new->pieces[WHITE]);
|
INIT_LIST_HEAD(&new->pieces[WHITE]);
|
||||||
INIT_LIST_HEAD(&new->pieces[BLACK]);
|
INIT_LIST_HEAD(&new->pieces[BLACK]);
|
||||||
INIT_LIST_HEAD(&new->moves);
|
INIT_LIST_HEAD(&new->moves[WHITE]);
|
||||||
|
INIT_LIST_HEAD(&new->moves[BLACK]);
|
||||||
|
|
||||||
/* duplicate piece list */
|
/* duplicate piece list */
|
||||||
for (int color=0; color<2; ++color) {
|
for (int color=0; color<2; ++color) {
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ typedef struct pos_s {
|
|||||||
castle_t castle;
|
castle_t castle;
|
||||||
u16 clock_50;
|
u16 clock_50;
|
||||||
u16 curmove;
|
u16 curmove;
|
||||||
u16 mobility[2];
|
|
||||||
eval_t eval;
|
eval_t eval;
|
||||||
board_t board[BOARDSIZE];
|
board_t board[BOARDSIZE];
|
||||||
|
|
||||||
@@ -37,8 +36,9 @@ typedef struct pos_s {
|
|||||||
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];
|
||||||
struct list_head pieces[2];
|
struct list_head pieces[2];
|
||||||
struct list_head moves;
|
struct list_head moves[2];
|
||||||
} pos_t;
|
} pos_t;
|
||||||
|
|
||||||
void bitboard_print(bitboard_t bb);
|
void bitboard_print(bitboard_t bb);
|
||||||
|
|||||||
Reference in New Issue
Block a user