Esempio n. 1
0
void chess_generate_init(void)
{
    static int initialized = 0;
    ChessSquare sq;
    int dirs, d;
    int slide, jump;
    int file, rank;
    int to_file, to_rank;

    if (initialized)
        return;
    initialized = 1;

    for (sq = CHESS_SQUARE_A1; sq <= CHESS_SQUARE_H8; sq++)
    {
        dirs = 0;
        file = chess_square_file(sq);
        rank = chess_square_rank(sq);
        for (d = 0; d < 8; d++)
        {
            slide = slides_array[d];
            to_file = file + chess_square_file(slide + 36) - 4;
            to_rank = rank + chess_square_rank(slide + 36) - 4;
            if (to_file >= CHESS_FILE_A && to_file <= CHESS_FILE_H
            &&  to_rank >= CHESS_RANK_1 && to_rank <= CHESS_RANK_8)
                dirs |= dirs_array[d];
        }

        slide_dirs[sq] = dirs;
    }

    for (sq = CHESS_SQUARE_A1; sq <= CHESS_SQUARE_H8; sq++)
    {
        dirs = 0;
        file = chess_square_file(sq);
        rank = chess_square_rank(sq);
        for (d = 0; d < 8; d++)
        {
            jump = jumps_array[d];
            to_file = file + chess_square_file(jump + 36) - 4;
            to_rank = rank + chess_square_rank(jump + 36) - 4;
            if (to_file >= CHESS_FILE_A && to_file <= CHESS_FILE_H
            &&  to_rank >= CHESS_RANK_1 && to_rank <= CHESS_RANK_8)
                dirs |= dirs_array[d];
        }

        jump_dirs[sq] = dirs;
    }
}
Esempio n. 2
0
void chess_position_undo_move(ChessPosition* position, ChessUnmove unmove)
{
    ChessSquare from = chess_unmove_from(unmove);
    ChessSquare to = chess_unmove_to(unmove);
    ChessUnmoveCaptured captured = chess_unmove_captured(unmove);
    ChessUnmoveEp ep = chess_unmove_ep(unmove);

    ChessPiece piece;
    ChessColor other = position->to_move;
    ChessColor color = chess_color_other(other);
    ChessFile file;

    if (from == 0 && to == 0)
    {
        /* Null move */
        piece = CHESS_PIECE_NONE;
    }
    else
    {
        if (chess_unmove_promotion(unmove))
            piece = chess_piece_of_color(CHESS_PIECE_WHITE_PAWN, color);
        else
            piece = position->piece[to];
        assert(color == chess_piece_color(piece));

        /* Unmove the piece */
        position->piece[from] = piece;
        position->piece[to] = captured_piece(captured, other);

        /* Handle castling */
        if (piece == CHESS_PIECE_WHITE_KING && from == CHESS_SQUARE_E1)
        {
            if (to == CHESS_SQUARE_G1)
            {
                position->piece[CHESS_SQUARE_F1] = CHESS_PIECE_NONE;
                position->piece[CHESS_SQUARE_H1] = CHESS_PIECE_WHITE_ROOK;
            }
            else if (to == CHESS_SQUARE_C1)
            {
                position->piece[CHESS_SQUARE_D1] = CHESS_PIECE_NONE;
                position->piece[CHESS_SQUARE_A1] = CHESS_PIECE_WHITE_ROOK;
            }
        }
        else if (piece == CHESS_PIECE_BLACK_KING && from == CHESS_SQUARE_E8)
        {
            if (to == CHESS_SQUARE_G8)
            {
                position->piece[CHESS_SQUARE_F8] = CHESS_PIECE_NONE;
                position->piece[CHESS_SQUARE_H8] = CHESS_PIECE_BLACK_ROOK;
            }
            else if (to == CHESS_SQUARE_C8)
            {
                position->piece[CHESS_SQUARE_D8] = CHESS_PIECE_NONE;
                position->piece[CHESS_SQUARE_A8] = CHESS_PIECE_BLACK_ROOK;
            }
        }
        position->castle = chess_unmove_castle(unmove);
    }

    /* Handle ep */
    if (ep == CHESS_UNMOVE_EP_NONE)
    {
        position->ep = CHESS_FILE_INVALID;
    }
    else if (ep == CHESS_UNMOVE_EP_CAPTURE)
    {
        assert(piece == CHESS_PIECE_WHITE_PAWN || piece == CHESS_PIECE_BLACK_PAWN);

        /* Restore the captured pawn */
        file = chess_square_file(to);
        if (color == CHESS_COLOR_WHITE)
            position->piece[chess_square_from_fr(file, CHESS_RANK_5)] = CHESS_PIECE_BLACK_PAWN;
        else
            position->piece[chess_square_from_fr(file, CHESS_RANK_4)] = CHESS_PIECE_WHITE_PAWN;
        position->ep = file;
    }
    else
    {
        position->ep = ep - CHESS_UNMOVE_EP_AVAILABLE;
    }

    /* Update king positions */
    if (piece == CHESS_PIECE_WHITE_KING)
        position->wking = from;
    else if (piece == CHESS_PIECE_BLACK_KING)
        position->bking = from;

    /* Update move counters */
    position->fifty = chess_unmove_fifty(unmove);

    position->to_move = color;
    if (position->to_move == CHESS_COLOR_BLACK)
        position->move_num--;
}
Esempio n. 3
0
ChessUnmove chess_position_make_move(ChessPosition* position, ChessMove move)
{
    ChessSquare from = chess_move_from(move);
    ChessSquare to = chess_move_to(move);
    ChessMovePromote promote = chess_move_promotes(move);
    ChessPiece piece;
    ChessColor color = position->to_move;
    ChessUnmoveEp ep;
    ChessUnmoveCaptured captured;
    ChessCastleState castle = position->castle;
    int fifty = position->fifty;

    /* Move the piece */
    if (move == CHESS_MOVE_NULL)
    {
        piece = CHESS_PIECE_NONE;
        captured = CHESS_UNMOVE_CAPTURED_NONE;
    }
    else
    {
        piece = position->piece[from];
        captured = capture_piece(position->piece[to]);

        position->piece[from] = CHESS_PIECE_NONE;
        if (promote == CHESS_MOVE_PROMOTE_NONE)
        {
            position->piece[to] = piece;
            if (piece == CHESS_PIECE_WHITE_KING)
                position->wking = to;
            else if (piece == CHESS_PIECE_BLACK_KING)
                position->bking = to;
        }
        else
        {
            position->piece[to] = promoted_piece(promote, color);
        }

        /* Handle castling */
        if (piece == CHESS_PIECE_WHITE_KING && from == CHESS_SQUARE_E1)
        {
            if (to == CHESS_SQUARE_G1)
            {
                position->piece[CHESS_SQUARE_F1] = CHESS_PIECE_WHITE_ROOK;
                position->piece[CHESS_SQUARE_H1] = CHESS_PIECE_NONE;
            }
            else if (to == CHESS_SQUARE_C1)
            {
                position->piece[CHESS_SQUARE_D1] = CHESS_PIECE_WHITE_ROOK;
                position->piece[CHESS_SQUARE_A1] = CHESS_PIECE_NONE;
            }
        }
        else if (piece == CHESS_PIECE_BLACK_KING && from == CHESS_SQUARE_E8)
        {
            if (to == CHESS_SQUARE_G8)
            {
                position->piece[CHESS_SQUARE_F8] = CHESS_PIECE_BLACK_ROOK;
                position->piece[CHESS_SQUARE_H8] = CHESS_PIECE_NONE;
            }
            else if (to == CHESS_SQUARE_C8)
            {
                position->piece[CHESS_SQUARE_D8] = CHESS_PIECE_BLACK_ROOK;
                position->piece[CHESS_SQUARE_A8] = CHESS_PIECE_NONE;
            }
        }

        /* Check if castling availability was lost */
        if (position->castle & (CHESS_CASTLE_STATE_WKQ))
        {
            if (from == CHESS_SQUARE_A1 || to == CHESS_SQUARE_A1)
                position->castle &= ~CHESS_CASTLE_STATE_WQ;

            if (from == CHESS_SQUARE_H1 || to == CHESS_SQUARE_H1)
                position->castle &= ~CHESS_CASTLE_STATE_WK;

            if (from == CHESS_SQUARE_E1 || to == CHESS_SQUARE_E1)
                position->castle &= ~(CHESS_CASTLE_STATE_WKQ);
        }
        if (position->castle & (CHESS_CASTLE_STATE_BKQ))
        {
            if (from == CHESS_SQUARE_A8 || to == CHESS_SQUARE_A8)
                position->castle &= ~CHESS_CASTLE_STATE_BQ;

            if (from == CHESS_SQUARE_H8 || to == CHESS_SQUARE_H8)
                position->castle &= ~CHESS_CASTLE_STATE_BK;

            if (from == CHESS_SQUARE_E8 || to == CHESS_SQUARE_E8)
                position->castle &= ~(CHESS_CASTLE_STATE_BKQ);
        }
    }

    /* Handle ep */
    if (position->ep == CHESS_FILE_INVALID)
    {
        ep = CHESS_UNMOVE_EP_NONE;
    }
    else
    {
        if (piece == CHESS_PIECE_WHITE_PAWN && to == chess_square_from_fr(position->ep, CHESS_RANK_6))
        {
            position->piece[chess_square_from_fr(position->ep, CHESS_RANK_5)] = CHESS_PIECE_NONE;
            ep = CHESS_UNMOVE_EP_CAPTURE;
        }
        else if (piece == CHESS_PIECE_BLACK_PAWN && to == chess_square_from_fr(position->ep, CHESS_RANK_3))
        {
            position->piece[chess_square_from_fr(position->ep, CHESS_RANK_4)] = CHESS_PIECE_NONE;
            ep = CHESS_UNMOVE_EP_CAPTURE;
        }
        else
        {
            ep = CHESS_UNMOVE_EP_AVAILABLE + position->ep;
        }
    }

    /* Update ep on a double pawn move */
    if (piece == CHESS_PIECE_WHITE_PAWN && to - from == 16)
        position->ep = chess_square_file(to);
    else if (piece == CHESS_PIECE_BLACK_PAWN && from - to == 16)
        position->ep = chess_square_file(to);
    else
        position->ep = CHESS_FILE_INVALID;

    /* Update fifty counter only if a reversible move was played */
    if (piece == CHESS_PIECE_WHITE_PAWN || piece == CHESS_PIECE_BLACK_PAWN
        || captured != CHESS_UNMOVE_CAPTURED_NONE || castle != position->castle)
        position->fifty = 0;
    else
        position->fifty++;

    /* Update move counter */
    position->to_move = chess_color_other(position->to_move);
    if (position->to_move == CHESS_COLOR_WHITE)
        position->move_num++;

    return chess_unmove_make(from, to, captured,
        promote != CHESS_MOVE_PROMOTE_NONE, ep, castle, fifty);
}