Пример #1
0
void unmake_move(Move move)
{
    turn_to_move = not_turn_to_move;
    ply -= 1;
    int direction_of_pawns = turn_to_move == WHITE? -10: 10;
    int from = move_from(move);
    int to = move_to(move);
    int figure = board[move_to(move)];
    int broken = move_broken(move);
    int turn = move_turn(move);

    if(turn)
        board[from] = create_figure(turn_to_move, PAWN);
    else
        board[from] = figure;
    
    if(get_value(figure) == PAWN && to == ply->en_passant)
    {
        board[to] = EMPTY;
        board[to - direction_of_pawns] = create_figure(not_turn_to_move, PAWN);
    }
    else
        board[to] = broken;
    
    if(get_value(figure) == KING)
    {
        int horizontal;
        if(turn_to_move == WHITE)
        {
            place_of_white_king = from;
            horizontal = 90;
        }
        else
        {
            place_of_black_king = from;
            horizontal = 20;
        }
        if(from - to == 2)
        {
            board[horizontal + 1] = board[horizontal + 4];
            board[horizontal + 4] = EMPTY;
        }
        else if(to - from == 2)
        {
            board[horizontal + 8] = board[horizontal + 6];
            board[horizontal + 6] = EMPTY;
        }
    }
}
Пример #2
0
Move str_to_move(char *string)
{
    for(int i = 0; i < 4; i += 1)
        if(string[i] == '\0') return 0;
    if(!((string[0] >= 'a' && string[0] <= 'h') &&
         (string[1] >= '1' && string[1] <= '8') &&
         (string[2] >= 'a' && string[2] <= 'h') &&
         (string[3] >= '1' && string[3] <= '8'))) return 0;
    
    int from = ('8' - string[1] + 2) * 10 + (string[0] - 'a' + 1);
    int to   = ('8' - string[3] + 2) * 10 + (string[2] - 'a' + 1);
    int broken = board[to];
    int turn = 0;
    switch(string[4])
    {
        case 'q':  turn = create_figure(turn_to_move, QUEEN); break;
        case 'r':  turn = create_figure(turn_to_move, ROOK); break;
        case 'b':  turn = create_figure(turn_to_move, BISHOP); break;
        case 'n':  turn = create_figure(turn_to_move, KNIGHT); break;
    }
    return create_move(from, to, broken, turn);
}
Пример #3
0
int in_check(int turn_to_move)
{
    int direction_of_pawns = turn_to_move == WHITE? -10: 10;
    int captures_of_pawns[2] = {direction_of_pawns + 1, direction_of_pawns - 1};
    int place_of_king = turn_to_move == WHITE? place_of_white_king:
                                               place_of_black_king;
        
    for(int i = 0; i < 2; i += 1)
    {
        int tmp = place_of_king + captures_of_pawns[i];
        if(board[tmp] == create_figure(not_turn_to_move, PAWN))
            return 1;
    }
    for(int i = 0; i < 8; i += 1)
    {
        int tmp = place_of_king + moves_of_king[i];
        if(board[tmp] == create_figure(not_turn_to_move, KING))
            return 1;
    }
    for(int i = 0; i < 8; i += 1)
    {
        int tmp = place_of_king + moves_of_knight[i];
        if(board[tmp] == create_figure(not_turn_to_move, KNIGHT))
            return 1;
    }
    for(int i = 0; i < 4; i += 1)
    {
        int inc = directions_of_bishop[i];
        int x = place_of_king + inc;
        while(board[x] == EMPTY)
            x += inc;
        if(board[x] == create_figure(not_turn_to_move, QUEEN) ||
           board[x] == create_figure(not_turn_to_move, BISHOP))
                return 1;
    }
    for(int i = 0; i < 4; i += 1)
    {
        int inc = directions_of_rook[i];
        int x = place_of_king + inc;
        while(board[x] == EMPTY)
            x += inc;
        if(board[x] == create_figure(not_turn_to_move, QUEEN) ||
           board[x] == create_figure(not_turn_to_move, ROOK))
                return 1;
    }
    return 0;
}
Пример #4
0
void main()
{
    char c;
    int gata = 0;
    double xx1[DIM], xx2[DIM], yy1[DIM], yy2[DIM];

    initialize_graphic_mode();
    initialize_variable_spaces();
    create_figure();
    draw_figure();
    draw_axes();
    draw_line();

    do
    {
        c = getch();
        for (int i = 0; i < DIM; i++)
        {
            xx1[i] = x1[i];
            xx2[i] = x2[i];
            yy1[i] = y1[i];
            yy2[i] = y2[i];
        }
        switch (c)
        {
        case 9:
            idx++;
            if (idx == 9)
                idx = 1;
            variable_space(1);
            break;
        case '+':
            modify_variable(1);
            break;
        case '-':
            modify_variable(0);
            break;
        case 't':
            draw_figure();
            translate(transX, transY);
            draw_figure();
            break;
        case 's':
            draw_figure();
            scale(scaleX, scaleY);
            draw_figure();
            break;
        case 'c':
            draw_figure();
            center_rotate(rotA);
            draw_figure();
            break;
        case 'r':
            draw_figure();
            origin_rotate(rotA);
            draw_figure();
            break;
        case 'x':
            draw_figure();
            Ox_simetry();
            draw_figure();
            break;
        case 'y':
            draw_figure();
            Oy_simetry();
            draw_figure();
            break;
        case 'o':
            draw_figure();
            origin_simetry();
            draw_figure();
            break;
        case 'd':
            draw_figure();
            random_line_simetry(simX, simY, simA);
            draw_figure();
            break;
        case 27:
            gata = 1;
            break;
        case 0:
            c = getch();
            switch (c)
            {
            case 15:
                idx--;
                if (idx == 0)
                    idx = 8;
                variable_space(0);
                break;
            case 80:
                draw_axes();
                if (y < 427)
                    y++;
                draw_axes();
                break;
            case 72:
                draw_axes();
                if (y > 0)
                    y--;
                draw_axes();
                break;
            case 77:
                draw_axes();
                if (x < 638)
                    x++;
                draw_axes();
                break;
            case 75:
                draw_axes();
                if (x > 0)
                    x--;
                draw_axes();
                break;
            }
        }
        if (not_on_the_screen())
        {
            draw_figure();
            for (int i = 0; i < DIM; i++)
            {
                x1[i] = xx1[i];
                x2[i] = xx2[i];
                y1[i] = yy1[i];
                y2[i] = yy2[i];
            }
            draw_figure();
        }
    }
    while (!gata);

    closegraph();
}
Пример #5
0
int generate_moves(Move *movelist)
{
    int horizontal2 = turn_to_move == WHITE? 8 : 3;
    int horizontal7 = turn_to_move == WHITE? 3 : 8;
    int direction_of_pawns = turn_to_move == WHITE? -10: 10;
    int captures_of_pawns[2] = {direction_of_pawns + 1, direction_of_pawns - 1};
    int place_of_king = turn_to_move == WHITE? place_of_white_king:
                                               place_of_black_king;
    int n = 0;
    
    int king_castling, queen_castling;
    if(turn_to_move == WHITE)
    {
        king_castling  = ply->castlings & K_castling;
        queen_castling = ply->castlings & Q_castling;
    }
    else
    {
        king_castling  = ply->castlings & k_castling;
        queen_castling = ply->castlings & q_castling;
    }
    int is_in_check = in_check(turn_to_move);
    for(int i = 0; i < 8; i += 1)
    {
        int i_move = moves_of_king[i];
        int tmp = place_of_king + i_move;
        if(board[tmp] == EMPTY || get_color(board[tmp]) == not_turn_to_move)
        {
            int i_move_is_possible = 0;
            Move tmp_move = create_move(place_of_king, tmp, board[tmp], 0);
            make_move(tmp_move);
            if(!in_check(not_turn_to_move))
            {
                i_move_is_possible = 1;
                movelist[n] = tmp_move;
                n += 1;
            }
            unmake_move(tmp_move);
            
            if(is_in_check || !i_move_is_possible || board[tmp] != EMPTY)
                continue;
            if(i_move == 1 && king_castling && board[place_of_king + 2] == EMPTY)
            {
                movelist[n] = create_move(place_of_king, place_of_king + 2, 0, 0);
                n += 1;
            }
            if(i_move == -1 && queen_castling &&
               board[place_of_king - 2] == EMPTY &&
               board[place_of_king - 3] == EMPTY)
            {
                movelist[n] = create_move(place_of_king, place_of_king - 2, 0, 0);
                n += 1;
            }
        }
    }
    
    if(ply->en_passant)
    {
        for(int i = 0; i < 2; i += 1)
        {
            int tmp = ply->en_passant - captures_of_pawns[i];
            if(board[tmp] == create_figure(turn_to_move, PAWN))
            {
                movelist[n] = create_move(tmp, ply->en_passant, 0, 0);
                n += 1;
            }
        }
    }
    for(int i64 = 0; i64 < 64; i64 += 1)
    {
        int current_cell = board64[i64];
        int figure = board[current_cell];
        if(get_color(figure) != turn_to_move)
            continue;
        switch(get_value(figure))
        {
            case QUEEN:
                for(int i = 0; i < 8; i += 1)
                {
                    int inc = directions_of_queen[i];
                    int x = current_cell + inc;
                    while(board[x] == EMPTY)
                    {
                        movelist[n] = create_move(current_cell, x, 0, 0);
                        n += 1;
                        x += inc;
                    }
                    if(get_color(board[x]) == not_turn_to_move )
                    {
                        movelist[n] = create_move(current_cell, x, board[x], 0);
                        n += 1;
                    }
                }
                break;
            case ROOK:
                for(int i = 0; i < 4; i += 1)
                {
                    int inc = directions_of_rook[i];
                    int x = current_cell + inc;
                    while(board[x] == EMPTY)
                    {
                        movelist[n] = create_move(current_cell, x, 0, 0);
                        n += 1;
                        x += inc;
                    }
                    if(get_color(board[x]) == not_turn_to_move)
                    {
                        movelist[n] = create_move(current_cell, x, board[x], 0);
                        n += 1;
                    }
                }
                break;
            case BISHOP:
                for(int i = 0; i < 4; i += 1)
                {
                    int inc = directions_of_bishop[i];
                    int x = current_cell + inc;
                    while(board[x] == EMPTY)
                    {
                        movelist[n] = create_move(current_cell, x, 0, 0);
                        n += 1;
                        x += inc;
                    }
                    if(get_color(board[x]) == not_turn_to_move)
                    {
                        movelist[n] = create_move(current_cell, x, board[x], 0);
                        n += 1;
                    }
                }
                break;
            case KNIGHT:
                for(int i = 0; i < 8; i += 1)
                {
                    int tmp = current_cell + moves_of_knight[i];
                    if(board[tmp] == EMPTY ||
                        get_color(board[tmp]) == not_turn_to_move)
                    {
                        movelist[n] = create_move(current_cell, tmp, board[tmp], 0);
                        n += 1;
                    }
                }
                break;
            case PAWN:
                ;int tmp = current_cell + direction_of_pawns;
                if(board[tmp] == EMPTY)
                {
                    if(current_cell/10 == horizontal7)
                    {
                        for(int j = 0; j < 4; j += 1)
                        {
                            movelist[n] = create_move(current_cell, tmp, 0,
                                create_figure(turn_to_move, turn_figures[j]));
                            n += 1;
                        }
                    }
                    else
                    {
                        movelist[n] = create_move(current_cell, tmp, 0, 0);
                        n += 1;
                    }
                    tmp += direction_of_pawns;
                    if(board[tmp] == EMPTY && current_cell/10 == horizontal2)
                    {
                        movelist[n] = create_move(current_cell, tmp, 0, 0);
                        n += 1;
                    }
                }
                for(int i = 0; i < 2; i += 1)
                {
                    int tmp = current_cell + captures_of_pawns[i];
                    if(get_color(board[tmp]) == not_turn_to_move)
                    {
                        if(current_cell/10 == horizontal7)
                        {
                            for(int j = 0; j < 4; j += 1)
                            {
                                movelist[n] = create_move(current_cell, tmp, board[tmp],
                                    create_figure(turn_to_move, turn_figures[j]));
                                n += 1;
                            }
                        }
                        else
                        {
                            movelist[n] = create_move(current_cell, tmp, board[tmp], 0);
                            n += 1;
                        }
                    }
                }
        }
    }
    for(int i = 0; i < n; i += 1)
    {
        Move i_move = movelist[i];
        make_move(i_move);
        if(in_check(not_turn_to_move))
        {
            movelist[i] = movelist[n - 1];
            n -= 1;
            i -= 1;
        }
        unmake_move(i_move);
    }
    return n;
}
Пример #6
0
void make_move(Move move)
{
    U64 hash = ply->hash;
    int direction_of_pawns = turn_to_move == WHITE? -10: 10;
    int from = move_from(move);
    int figure = board[from];
    int to = move_to(move);
    int turn = move_turn(move);
    int broken = move_broken(move);
    board[from] = EMPTY;
    hash ^= zobrist_piecesquare[figure][from];
    if(turn)
    {
        board[to] = turn;
        hash ^= zobrist_piecesquare[turn][to];
    }
    else
    {
        board[to] = figure;
        hash ^= zobrist_piecesquare[figure][to];
    }
    if(get_value(figure) == PAWN && to == ply->en_passant)
    {
        int tmp = to - direction_of_pawns;
        board[tmp] = EMPTY;
        hash ^= zobrist_piecesquare[create_figure(not_turn_to_move, PAWN)][tmp];
    }
    else if(broken)
    {
        hash ^= zobrist_piecesquare[broken][to];
    }
    if(ply->en_passant)
    {
        hash ^= zobrist_en_passant[ply->en_passant];
    }
    
    ply += 1;
    
    if(get_value(figure) == PAWN && to - from == direction_of_pawns * 2)
    {
        ply->en_passant = from + direction_of_pawns;
        hash ^= zobrist_en_passant[ply->en_passant];
    }
    else
    {
        ply->en_passant = 0;
    }
    
    ply->castlings = (ply - 1)->castlings;
    if(get_value(figure) == KING)
    {
        int horizontal;
        if(turn_to_move == WHITE)
        {
            place_of_white_king = to;
            make_white_castlings_is_incorrect();
            horizontal = 90;
        }
        else
        {
            place_of_black_king = to;
            make_black_castlings_is_incorrect();
            horizontal = 20;
        }
        if(from - to == 2)
        {
            board[horizontal + 4] = board[horizontal + 1];
            board[horizontal + 1] = EMPTY;
        }
        else if(to - from == 2)
        {
            board[horizontal + 6] = board[horizontal + 8];
            board[horizontal + 8] = EMPTY;
        }
    }
    if(board[98] != create_figure(WHITE, ROOK))
        make_K_castling_is_incorrect();
    if(board[91] != create_figure(WHITE, ROOK))
        make_Q_castling_is_incorrect();
    if(board[28] != create_figure(BLACK, ROOK))
        make_k_castling_is_incorrect();
    if(board[21] != create_figure(BLACK, ROOK))
        make_q_castling_is_incorrect();
    
    if(broken || get_value(figure) == PAWN)
        ply->number_of_insignificant_plies = 0;
    else
        ply->number_of_insignificant_plies = 
            (ply - 1)->number_of_insignificant_plies + 1;
    turn_to_move = not_turn_to_move;
    
    hash ^= zobrist_color;
    hash ^= zobrist_castlings[(ply - 1)->castlings];
    hash ^= zobrist_castlings[ply->castlings];
    ply->hash = hash;
}
Пример #7
0
void setup_position(char* fen)
{
    ply = begin_ply;
    turn_to_move = WHITE;
    ply->en_passant = 0;
    ply->castlings = 0;
    ply->number_of_insignificant_plies = 0;
    for(int i = 0; i < 120; i += 1) board[i] = BORDER;
    for(int i = 0; i < 64; i += 1) board[board64[i]] = EMPTY;
    
    int i = 0;
    int current_cell = 0;
    for(; fen[i] != ' ' && fen[i] != '\0'; i += 1, current_cell += 1)
    {
        int index_of_figure = board64[current_cell]; 
        switch(fen[i])
        {
            case '/':
                current_cell -= 1;
            break; case 'K':
                place_of_white_king = index_of_figure;
                board[index_of_figure] = create_figure(WHITE, KING);
            break; case 'Q':
                board[index_of_figure] = create_figure(WHITE, QUEEN);
            break; case 'R':
                board[index_of_figure] = create_figure(WHITE, ROOK);
            break; case 'B':
                board[index_of_figure] = create_figure(WHITE, BISHOP);
            break; case 'N':
                board[index_of_figure] = create_figure(WHITE, KNIGHT);
            break; case 'P':
                board[index_of_figure] = create_figure(WHITE, PAWN);
            break; case 'k':
                place_of_black_king = index_of_figure;
                board[index_of_figure] = create_figure(BLACK, KING);
            break; case 'q':
                board[index_of_figure] = create_figure(BLACK, QUEEN);
            break; case 'r':
                board[index_of_figure] = create_figure(BLACK, ROOK);
            break; case 'b':
                board[index_of_figure] = create_figure(BLACK, BISHOP);
            break; case 'n':
                board[index_of_figure] = create_figure(BLACK, KNIGHT);
            break; case 'p':
                board[index_of_figure] = create_figure(BLACK, PAWN);
            break; default:
                current_cell += fen[i] - '0' - 1;
        }
    }
    if(fen[i] == '\0')
    {
        setup_hash();
        return;
    }
    i += 1;
    
    if(fen[i] == 'w')      turn_to_move = WHITE;
    else if(fen[i] == 'b') turn_to_move = BLACK;
    i += 1;
    if(fen[i] == '\0')
    {
        setup_hash();
        return;
    }
    i += 1;
    
    for(; fen[i] != ' ' && fen[i] != '\0'; i += 1)
    {
        switch(fen[i])
        {
            case 'K': ply->castlings |= K_castling; break;
            case 'Q': ply->castlings |= Q_castling; break;
            case 'k': ply->castlings |= k_castling; break;
            case 'q': ply->castlings |= q_castling; break;
        }
    }
    if(fen[i] == '\0')
    {
        setup_hash();
        return;
    }
    i += 1;
    
    
    if(fen[i] == '-') i += 1;
    else
    {
        ply->en_passant = ('8' - fen[i + 1] + 2) * 10 + fen[i] - 'a' + 1;
        i += 2;
    }
    if(fen[i] == '\0')
    {
        setup_hash();
        return;
    }
    i += 1;
    
    if(fen[i + 1] == ' ' || fen[i + 1] == '\0')
        ply->number_of_insignificant_plies = fen[i] - '0';
    else
        ply->number_of_insignificant_plies = ((fen[i] - '0') * 10 + fen[i + 1] - '0');
    
    setup_hash();
}
Пример #8
0
void print_position(int is_reversed)
{
    for(int i = 0; i < 8; i += 1)
    {
        for(int j = 0; j < 8; j += 1)
        {
            int index = is_reversed ? (7 - i) * 8 + 7 - j: i * 8 + j;
            switch(board[board64[index]])
            {
                case EMPTY: printf(".");
                break; case create_figure(WHITE, KING)  : printf("K");
                break; case create_figure(WHITE, QUEEN) : printf("Q");
                break; case create_figure(WHITE, ROOK)  : printf("R");
                break; case create_figure(WHITE, BISHOP): printf("B");
                break; case create_figure(WHITE, KNIGHT): printf("N");
                break; case create_figure(WHITE, PAWN)  : printf("P");
                break; case create_figure(BLACK, KING)  : printf("k");
                break; case create_figure(BLACK, QUEEN) : printf("q");
                break; case create_figure(BLACK, ROOK)  : printf("r");
                break; case create_figure(BLACK, BISHOP): printf("b");
                break; case create_figure(BLACK, KNIGHT): printf("n");
                break; case create_figure(BLACK, PAWN)  : printf("p");
            }
        }
        printf("\n");
    }
    printf("\n");
}
Пример #9
0
int evaluate(int alpha, int beta)
{
    Entry *entry = hash_get_entry();
    if(entry != NULL)
    {
        int eval = entry->eval, flag = entry->flag;
        if(flag != LESS_THAN_ALPHA && eval >= beta)
            return beta;
        if(flag != MORE_THAN_BETA && eval <= alpha)
            return alpha;
        if(flag == BETWEEN_ALPHA_AND_BETA)
            return eval;
    }
    
    int white_pawns_in_verticals[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    int black_pawns_in_verticals[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    int evaluation = 0;
    int current_figure_material = 0;
    int white_king_tropism = 0;
    int black_king_tropism = 0;
    
    for(int i = 0; i < 64; i += 1)
    {
        int current_cell = board64[i];
        int figure = board[current_cell];
        int color = get_color(figure);
        int value = get_value(figure);
        
        if(figure == EMPTY || value == KING) continue;
        
        int material_value = get_material_value(color, value);
        if(value != PAWN) current_figure_material += abs(material_value);
        evaluation += material_value;
        evaluation += get_PST_value(figure, i);
        
        if(color == BLACK)
        {
            white_king_tropism += get_distance_bonus(current_cell, figure,
                                                        place_of_white_king);
        }
        else
        {
            black_king_tropism += get_distance_bonus(current_cell, figure,
                                                        place_of_black_king);
        }
        
        if(value == PAWN)
        {
            int vertical = current_cell % 10;
            if(color == WHITE)
                white_pawns_in_verticals[vertical] += 1;
            else
                black_pawns_in_verticals[vertical] += 1;
        }
    }
    
    
    int white_pawn_shield = 0;
    if (place_of_white_king == H1 || place_of_white_king == H2 ||
        place_of_white_king == G1 || place_of_white_king == G2 ||
        place_of_white_king == F1)
    {
        if(board[H2] == create_figure(WHITE, PAWN))
            white_pawn_shield += PAWN_ON_HORIONTAL_2;
        else if(board[H3] == create_figure(WHITE, PAWN))
            white_pawn_shield += PAWN_ON_HORIONTAL_3;
        if(board[G2] == create_figure(WHITE, PAWN))
            white_pawn_shield += PAWN_ON_HORIONTAL_2;
        else if(board[G3] == create_figure(WHITE, PAWN))
            white_pawn_shield += PAWN_ON_HORIONTAL_3;
        if(board[F2] == create_figure(WHITE, PAWN))
            white_pawn_shield += PAWN_ON_HORIONTAL_2 / 2;
        if(board[H1] == create_figure(WHITE, ROOK) ||
           board[H2] == create_figure(WHITE, ROOK) ||
           board[G1] == create_figure(WHITE, ROOK))
        {
            evaluation += UNDEVELOPED_ROOK_PENALTY;
        }
    }
    else if(place_of_white_king == A1 || place_of_white_king == A2 ||
            place_of_white_king == B1 || place_of_white_king == B2 ||
            place_of_white_king == C1)
    {
        if(board[A2] == create_figure(WHITE, PAWN))
            white_pawn_shield += PAWN_ON_HORIONTAL_2;
        else if(board[A3] == create_figure(WHITE, PAWN))
            white_pawn_shield += PAWN_ON_HORIONTAL_3;
        if(board[B2] == create_figure(WHITE, PAWN))
            white_pawn_shield += PAWN_ON_HORIONTAL_2;
        else if(board[B3] == create_figure(WHITE, PAWN))
            white_pawn_shield += PAWN_ON_HORIONTAL_3;
        if(board[C2] == create_figure(WHITE, PAWN))
            white_pawn_shield += PAWN_ON_HORIONTAL_2 / 2;
        if(board[A1] == create_figure(WHITE, ROOK) ||
           board[A2] == create_figure(WHITE, ROOK) ||
           board[B1] == create_figure(WHITE, ROOK))
        {
            evaluation += UNDEVELOPED_ROOK_PENALTY;
        }
    }
    else
    {
        white_pawn_shield = KING_IN_CENTER_PENALTY;
    }
    int black_pawn_shield = 0;
    if (place_of_black_king == H8 || place_of_black_king == H7 ||
        place_of_black_king == G8 || place_of_black_king == G7 ||
        place_of_black_king == F8)
    {
        if(board[H7] == create_figure(BLACK, PAWN))
            black_pawn_shield += PAWN_ON_HORIONTAL_2;
        else if(board[H6] == create_figure(BLACK, PAWN))
            black_pawn_shield += PAWN_ON_HORIONTAL_3;
        if(board[G7] == create_figure(BLACK, PAWN))
            black_pawn_shield += PAWN_ON_HORIONTAL_2;
        else if(board[G6] == create_figure(BLACK, PAWN))
            black_pawn_shield += PAWN_ON_HORIONTAL_3;
        if(board[F7] == create_figure(BLACK, PAWN))
            black_pawn_shield += PAWN_ON_HORIONTAL_2 / 2;
        if(board[H8] == create_figure(BLACK, ROOK) ||
           board[H7] == create_figure(BLACK, ROOK) ||
           board[G8] == create_figure(BLACK, ROOK))
        {
            evaluation += -UNDEVELOPED_ROOK_PENALTY;
        }
    }
    else if(place_of_black_king == A8 || place_of_black_king == A8 ||
            place_of_black_king == B8 || place_of_black_king == B8 ||
            place_of_black_king == C8)
    {
        if(board[A7] == create_figure(BLACK, PAWN))
            black_pawn_shield += PAWN_ON_HORIONTAL_2;
        else if(board[A6] == create_figure(BLACK, PAWN))
            black_pawn_shield += PAWN_ON_HORIONTAL_3;
        if(board[B7] == create_figure(BLACK, PAWN))
            black_pawn_shield += PAWN_ON_HORIONTAL_2;
        else if(board[B6] == create_figure(BLACK, PAWN))
            black_pawn_shield += PAWN_ON_HORIONTAL_3;
        if(board[C7] == create_figure(BLACK, PAWN))
            black_pawn_shield += PAWN_ON_HORIONTAL_2 / 2;
        if(board[A8] == create_figure(BLACK, ROOK) ||
           board[A7] == create_figure(BLACK, ROOK) ||
           board[B8] == create_figure(BLACK, ROOK))
        {
            evaluation += -UNDEVELOPED_ROOK_PENALTY;
        }
    }
    else
    {
        black_pawn_shield = KING_IN_CENTER_PENALTY;
    }
    
    int white_king_safety = (white_pawn_shield - white_king_tropism);
    int black_king_safety = (black_pawn_shield - black_king_tropism);
    evaluation += ((white_king_safety - black_king_safety)
                        * current_figure_material / MAX_FIGURE_MATERIAL);
    
    
    int white_isolated = 0, black_isolated = 0;
    int white_doubled = 0, black_doubled = 0;
    for(int i = 1; i <= 8; i += 1)
    {
        if(white_pawns_in_verticals[i - 1] == 0 &&
           white_pawns_in_verticals[i + 1] == 0)
        {
            white_isolated += white_pawns_in_verticals[i];
        }
        else if(white_pawns_in_verticals[i] > 1)
        {
            white_doubled += white_pawns_in_verticals[i];
        }
        
        if(black_pawns_in_verticals[i - 1] == 0 &&
           black_pawns_in_verticals[i + 1] == 0)
        {
            black_isolated += white_pawns_in_verticals[i];
        }
        else if(white_pawns_in_verticals[i] > 1)
        {
            black_doubled += white_pawns_in_verticals[i];
        }
    }
    evaluation += (white_isolated - black_isolated) * PAWN_ISOLATED_PENALTY;
    evaluation += (white_doubled - black_doubled) * PAWN_DOUBLED_PENALTY;
    
    return turn_to_move == WHITE? evaluation: -evaluation;
}