Шахматная программа C ++, выбрасывающая segfault на одну указанную c позицию ТОЛЬКО при использовании отладчика - PullRequest
0 голосов
/ 01 мая 2020

Я пишу шахматного бота и застрял здесь. Раньше программа использовала segfault при нормальной работе, теперь она выдает ТОЛЬКО при использовании отладчика, и это происходит только в одной конкретной позиции на доске. Ошибка возникает в этой строке

Move* moves = GameObj.get_all_moves(player, false);

Вот стек вызовов от отладчика. Стек вызовов Глядя на стек вызовов, я понял, что это должно быть что-то, связанное с распределением памяти (в чем я действительно слаб). В списке наблюдения я увидел, что для «ходов» был назначен правильный адрес. В чем может быть проблема? game.get_all_moves

Move* game::get_all_moves(string player, bool legal, bool debug){

Move *non_captures = nullptr;
Move *capture_start = nullptr;
Move *capture_end = nullptr;
int *temp = nullptr;
map<char, int> piece_vals;
set_piece_vals(piece_vals, player);
for(int i=0; i < 64; i++){
    if(get_player(this->game_board[i]) == player){
        temp = get_true_pos(this->get_true_target_area(i, player));
        for(; *temp != -1; temp++){
            if(legal)
                if(!this->make_move(i, *temp, player, true, false))
                    continue;
            Move *temp_move = new Move;
            temp_move->current = i;
            temp_move->target = *temp;
            temp_move->score = 0;
            if(this->game_board[*temp] != 'f'){
                // Capture
                temp_move->score = piece_vals[this->game_board[i]] - piece_vals[this->game_board[*temp]];
                temp_move->next = nullptr;
                if(capture_start == nullptr)
                    capture_start = temp_move;
                else
                    capture_end->next = temp_move;
                capture_end = temp_move;
            }
            else{
                temp_move->next = non_captures;
                non_captures = temp_move;
            }
        }
    }
}
// Sort Captures and Link the lists
if(capture_start != nullptr){
    sort_lists(capture_start, capture_end);
    capture_end->next = non_captures;
    return capture_start;
}
return non_captures;
}

get_true_pos -> возвращает указатель заголовка стека, содержащего индексы 1 с в наборе битов true_target_area -> Набор битов, представляющий позиции, которые может перемещать фигура. sorts_lists используется для сортировки очереди по ее оценке. минимакс

 int minimax(game GameObj, string max_player, string player, bool is_max, short int depth, int alpha, int beta, bool null_move){

game tempObj;

if(depth == 0)
    return heuristic(GameObj, player, max_player);
int val;

// Null Move
if(!null_move && depth >= R + 1 && check_null_move(GameObj, player)){
    val = -minimax(GameObj, max_player, reverse_player(player), !is_max, depth - R - 1, -beta, -beta + 1, true);
    if(val >= beta)
        return beta;
}

Move* moves = GameObj.get_all_moves(player, false);

if(is_max){
    for(;moves != nullptr; moves=moves->next){
        tempObj = game(GameObj);
        tempObj.make_move(moves->current, moves->target, player, false, true);
        val = minimax(tempObj, max_player, reverse_player(player), false, depth - 1, alpha, beta, null_move);
        alpha = max(alpha, val);
        if(beta <= alpha)
            break;
    }
    if(alpha == -1*pow(10, 5)){
        // No moves
        if(heuristic(GameObj, player, max_player) < -draw_cutoff && !GameObj.is_check(player))
            // Not in check implies draw...
            // Maximiser at a disadvantage, force a draw by providing high cutoff
            return pow(10, 5);
    }
    return alpha;
}
else{
    for(;moves != nullptr; moves=moves->next){
        tempObj = game(GameObj);
        tempObj.make_move(moves->current, moves->target, player, false, true);
        val = minimax(tempObj, max_player, reverse_player(player), true, depth - 1, alpha, beta, null_move);
        beta = min(val, beta);
        if(beta <= alpha)
            break;
    }
    if(beta == pow(10, 5)){
        if(heuristic(GameObj, player, max_player) > draw_cutoff && !GameObj.is_check(player))
            // Not in check implies draw...
            // Minimiser at a disadvantage, force a draw by providing high cutoff
            return -1*pow(10, 5);
    }
    return beta;
}

}
...