Files
brchess/src/position.c

176 lines
4.3 KiB
C

/* position.c - position 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 <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include "chessdefs.h"
#include "position.h"
#include "fen.h"
char *piece2string(piece_t p)
{
piece_t piece = PIECE(p);
switch (piece) {
case PAWN:
return "Pawn";
case KNIGHT:
return "Knight";
case BISHOP:
return "Bishop";
case ROOK:
return "Rook";
case QUEEN:
return "Queen";
case KING:
return "King";
}
return "Unknown";
}
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;
}
if (IS_BLACK(p))
res = tolower(res);
return res;
}
/* void pos_print - Print position on stdout.
* @pos: Position address (pos_t * )
*
* Return: None.
*/
void pos_print(pos_t *pos)
{
int rank, file;
piece_t piece;
board_t *board = pos->board;
printf(" +---+---+---+---+---+---+---+---+\n");
for (rank = 7; rank >= 0; --rank) {
printf("%c |", rank + '1');
for (file = 0; file < 8; ++file) {
piece = board[SQ88(file, rank)].piece;
printf(" %c |", piece2char(piece));
}
printf("\n +---+---+---+---+---+---+---+---+\n");
}
printf(" A B C D E F G H\n\n");
printf("Next move: %s.\n", IS_WHITE(pos->turn) ? "white" : "black");
printf("Possible en-passant: [%#x] ", pos->en_passant);
if (pos->en_passant == 0)
printf("None.\n");
else
printf("%d %d = %c%c\n", GET_F(pos->en_passant),
GET_R(pos->en_passant),
FILE2C(GET_F(pos->en_passant)),
RANK2C(GET_R(pos->en_passant)));
printf("castle [%#x] : ", pos->castle);
if (pos->castle & CASTLE_WK)
printf("K");
if (pos->castle & CASTLE_WQ)
printf("Q");
if (pos->castle & CASTLE_BK)
printf("k");
if (pos->castle & CASTLE_BQ)
printf("q");
printf("\n50 half-moves-rule = %d\n", pos->clock_50);
printf("Current move = %d\n", pos->curmove);
}
pos_t *pos_init(pos_t *pos)
{
int file, rank;
board_t *board = pos->board;
for (file = 0; file < 8; ++file) {
for (rank = 0; rank < 8; ++rank) {
/*printf("file = %d rank = %d SQ88 = %#2x = %d addr=%p\n", file, rank,
SQ88(file, rank), SQ88(file, rank),
&board[SQ88(file, rank)].piece);
*/
board[SQ88(file, rank)].piece = EMPTY;
}
}
pos->turn = WHITE;
pos->castle = 0;
pos->clock_50 = 0;
pos->curmove = 0;
pos->en_passant = 0;
pos->en_passant = 0;
INIT_LIST_HEAD(&pos->pieces_white);
INIT_LIST_HEAD(&pos->pieces_black);
INIT_LIST_HEAD(&pos->moves);
return pos;
}
pos_t *pos_startpos(pos_t *pos)
{
static char *startfen="rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
return fen2pos(pos, startfen);
}
pos_t *pos_create()
{
pos_t *pos = malloc(sizeof(pos_t));
if (pos) {
//printf("sizeof(board)=%lu\n", sizeof (board_t));
pos->board = malloc(sizeof (board_t)*BOARDSIZE);
//printf("board mem: %p-%p\n", pos->board, pos->board+sizeof (board_t));
if (pos->board)
pos_init(pos);
else {
free(pos);
pos = NULL;
}
}
return pos;
}