Add pawn pseudo-moves
This commit is contained in:
@@ -131,6 +131,7 @@ pos_t *fen2pos(pos_t *pos, char *fen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
p++;
|
||||||
|
|
||||||
/* 4) en passant
|
/* 4) en passant
|
||||||
*/
|
*/
|
||||||
|
183
src/move.c
183
src/move.c
@@ -51,6 +51,10 @@ void move_print(move_t *move)
|
|||||||
printf("%c%c",
|
printf("%c%c",
|
||||||
FILE2C(GET_F(move->to)),
|
FILE2C(GET_F(move->to)),
|
||||||
RANK2C(GET_R(move->to)));
|
RANK2C(GET_R(move->to)));
|
||||||
|
if (move->flags & M_EN_PASSANT)
|
||||||
|
printf("e.p.");
|
||||||
|
if (move->promotion)
|
||||||
|
printf("=%s", P_SYM(move->promotion));
|
||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,9 +74,131 @@ void moves_print(pos_t *pos)
|
|||||||
printf("\n\tTotal moves = %d\n", i);
|
printf("\n\tTotal moves = %d\n", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate moves for non pawn pieces
|
inline static move_t *move_add(pos_t *pos, piece_t piece, square_t from,
|
||||||
|
square_t to)
|
||||||
|
{
|
||||||
|
board_t *board = pos->board;
|
||||||
|
move_t *move;
|
||||||
|
|
||||||
|
if (!(move = pool_get(moves_pool)))
|
||||||
|
return NULL;
|
||||||
|
move->piece = piece;
|
||||||
|
move->from = from;
|
||||||
|
move->to = to;
|
||||||
|
move->taken = board[to].piece;
|
||||||
|
move->flags = M_NORMAL;
|
||||||
|
if (move->taken)
|
||||||
|
move->flags |= M_CAPTURE;
|
||||||
|
list_add(&move->list, &pos->moves);
|
||||||
|
return move;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: return nmoves */
|
||||||
|
inline static move_t *move_pawn_add(pos_t *pos, piece_t piece, square_t from,
|
||||||
|
square_t to, unsigned char rank7)
|
||||||
|
{
|
||||||
|
//board_t *board = pos->board;
|
||||||
|
move_t *move;
|
||||||
|
piece_t promote;
|
||||||
|
unsigned char color = COLOR(piece);
|
||||||
|
|
||||||
|
if (RANK88(from) == rank7) { /* promotion */
|
||||||
|
for (promote = QUEEN; promote > PAWN; promote >>= 1) {
|
||||||
|
if ((move = move_add(pos, piece, from, to))) {
|
||||||
|
move->flags |= M_PROMOTION;
|
||||||
|
move->promotion = promote | color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
move = move_add(pos, piece, from, to);
|
||||||
|
}
|
||||||
|
return move;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pawn moves. We do not test for valid destination square here,
|
||||||
|
* assuming position is valid. Is that correct ?
|
||||||
*/
|
*/
|
||||||
int pseudo_moves_get(pos_t *pos, piece_list_t *ppiece)
|
int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece)
|
||||||
|
{
|
||||||
|
piece_t piece = PIECE(ppiece->piece);
|
||||||
|
square_t square = ppiece->square, new;
|
||||||
|
unsigned char color = COLOR(piece);
|
||||||
|
board_t *board = pos->board;
|
||||||
|
unsigned char rank2, rank7, rank5;
|
||||||
|
move_t *move = NULL;
|
||||||
|
char dir;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
/* setup direction */
|
||||||
|
if (color == WHITE) {
|
||||||
|
dir = 1;
|
||||||
|
rank2 = 1;
|
||||||
|
rank7 = 6;
|
||||||
|
rank5 = 4;
|
||||||
|
} else {
|
||||||
|
dir = -1;
|
||||||
|
rank2 = 6;
|
||||||
|
rank7 = 1;
|
||||||
|
rank5 = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* normal push. We do not test for valid destination square here,
|
||||||
|
* assuming position is valid. Is that correct ?
|
||||||
|
*/
|
||||||
|
//moves_print(pos);
|
||||||
|
new = square + dir * 16;
|
||||||
|
if (!board[new].piece) {
|
||||||
|
//printf("pushing pawn %#04x\n", square);
|
||||||
|
if ((move = move_pawn_add(pos, piece, square, new, rank7)))
|
||||||
|
count++;
|
||||||
|
//moves_print(pos);
|
||||||
|
|
||||||
|
/* push 2 squares */
|
||||||
|
if (move && RANK88(square) == rank2) {
|
||||||
|
new += dir * 16;
|
||||||
|
if (SQ88_OK(new) && !board[new].piece) {
|
||||||
|
//printf("pushing pawn %#04x 2 squares\n", square);
|
||||||
|
if ((move = move_pawn_add(pos, piece, square, new, rank7)))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* en passant */
|
||||||
|
if (pos->en_passant && RANK88(square) == rank5) {
|
||||||
|
unsigned char ep_file = FILE88(pos->en_passant);
|
||||||
|
unsigned char sq_file = FILE88(square);
|
||||||
|
|
||||||
|
//printf("possible en passant on rank %#x (current = %#0x)\n", ep_file,
|
||||||
|
// sq_file);
|
||||||
|
|
||||||
|
if (sq_file == ep_file - 1 || sq_file == ep_file + 1) {
|
||||||
|
square_t taken = board[SQUARE(ep_file, rank5)].piece;
|
||||||
|
move = move_pawn_add(pos, piece, square, pos->en_passant, rank7);
|
||||||
|
count++;
|
||||||
|
move->flags |= M_EN_PASSANT;
|
||||||
|
move->taken = taken;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* capture */
|
||||||
|
for (new = square + dir * 15; new <= square + 17; new += 2) {
|
||||||
|
if (SQ88_NOK(new))
|
||||||
|
continue;
|
||||||
|
if (board[new].piece && COLOR(board[new].piece) != color) {
|
||||||
|
//printf("pawn capture %#04x\n", square);
|
||||||
|
if ((move = move_pawn_add(pos, piece, square, new, rank7)))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* general rule moves for non pawn pieces
|
||||||
|
*/
|
||||||
|
int pseudo_moves_gen(pos_t *pos, piece_list_t *ppiece)
|
||||||
{
|
{
|
||||||
piece_t piece = PIECE(ppiece->piece);
|
piece_t piece = PIECE(ppiece->piece);
|
||||||
struct vector *vector = vectors+piece;
|
struct vector *vector = vectors+piece;
|
||||||
@@ -80,16 +206,16 @@ int pseudo_moves_get(pos_t *pos, piece_list_t *ppiece)
|
|||||||
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;
|
||||||
char color = COLOR(piece);
|
unsigned char color = COLOR(piece);
|
||||||
move_t *move;
|
move_t *move;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
/*printf("%s: pos:%p piece:%d [%s] at %#04x[%c%c]\n", __func__, pos, piece,
|
/*printf("%s: pos:%p piece:%d [%s] at %#04x[%c%c]\n", __func__, pos, piece,
|
||||||
piece2string(piece),
|
piece2string(piece),
|
||||||
square,
|
square,
|
||||||
FILE2C(GET_F(square)),
|
FILE2C(GET_F(square)),
|
||||||
RANK2C(GET_R(square)));
|
RANK2C(GET_R(square)));
|
||||||
printf("\tvector=%ld ndirs=%d slide=%d\n", vector-vectors, ndirs, slide);
|
printf("\tvector=%ld ndirs=%d slide=%d\n", vector-vectors, ndirs, slide);
|
||||||
*/
|
*/
|
||||||
for (int curdir = 0; curdir < ndirs; ++curdir) {
|
for (int curdir = 0; curdir < ndirs; ++curdir) {
|
||||||
char dir = vector->dir[curdir];
|
char dir = vector->dir[curdir];
|
||||||
@@ -107,17 +233,8 @@ int pseudo_moves_get(pos_t *pos, piece_list_t *ppiece)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* we are sure the move is valid : we create move */
|
/* we are sure the move is valid : we create move */
|
||||||
if (!(move = pool_get(moves_pool))) {
|
if ((move = move_add(pos, piece, square, new)))
|
||||||
//printf("\t\tmem error\n");
|
count++;
|
||||||
return count;
|
|
||||||
}
|
|
||||||
move->piece = piece;
|
|
||||||
move->from = square;
|
|
||||||
move->to = new;
|
|
||||||
move->taken = board[new].piece;
|
|
||||||
//move_print(move);
|
|
||||||
list_add(&move->list, &pos->moves);
|
|
||||||
count++;
|
|
||||||
if (move->taken)
|
if (move->taken)
|
||||||
break;
|
break;
|
||||||
if (!slide)
|
if (!slide)
|
||||||
@@ -138,30 +255,24 @@ int moves_get(pos_t *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_get(pos, piece);
|
pseudo_moves_gen(pos, piece);
|
||||||
|
else
|
||||||
|
pseudo_moves_pawn(pos, piece);
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
move_t *pseudo_moves_pawn(pos_t *pos)
|
|
||||||
{
|
|
||||||
static short directions[] = {16};
|
|
||||||
if (!pos && *directions)
|
|
||||||
printf("for flycheck");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unused
|
/* unused
|
||||||
move_t *(*moves_fct[])(pos_t *) = {
|
move_t *(*moves_fct[])(pos_t *) = {
|
||||||
[PAWN] = pseudo_moves_pawn,
|
[PAWN] = pseudo_moves_pawn,
|
||||||
[KNIGHT] = pseudo_moves_knight,
|
[KNIGHT] = pseudo_moves_knight,
|
||||||
[BISHOP] = pseudo_moves_bishop,
|
[BISHOP] = pseudo_moves_bishop,
|
||||||
[ROOK] = pseudo_moves_rook,
|
[ROOK] = pseudo_moves_rook,
|
||||||
[QUEEN] = pseudo_moves_queen,
|
[QUEEN] = pseudo_moves_queen,
|
||||||
[KING] = pseudo_moves_king
|
[KING] = pseudo_moves_king
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef MOVEBIN
|
#ifdef MOVEBIN
|
||||||
|
19
src/move.h
19
src/move.h
@@ -19,21 +19,30 @@
|
|||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "piece.h"
|
#include "piece.h"
|
||||||
|
|
||||||
|
/* move flags
|
||||||
|
*/
|
||||||
|
typedef unsigned char move_flags_t;
|
||||||
|
#define M_NORMAL 0x00
|
||||||
|
#define M_CHECK 0x01 /* unsure if we know */
|
||||||
|
#define M_CAPTURE 0x02
|
||||||
|
#define M_EN_PASSANT 0x04
|
||||||
|
#define M_PROMOTION 0x08
|
||||||
|
#define M_CASTLE 0x10
|
||||||
|
|
||||||
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; /* removed piece */
|
piece_t taken; /* removed piece */
|
||||||
|
piece_t promotion; /* promoted piece */
|
||||||
|
move_flags_t flags;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
} move_t;
|
} move_t;
|
||||||
|
|
||||||
pool_t *moves_pool_init();
|
pool_t *moves_pool_init();
|
||||||
void move_print(move_t *move);
|
void move_print(move_t *move);
|
||||||
void moves_print(pos_t *move);
|
void moves_print(pos_t *move);
|
||||||
int pseudo_moves_get(pos_t *pos, piece_list_t *piece);
|
int pseudo_moves_gen(pos_t *pos, piece_list_t *piece);
|
||||||
|
int pseudo_moves_pawn(pos_t *pos, piece_list_t *piece);
|
||||||
int moves_get(pos_t *pos);
|
int moves_get(pos_t *pos);
|
||||||
|
|
||||||
/* not used */
|
|
||||||
move_t *pseudo_moves_pawn(pos_t *pos);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user