Compare commits
2 Commits
6178e7c963
...
a649db77ef
| Author | SHA1 | Date | |
|---|---|---|---|
| a649db77ef | |||
| 1ab928cc6f |
@ -28,5 +28,7 @@ void undoMove(uint_least64_t *board, struct move_t move, bool color);
|
|||||||
struct gameState_t makeMove(struct gameState_t gameState, struct move_t move);
|
struct gameState_t makeMove(struct gameState_t gameState, struct move_t move);
|
||||||
void initMagicTable();
|
void initMagicTable();
|
||||||
bool kingInCheck(const uint_least64_t *board, const bool color);
|
bool kingInCheck(const uint_least64_t *board, const bool color);
|
||||||
|
uint_least8_t getBaseRankI(bool color);
|
||||||
|
uint_least8_t getBaseRank(bool color);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -14,11 +14,6 @@
|
|||||||
//#define START_FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
|
//#define START_FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
|
||||||
#define START_FEN "rnbqkbnr/PPppppPP/8/8/8/8/ppPPPPpp/RNBQKBNR w KQkq - 0 1"
|
#define START_FEN "rnbqkbnr/PPppppPP/8/8/8/8/ppPPPPpp/RNBQKBNR w KQkq - 0 1"
|
||||||
|
|
||||||
#define drawPiece(file, rank, piece) do { \
|
|
||||||
const RsvgRectangle rect = {xOffset + (file) * fieldSize, yOffset + (rank) * fieldSize, fieldSize, fieldSize};\
|
|
||||||
rsvg_handle_render_document(piecesSvg[pieceToSvgI(piece)], cr, &rect, NULL); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
struct drawData_t {
|
struct drawData_t {
|
||||||
RsvgHandle **piecesSvg;
|
RsvgHandle **piecesSvg;
|
||||||
struct gameState_t *gameState;
|
struct gameState_t *gameState;
|
||||||
@ -33,12 +28,19 @@ struct drawData_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const uint_least8_t PROMOTION_PIECES[] = {QUEEN, KNIGHT, BISHOP, ROOK};
|
const uint_least8_t PROMOTION_PIECES[] = {QUEEN, KNIGHT, BISHOP, ROOK};
|
||||||
static bool turn = WHITE;
|
|
||||||
|
|
||||||
static uint_least8_t pieceToSvgI(struct piece_t piece) {
|
static uint_least8_t pieceToSvgI(struct piece_t piece) {
|
||||||
return piece.color == WHITE ? piece.type | 8 : piece.type;
|
return piece.color == WHITE ? piece.type | 8 : piece.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void drawPiece(struct drawData_t *ctx, cairo_t *cr, uint_least8_t field, struct piece_t piece) {
|
||||||
|
const uint_least8_t file = field % BOARD_SIZE;
|
||||||
|
const uint_least8_t rank = field / BOARD_SIZE;
|
||||||
|
const RsvgRectangle rect = {ctx->xOffset + file * ctx->fieldSize, ctx->yOffset + rank * ctx->fieldSize, ctx->fieldSize, ctx->fieldSize};\
|
||||||
|
rsvg_handle_render_document(ctx->piecesSvg[pieceToSvgI(piece)], cr, &rect, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void selectCircle(cairo_t *cr, const struct drawData_t *drawData, uint_least8_t field, double radius) {
|
static void selectCircle(cairo_t *cr, const struct drawData_t *drawData, uint_least8_t field, double radius) {
|
||||||
uint_least8_t file = field % BOARD_SIZE;
|
uint_least8_t file = field % BOARD_SIZE;
|
||||||
uint_least8_t rank = field / BOARD_SIZE;
|
uint_least8_t rank = field / BOARD_SIZE;
|
||||||
@ -50,17 +52,19 @@ static void selectCircle(cairo_t *cr, const struct drawData_t *drawData, uint_le
|
|||||||
|
|
||||||
static struct gameState_t userMove(struct gameState_t gameState, struct move_t move) {
|
static struct gameState_t userMove(struct gameState_t gameState, struct move_t move) {
|
||||||
gameState = makeMove(gameState, move);
|
gameState = makeMove(gameState, move);
|
||||||
#ifdef NO_COMPUTER
|
#ifndef NO_COMPUTER
|
||||||
turn = !turn;
|
|
||||||
#else
|
|
||||||
move = bestMove(gameState);
|
move = bestMove(gameState);
|
||||||
gameState = makeMove(gameState, move);
|
gameState = makeMove(gameState, move);
|
||||||
#endif
|
#endif
|
||||||
return gameState;
|
return gameState;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint_least8_t promotionUiPos(uint_least8_t dst) {
|
static uint_least8_t promotionUiPos(uint_least8_t dst, bool color) {
|
||||||
return dst >= 1 ? dst - 1 : 0;
|
const uint_least8_t rankI = getBaseRankI(!color);
|
||||||
|
uint_least8_t uiPos = dst >= rankI + 1 ? dst - 1 : dst;
|
||||||
|
const uint_least8_t overflowI = rankI + BOARD_SIZE;
|
||||||
|
if(uiPos + LENGTH(PROMOTION_PIECES) > overflowI) uiPos = overflowI - LENGTH(PROMOTION_PIECES);
|
||||||
|
return uiPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_event(GtkDrawingArea *area, cairo_t *cr, int width, int height, gpointer data) {
|
static void draw_event(GtkDrawingArea *area, cairo_t *cr, int width, int height, gpointer data) {
|
||||||
@ -68,7 +72,8 @@ static void draw_event(GtkDrawingArea *area, cairo_t *cr, int width, int height,
|
|||||||
const double xOffset = (width - fieldSize * BOARD_SIZE) / 2;
|
const double xOffset = (width - fieldSize * BOARD_SIZE) / 2;
|
||||||
const double yOffset = (height - fieldSize * BOARD_SIZE) / 2;
|
const double yOffset = (height - fieldSize * BOARD_SIZE) / 2;
|
||||||
struct drawData_t *drawData = (struct drawData_t*)data;
|
struct drawData_t *drawData = (struct drawData_t*)data;
|
||||||
const uint_least64_t *board = drawData->gameState->board;
|
const struct gameState_t *gameState = drawData->gameState;
|
||||||
|
const uint_least64_t *board = gameState->board;
|
||||||
RsvgHandle **piecesSvg = drawData->piecesSvg;
|
RsvgHandle **piecesSvg = drawData->piecesSvg;
|
||||||
drawData->xOffset = xOffset;
|
drawData->xOffset = xOffset;
|
||||||
drawData->yOffset = yOffset;
|
drawData->yOffset = yOffset;
|
||||||
@ -82,7 +87,7 @@ static void draw_event(GtkDrawingArea *area, cairo_t *cr, int width, int height,
|
|||||||
cairo_fill(cr);
|
cairo_fill(cr);
|
||||||
if(bitboardGetAllPieces(board, field)) {
|
if(bitboardGetAllPieces(board, field)) {
|
||||||
const struct piece_t piece = pieceAtField(board, rank * BOARD_SIZE + file);
|
const struct piece_t piece = pieceAtField(board, rank * BOARD_SIZE + file);
|
||||||
drawPiece(file, rank, piece);
|
drawPiece(drawData, cr, field, piece);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,14 +102,13 @@ static void draw_event(GtkDrawingArea *area, cairo_t *cr, int width, int height,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(drawData->selectDst != NOT_SELECTED) {
|
if(drawData->selectDst != NOT_SELECTED) {
|
||||||
uint_least8_t uiPos = promotionUiPos(drawData->selectDst);
|
uint_least8_t uiPos = promotionUiPos(drawData->selectDst, gameState->color);
|
||||||
if(uiPos + 3 >= BOARD_SIZE) uiPos = BOARD_SIZE - LENGTH(PROMOTION_PIECES);
|
|
||||||
cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
|
cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
|
||||||
cairo_rectangle(cr, xOffset + uiPos * fieldSize, yOffset, 4 * fieldSize, fieldSize);
|
cairo_rectangle(cr, xOffset + uiPos * fieldSize, yOffset, 4 * fieldSize, fieldSize);
|
||||||
cairo_fill(cr);
|
cairo_fill(cr);
|
||||||
for(uint_least8_t i = 0; i < LENGTH(PROMOTION_PIECES); ++i) {
|
for(uint_least8_t i = 0; i < LENGTH(PROMOTION_PIECES); ++i) {
|
||||||
const struct piece_t piece = {PROMOTION_PIECES[i], true};
|
const struct piece_t piece = {PROMOTION_PIECES[i], gameState->color};
|
||||||
drawPiece(uiPos + i, 0, piece);
|
drawPiece(drawData, cr, uiPos + i, piece);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,9 +125,9 @@ static void on_click(GtkGestureClick *gesture, int n_press, double x, double y,
|
|||||||
const uint_least8_t file = adjustedX / fieldSize;
|
const uint_least8_t file = adjustedX / fieldSize;
|
||||||
const uint_least8_t rank = adjustedY / fieldSize;
|
const uint_least8_t rank = adjustedY / fieldSize;
|
||||||
const uint_least8_t field = file + rank * BOARD_SIZE;
|
const uint_least8_t field = file + rank * BOARD_SIZE;
|
||||||
const bool promotion_field = rank == (gameState->color == WHITE ? 0 : BOARD_SIZE - 1);
|
const bool onPromotionField = rank == getBaseRank(!gameState->color);
|
||||||
if(drawData->selectDst == NOT_SELECTED) {
|
if(drawData->selectDst == NOT_SELECTED) {
|
||||||
const struct piece_t allPiece = {ALL_PIECES, turn};
|
const struct piece_t allPiece = {ALL_PIECES, gameState->color};
|
||||||
if(bitboardGet(board, allPiece, field)) {
|
if(bitboardGet(board, allPiece, field)) {
|
||||||
// deactivated piece by clicking on it again
|
// deactivated piece by clicking on it again
|
||||||
if(field == drawData->clickedPiece) {
|
if(field == drawData->clickedPiece) {
|
||||||
@ -146,7 +150,7 @@ static void on_click(GtkGestureClick *gesture, int n_press, double x, double y,
|
|||||||
}
|
}
|
||||||
if(isValidDst) {
|
if(isValidDst) {
|
||||||
const struct piece_t piece = pieceAtField(board, drawData->clickedPiece);
|
const struct piece_t piece = pieceAtField(board, drawData->clickedPiece);
|
||||||
if(piece.type == PAWN && promotion_field) { // promotion
|
if(piece.type == PAWN && onPromotionField) { // promotion
|
||||||
drawData->selectDst = field;
|
drawData->selectDst = field;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -166,11 +170,11 @@ static void on_click(GtkGestureClick *gesture, int n_press, double x, double y,
|
|||||||
drawData->movesLength = 0;
|
drawData->movesLength = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(promotion_field) {
|
else if(onPromotionField) {
|
||||||
const uint_least8_t uiPos = promotionUiPos(drawData->selectDst);
|
const uint_least8_t uiPos = promotionUiPos(drawData->selectDst, gameState->color);
|
||||||
const uint_least8_t i = file - uiPos;
|
const uint_least8_t i = field - uiPos;
|
||||||
if(i >= LENGTH(PROMOTION_PIECES)) return;
|
if(i >= LENGTH(PROMOTION_PIECES)) return;
|
||||||
const uint_least8_t dstPiece = PROMOTION_PIECES[file - uiPos];
|
const uint_least8_t dstPiece = PROMOTION_PIECES[i];
|
||||||
const uint_least8_t capturedPiece = pieceAtField(board, drawData->selectDst).type;
|
const uint_least8_t capturedPiece = pieceAtField(board, drawData->selectDst).type;
|
||||||
const struct move_t move = {drawData->clickedPiece, drawData->selectDst, 0, PAWN, dstPiece, capturedPiece};
|
const struct move_t move = {drawData->clickedPiece, drawData->selectDst, 0, PAWN, dstPiece, capturedPiece};
|
||||||
*gameState = userMove(*gameState, move);
|
*gameState = userMove(*gameState, move);
|
||||||
|
|||||||
@ -133,17 +133,21 @@ bool kingInCheck(const uint_least64_t *board, const bool color) {
|
|||||||
return inCheck(board, bitboardGetMask(board, king), color);
|
return inCheck(board, bitboardGetMask(board, king), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint_least8_t getCastleRankI(bool color) {
|
uint_least8_t getBaseRank(bool color) {
|
||||||
if(color == WHITE) {
|
if(color == WHITE) {
|
||||||
return (BOARD_SIZE - 1) * BOARD_SIZE;
|
return BOARD_SIZE - 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint_least8_t getBaseRankI(bool color) {
|
||||||
|
return getBaseRank(color) * BOARD_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
static void castleMoveRook(uint_least64_t *board, uint_least8_t spezialMove, bool color, bool undo) {
|
static void castleMoveRook(uint_least64_t *board, uint_least8_t spezialMove, bool color, bool undo) {
|
||||||
if(spezialMove == SHORT_CASTLE || spezialMove == LONG_CASTLE) {
|
if(spezialMove == SHORT_CASTLE || spezialMove == LONG_CASTLE) {
|
||||||
const uint_least8_t rookSrc = getCastleRankI(color) + (spezialMove == SHORT_CASTLE ? BOARD_SIZE - 1 : 0);
|
const uint_least8_t rookSrc = getBaseRankI(color) + (spezialMove == SHORT_CASTLE ? BOARD_SIZE - 1 : 0);
|
||||||
const uint_least8_t rookDst = getCastleRankI(color) + (spezialMove == SHORT_CASTLE ? 5 : 3);
|
const uint_least8_t rookDst = getBaseRankI(color) + (spezialMove == SHORT_CASTLE ? 5 : 3);
|
||||||
const struct piece_t rook = {ROOK, color};
|
const struct piece_t rook = {ROOK, color};
|
||||||
bitboardSet(board, rook, undo ? rookSrc : rookDst);
|
bitboardSet(board, rook, undo ? rookSrc : rookDst);
|
||||||
bitboardClear(board, rook, undo ? rookDst : rookSrc);
|
bitboardClear(board, rook, undo ? rookDst : rookSrc);
|
||||||
@ -248,7 +252,7 @@ uint_least8_t pieceValidMoves(struct gameState_t gameState, struct piece_t piece
|
|||||||
addPreGenMoves(addmoveCtx, KING_MOVES, src, piece);
|
addPreGenMoves(addmoveCtx, KING_MOVES, src, piece);
|
||||||
const struct castle_t canCastle = gameState.canCastle[piece.color];
|
const struct castle_t canCastle = gameState.canCastle[piece.color];
|
||||||
const uint_least64_t allPiecesMask = bitboardMaskAllPieces(board);
|
const uint_least64_t allPiecesMask = bitboardMaskAllPieces(board);
|
||||||
const uint_least8_t rankShift = piece.color == WHITE ? BOARD_SIZE * (BOARD_SIZE - 1) : 0;
|
const uint_least8_t rankShift = getBaseRankI(piece.color);
|
||||||
const uint_least64_t shortCastleMask = (uint_least64_t)0b11 << (5 + rankShift);
|
const uint_least64_t shortCastleMask = (uint_least64_t)0b11 << (5 + rankShift);
|
||||||
const uint_least64_t shortCastleCheckMask = (uint_least64_t)0b11 << (4 + rankShift);
|
const uint_least64_t shortCastleCheckMask = (uint_least64_t)0b11 << (4 + rankShift);
|
||||||
const uint_least64_t longCastleMask = (uint_least64_t)0b111 << (1 + rankShift);
|
const uint_least64_t longCastleMask = (uint_least64_t)0b111 << (1 + rankShift);
|
||||||
@ -363,7 +367,7 @@ struct gameState_t makeMove(struct gameState_t gameState, struct move_t move) {
|
|||||||
canCastleCurrentPlayer->shortCastle = false;
|
canCastleCurrentPlayer->shortCastle = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setCastleInfo(canCastleCurrentPlayer, move.src - getCastleRankI(gameState.color));
|
setCastleInfo(canCastleCurrentPlayer, move.src - getBaseRankI(gameState.color));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -371,7 +375,7 @@ struct gameState_t makeMove(struct gameState_t gameState, struct move_t move) {
|
|||||||
// if the rook is captured
|
// if the rook is captured
|
||||||
struct castle_t *canCastleOther = gameState.canCastle + !gameState.color;
|
struct castle_t *canCastleOther = gameState.canCastle + !gameState.color;
|
||||||
if(canCastleOther->longCastle || canCastleOther->shortCastle) {
|
if(canCastleOther->longCastle || canCastleOther->shortCastle) {
|
||||||
setCastleInfo(canCastleOther, move.dst - getCastleRankI(!gameState.color));
|
setCastleInfo(canCastleOther, move.dst - getBaseRankI(!gameState.color));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user