pseudo-moves for pieces (not pawns nor special moves)
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@ GTAGS
|
|||||||
fen
|
fen
|
||||||
pool
|
pool
|
||||||
piece
|
piece
|
||||||
|
move
|
||||||
|
7
Makefile
7
Makefile
@@ -6,7 +6,7 @@ SRCDIR=./src
|
|||||||
SRC=$(wildcard $(SRCDIR)/*.c)
|
SRC=$(wildcard $(SRCDIR)/*.c)
|
||||||
INC=$(wildcard $(SRCDIR)/*.h)
|
INC=$(wildcard $(SRCDIR)/*.h)
|
||||||
|
|
||||||
BIN=fen pool piece
|
BIN=fen pool piece move
|
||||||
|
|
||||||
CFLAGS += -std=gnu99
|
CFLAGS += -std=gnu99
|
||||||
CFLAGS += -g
|
CFLAGS += -g
|
||||||
@@ -37,3 +37,8 @@ piece: CFLAGS+=-DPIECEBIN
|
|||||||
piece: $(SRC)
|
piece: $(SRC)
|
||||||
echo SRC=$(SRC)
|
echo SRC=$(SRC)
|
||||||
$(CC) $(CFLAGS) $? -o $@
|
$(CC) $(CFLAGS) $? -o $@
|
||||||
|
|
||||||
|
move: CFLAGS+=-DMOVEBIN
|
||||||
|
move: $(SRC)
|
||||||
|
echo SRC=$(SRC)
|
||||||
|
$(CC) $(CFLAGS) $? -o $@
|
||||||
|
1
dir-locals.el
Normal file
1
dir-locals.el
Normal file
@@ -0,0 +1 @@
|
|||||||
|
((c-mode . ((compile-command . "make -C ../build -j2 whatever"))))
|
@@ -27,7 +27,10 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
#define SQ88(f, r) (16 * (r) + (f)) /* from rank,file to sq88 */
|
#define SQ88(f, r) (16 * (r) + (f)) /* from rank,file to sq88 */
|
||||||
#define FILE88(s) ((s) & 7) /* from sq88 to file */
|
#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
|
/* piece human notation
|
||||||
*/
|
*/
|
||||||
|
222
src/move.c
Normal file
222
src/move.c
Normal 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
|
20
src/move.h
20
src/move.h
@@ -16,12 +16,24 @@
|
|||||||
|
|
||||||
#include "chessdefs.h"
|
#include "chessdefs.h"
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
|
#include "pool.h"
|
||||||
|
#include "piece.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct move_s {
|
||||||
piece_t t;
|
piece_t piece;
|
||||||
square_t from, to;
|
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
|
#endif
|
||||||
|
35
src/piece.c
35
src/piece.c
@@ -14,9 +14,42 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include "chessdefs.h"
|
#include "chessdefs.h"
|
||||||
#include "piece.h"
|
#include "piece.h"
|
||||||
|
#include "ctype.h"
|
||||||
|
|
||||||
static pool_t *pieces_pool;
|
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)
|
void piece_list_print(struct list_head *list)
|
||||||
{
|
{
|
||||||
struct list_head *p_cur, *tmp;
|
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) {
|
list_for_each_safe(p_cur, tmp, list) {
|
||||||
piece = list_entry(p_cur, piece_list_t, 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)),
|
FILE2C(GET_F(piece->square)),
|
||||||
RANK2C(GET_R(piece->square)));
|
RANK2C(GET_R(piece->square)));
|
||||||
/*printf("\t%d: %s on %c%c\n", i,
|
/*printf("\t%d: %s on %c%c\n", i,
|
||||||
|
@@ -145,6 +145,7 @@ pos_t *pos_init(pos_t *pos)
|
|||||||
pos->en_passant = 0;
|
pos->en_passant = 0;
|
||||||
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);
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,7 @@ typedef struct position {
|
|||||||
eval_t eval;
|
eval_t eval;
|
||||||
struct list_head pieces_white;
|
struct list_head pieces_white;
|
||||||
struct list_head pieces_black;
|
struct list_head pieces_black;
|
||||||
|
struct list_head moves;
|
||||||
board_t *board;
|
board_t *board;
|
||||||
} pos_t;
|
} pos_t;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user