pseudo-moves for pieces (not pawns nor special moves)

This commit is contained in:
2021-10-31 12:16:11 +01:00
parent 07e7cbc72a
commit 2f701c4bd5
9 changed files with 286 additions and 7 deletions

1
.gitignore vendored
View File

@@ -5,3 +5,4 @@ GTAGS
fen
pool
piece
move

View File

@@ -6,7 +6,7 @@ SRCDIR=./src
SRC=$(wildcard $(SRCDIR)/*.c)
INC=$(wildcard $(SRCDIR)/*.h)
BIN=fen pool piece
BIN=fen pool piece move
CFLAGS += -std=gnu99
CFLAGS += -g
@@ -37,3 +37,8 @@ piece: CFLAGS+=-DPIECEBIN
piece: $(SRC)
echo SRC=$(SRC)
$(CC) $(CFLAGS) $? -o $@
move: CFLAGS+=-DMOVEBIN
move: $(SRC)
echo SRC=$(SRC)
$(CC) $(CFLAGS) $? -o $@

1
dir-locals.el Normal file
View File

@@ -0,0 +1 @@
((c-mode . ((compile-command . "make -C ../build -j2 whatever"))))

View File

@@ -27,7 +27,10 @@ typedef struct {
*/
#define SQ88(f, r) (16 * (r) + (f)) /* from rank,file to sq88 */
#define FILE88(s) ((s) & 7) /* from sq88 to file */
#define RANK88(s) ((s) >> 8) /* from sq88 to rank */
#define RANK88(s) ((s) >> 4) /* from sq88 to rank */
#define SQ88_NOK(s) ((s) & 0x88) /* invalid square */
#define SQ88_OK(s) (!SQ88_NOK(s))
/* piece human notation
*/

222
src/move.c Normal file
View File

@@ -0,0 +1,222 @@
/* move.c - move management.
*
* 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.htmlL>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#include <malloc.h>
#include <ctype.h>
#include "chessdefs.h"
#include "piece.h"
#include "move.h"
#include "list.h"
static pool_t *moves_pool;
static struct vector {
unsigned char ndirs;
char slide;
char dir[8];
} vectors[] = {
[KNIGHT] = { 8, 0, { -33, -31, -18, -14, 14, 18, 31, 33}},
[BISHOP] = { 4, 1, { -15, -17, 15, 17}},
[ROOK] = { 4, 1, { -1, -16, 1, 16}},
[QUEEN] = { 8, 1, { -1, -16, 1, 16, -15, -17, 15, 17}},
[KING] = { 8, 0, { -1, -16, 1, 16, -15, -17, 15, 17}},
};
inline static char piece2char(piece_t p)
{
piece_t piece = PIECE(p);
char res;
//printf("%#x p=%#x\n", p, PIECE(p));
switch (piece) {
case PAWN:
res = CHAR_PAWN;
break;
case KNIGHT:
res = CHAR_KNIGHT;
break;
case BISHOP:
res = CHAR_BISHOP;
break;
case ROOK:
res = CHAR_ROOK;
break;
case QUEEN:
res = CHAR_QUEEN;
break;
case KING:
res = CHAR_KING;
break;
default:
res = CHAR_EMPTY;
}
return res;
}
pool_t *moves_pool_init()
{
if (!moves_pool)
moves_pool = pool_init("moves", 128, sizeof(piece_list_t));
return moves_pool;
}
void move_print(move_t *move)
{
printf("%c%c%c", piece2char(move->piece),
FILE2C(GET_F(move->from)),
RANK2C(GET_R(move->from)));
if (move->taken)
printf("x%c", piece2char(move->taken));
else
printf("-");
printf("%c%c",
FILE2C(GET_F(move->to)),
RANK2C(GET_R(move->to)));
printf(" ");
}
void moves_print(pos_t *pos)
{
struct list_head *p_cur, *tmp;
move_t *move;
int i = 0;
printf("%s pseudo-moves: ", pos->turn == WHITE? "White": "Black");
list_for_each_safe(p_cur, tmp, &pos->moves) {
move = list_entry(p_cur, move_t, list);
move_print(move);
i++;
}
printf("Total moves = %d\n", i);
}
/* generate moves for non pawn pieces
*/
int pseudo_moves_get(pos_t *pos, piece_list_t *ppiece)
{
piece_t piece = PIECE(ppiece->piece);
struct vector *vector = vectors+piece;
square_t square = ppiece->square;
unsigned char ndirs = vector->ndirs;
char slide = vector->slide;
board_t *board = pos->board;
char color = COLOR(piece);
move_t *move;
int count = 0;
/*printf("%s: pos:%p piece:%d [%s] at %#04x[%c%c]\n", __func__, pos, piece,
piece2string(piece),
square,
FILE2C(GET_F(square)),
RANK2C(GET_R(square)));
printf("\tvector=%ld ndirs=%d slide=%d\n", vector-vectors, ndirs, slide);
*/
for (int curdir = 0; curdir < ndirs; ++curdir) {
char dir = vector->dir[curdir];
for (square_t new = square + dir; ; new = new + dir) {
/* outside board */
if (SQ88_NOK(new)) {
//printf("\t\tskipping %04x (invalid square)\n", new);
break;
}
//printf("\ttrying %c%c", FILE2C(GET_F(new)), RANK2C(GET_R(new)));
/* own color on dest square */
if (board[new].piece && COLOR(board[new].piece) == color) {
//printf("\t\tskipping %04x (same color piece)\n", new);
break;
}
/* we are sure the move is valid : we create move */
if (!(move = pool_get(moves_pool))) {
//printf("\t\tmem error\n");
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)
break;
if (!slide)
break;
}
}
return count;
}
int moves_get(pos_t *pos)
{
struct list_head *p_cur, *tmp, *piece_list;
piece_list_t *piece;
int count = 0;
piece_list = pos->turn == WHITE? &pos->pieces_white: &pos->pieces_black;
list_for_each_safe(p_cur, tmp, piece_list) {
piece = list_entry(p_cur, piece_list_t, list);
if (PIECE(piece->piece) != PAWN)
pseudo_moves_get(pos, piece);
count++;
}
return count;
}
move_t *pseudo_moves_pawn(pos_t *pos)
{
static short directions[] = {16};
if (!pos && *directions)
printf("for flycheck");
return NULL;
}
/* unused
move_t *(*moves_fct[])(pos_t *) = {
[PAWN] = pseudo_moves_pawn,
[KNIGHT] = pseudo_moves_knight,
[BISHOP] = pseudo_moves_bishop,
[ROOK] = pseudo_moves_rook,
[QUEEN] = pseudo_moves_queen,
[KING] = pseudo_moves_king
};
*/
#ifdef MOVEBIN
#include "fen.h"
int main(int ac, char**av)
{
pos_t *pos;
pos = pos_create();
piece_pool_init();
moves_pool_init();
if (ac == 1) {
pos_startpos(pos);
} else {
fen2pos(pos, av[1]);
}
pos_print(pos);
pieces_print_pos_pieces(pos);
moves_get(pos);
moves_print(pos);
}
#endif

View File

@@ -16,12 +16,24 @@
#include "chessdefs.h"
#include "position.h"
#include "pool.h"
#include "piece.h"
typedef struct {
piece_t t;
typedef struct move_s {
piece_t piece;
square_t from, to;
} MOVE;
piece_t taken; /* removed piece */
extern MOVE *moves_rook(POS *pos);
struct list_head list;
} move_t;
pool_t *moves_pool_init();
void move_print(move_t *move);
void moves_print(pos_t *move);
int pseudo_moves_get(pos_t *pos, piece_list_t *piece);
int moves_get(pos_t *pos);
/* not used */
move_t *pseudo_moves_pawn(pos_t *pos);
#endif

View File

@@ -14,9 +14,42 @@
#include <malloc.h>
#include "chessdefs.h"
#include "piece.h"
#include "ctype.h"
static pool_t *pieces_pool;
inline static char piece2char(piece_t p)
{
piece_t piece = PIECE(p);
char res;
//printf("%#x p=%#x\n", p, PIECE(p));
switch (piece) {
case PAWN:
res = CHAR_PAWN;
break;
case KNIGHT:
res = CHAR_KNIGHT;
break;
case BISHOP:
res = CHAR_BISHOP;
break;
case ROOK:
res = CHAR_ROOK;
break;
case QUEEN:
res = CHAR_QUEEN;
break;
case KING:
res = CHAR_KING;
break;
default:
res = CHAR_EMPTY;
}
return res;
}
void piece_list_print(struct list_head *list)
{
struct list_head *p_cur, *tmp;
@@ -26,7 +59,7 @@ void piece_list_print(struct list_head *list)
list_for_each_safe(p_cur, tmp, list) {
piece = list_entry(p_cur, piece_list_t, list);
printf("%c%c%c ", *piece2string(piece->piece),
printf("%c%c%c ", piece2char(piece->piece),
FILE2C(GET_F(piece->square)),
RANK2C(GET_R(piece->square)));
/*printf("\t%d: %s on %c%c\n", i,

View File

@@ -145,6 +145,7 @@ pos_t *pos_init(pos_t *pos)
pos->en_passant = 0;
INIT_LIST_HEAD(&pos->pieces_white);
INIT_LIST_HEAD(&pos->pieces_black);
INIT_LIST_HEAD(&pos->moves);
return pos;
}

View File

@@ -28,6 +28,7 @@ typedef struct position {
eval_t eval;
struct list_head pieces_white;
struct list_head pieces_black;
struct list_head moves;
board_t *board;
} pos_t;