Я пишу шахматного бота и застрял здесь. Раньше программа использовала 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;
}
}