fixed promotion menu

computer not working!
This commit is contained in:
2024-09-05 14:47:47 +02:00
parent 6178e7c963
commit 1ab928cc6f
3 changed files with 43 additions and 32 deletions

View File

@ -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);
void initMagicTable();
bool kingInCheck(const uint_least64_t *board, const bool color);
uint_least8_t getBaseRankI(bool color);
uint_least8_t getBaseRank(bool color);
#endif

View File

@ -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 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 {
RsvgHandle **piecesSvg;
struct gameState_t *gameState;
@ -33,12 +28,19 @@ struct drawData_t {
};
const uint_least8_t PROMOTION_PIECES[] = {QUEEN, KNIGHT, BISHOP, ROOK};
static bool turn = WHITE;
static uint_least8_t pieceToSvgI(struct piece_t piece) {
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) {
uint_least8_t file = 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) {
gameState = makeMove(gameState, move);
#ifdef NO_COMPUTER
turn = !turn;
#else
#ifndef NO_COMPUTER
move = bestMove(gameState);
gameState = makeMove(gameState, move);
#endif
return gameState;
}
static uint_least8_t promotionUiPos(uint_least8_t dst) {
return dst >= 1 ? dst - 1 : 0;
static uint_least8_t promotionUiPos(uint_least8_t dst, bool color) {
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) {
@ -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 yOffset = (height - fieldSize * BOARD_SIZE) / 2;
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;
drawData->xOffset = xOffset;
drawData->yOffset = yOffset;
@ -82,7 +87,7 @@ static void draw_event(GtkDrawingArea *area, cairo_t *cr, int width, int height,
cairo_fill(cr);
if(bitboardGetAllPieces(board, field)) {
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) {
uint_least8_t uiPos = promotionUiPos(drawData->selectDst);
if(uiPos + 3 >= BOARD_SIZE) uiPos = BOARD_SIZE - LENGTH(PROMOTION_PIECES);
uint_least8_t uiPos = promotionUiPos(drawData->selectDst, gameState->color);
cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
cairo_rectangle(cr, xOffset + uiPos * fieldSize, yOffset, 4 * fieldSize, fieldSize);
cairo_fill(cr);
for(uint_least8_t i = 0; i < LENGTH(PROMOTION_PIECES); ++i) {
const struct piece_t piece = {PROMOTION_PIECES[i], true};
drawPiece(uiPos + i, 0, piece);
const struct piece_t piece = {PROMOTION_PIECES[i], gameState->color};
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 rank = adjustedY / fieldSize;
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) {
const struct piece_t allPiece = {ALL_PIECES, turn};
const struct piece_t allPiece = {ALL_PIECES, gameState->color};
if(bitboardGet(board, allPiece, field)) {
// deactivated piece by clicking on it again
if(field == drawData->clickedPiece) {
@ -146,7 +150,7 @@ static void on_click(GtkGestureClick *gesture, int n_press, double x, double y,
}
if(isValidDst) {
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;
}
else {
@ -166,11 +170,11 @@ static void on_click(GtkGestureClick *gesture, int n_press, double x, double y,
drawData->movesLength = 0;
}
}
else if(promotion_field) {
const uint_least8_t uiPos = promotionUiPos(drawData->selectDst);
const uint_least8_t i = file - uiPos;
else if(onPromotionField) {
const uint_least8_t uiPos = promotionUiPos(drawData->selectDst, gameState->color);
const uint_least8_t i = field - uiPos;
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 struct move_t move = {drawData->clickedPiece, drawData->selectDst, 0, PAWN, dstPiece, capturedPiece};
*gameState = userMove(*gameState, move);

View File

@ -133,17 +133,21 @@ bool kingInCheck(const uint_least64_t *board, const bool color) {
return inCheck(board, bitboardGetMask(board, king), color);
}
static uint_least8_t getCastleRankI(bool color) {
uint_least8_t getBaseRank(bool color) {
if(color == WHITE) {
return (BOARD_SIZE - 1) * BOARD_SIZE;
return BOARD_SIZE - 1;
}
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) {
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 rookDst = getCastleRankI(color) + (spezialMove == SHORT_CASTLE ? 5 : 3);
const uint_least8_t rookSrc = getBaseRankI(color) + (spezialMove == SHORT_CASTLE ? BOARD_SIZE - 1 : 0);
const uint_least8_t rookDst = getBaseRankI(color) + (spezialMove == SHORT_CASTLE ? 5 : 3);
const struct piece_t rook = {ROOK, color};
bitboardSet(board, rook, undo ? rookSrc : rookDst);
bitboardClear(board, rook, undo ? rookDst : rookSrc);
@ -226,7 +230,8 @@ static void movePawn(struct addMoveCtx_t ctx, bool color, uint_least8_t src, uin
struct move_t *moves = ctx.moves;
uint_least8_t *movesLength = ctx.movesLength;
const struct piece_t piece = {PAWN, color};
if(promotion && (color == WHITE && dst < BOARD_SIZE || color == BLACK && dst >= BOARD_SIZE * (BOARD_SIZE - 1))) {
const uint_least8_t rankI = getBaseRankI(color);
if(promotion && (color == WHITE && dst < rankI || color == BLACK && dst >= rankI)) {
for(uint_least8_t promotionPiece = QUEEN; promotionPiece < PAWN; ++promotionPiece) {
addMove(ctx, piece, src, dst, spezialMove, promotionPiece);
}
@ -248,7 +253,7 @@ uint_least8_t pieceValidMoves(struct gameState_t gameState, struct piece_t piece
addPreGenMoves(addmoveCtx, KING_MOVES, src, piece);
const struct castle_t canCastle = gameState.canCastle[piece.color];
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 shortCastleCheckMask = (uint_least64_t)0b11 << (4 + rankShift);
const uint_least64_t longCastleMask = (uint_least64_t)0b111 << (1 + rankShift);
@ -363,7 +368,7 @@ struct gameState_t makeMove(struct gameState_t gameState, struct move_t move) {
canCastleCurrentPlayer->shortCastle = false;
}
else {
setCastleInfo(canCastleCurrentPlayer, move.src - getCastleRankI(gameState.color));
setCastleInfo(canCastleCurrentPlayer, move.src - getBaseRankI(gameState.color));
}
}
}
@ -371,7 +376,7 @@ struct gameState_t makeMove(struct gameState_t gameState, struct move_t move) {
// if the rook is captured
struct castle_t *canCastleOther = gameState.canCastle + !gameState.color;
if(canCastleOther->longCastle || canCastleOther->shortCastle) {
setCastleInfo(canCastleOther, move.dst - getCastleRankI(!gameState.color));
setCastleInfo(canCastleOther, move.dst - getBaseRankI(!gameState.color));
}
}
{