fixed promotion menu
computer not working!
This commit is contained in:
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user