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
|
||||
pool
|
||||
piece
|
||||
move
|
||||
|
7
Makefile
7
Makefile
@@ -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
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 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
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 "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
|
||||
|
35
src/piece.c
35
src/piece.c
@@ -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,
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user