4 [main] open mchess 8784 cygwin_exception :: open_stackdumpfile: трассировка стека дампов в mchess.exe.stackdumpfile - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь создать простой шахматный движок, использующий альфа-бета-тестирование. Чтобы избежать трехкратного повторения, я сделал second_best, поэтому он будет возвращен, если повторяется тройное повторение, я не могу понять, в чем проблемавызывая ошибку, но я считаю, что это в файле ai.cc, потому что код работал нормально, прежде чем я его отредактировал.

, но я не понимаю, почему или как я ее решаю?

ai.cc :

#include <stdlib.h> // exit()
#include "ai.h"
#include "CMoveList.h"

/*
* zero, if the position is equal.
* 900+, if the opponent is check-mated.
* -999, if the side to move is check-mated.
*/

int AI::search(int alpha, int beta, int level)
{
    if (level == 0)
        return m_board.get_value(); // We are at leaf, just return the static evaluation.

    CMoveList moves;
    m_board.find_legal_moves(moves);
    int best_val = -999; // Assume the worst

                         // Search through all legal moves
    for (unsigned int i = 0; i<moves.size(); ++i)
    {
        if (best_val >= beta)
        {
            // This is the alpha-beta pruning.
            // Stop searching, if we already have found a "killer" move.
            break;
        }
        if (best_val > alpha)
        {
            // This is part of the alpha-beta pruning too.
            // Tighten the search window.
            alpha = best_val;
        }
        CMove move = moves[i];
        // Do a recursive search
        m_board.make_move(move);
        CMoveList tempMoves;
        m_board.find_legal_moves(tempMoves);

        bool checkMate = m_board.isKingInCheck();
        int num;
        if (tempMoves.size() == 0)
        {
            if (checkMate)
            {
                return 900 + level;
            }
            else
            {
                return 0;
            }
        }
        else
        {
            num = -search(-beta, -alpha, level - 1);
        }
        m_board.undo_move(move);

        if (num > best_val)
        {
            // Store the best value so far.
            best_val = num;
        }
    }

    return best_val;
} // end of int search

  /***************************************************************
  * find_best_move
  *
  * This is the main AI.
  * It returns what it considers to be the best legal move in the
  * current position.
  ***************************************************************/
CMove AI::find_best_move()
{
    // Make a list of all legal moves
    CMoveList moves;
    m_board.find_legal_moves(moves);


    std::cout << "info string " << moves.size() << " legal moves." << std::endl;

    CMoveList best_moves; // Array of the (one or more) best moves so far
    int best_val = -999;
    CMove best_move;
    CMove second_best = moves[0];
    // Search through all legal moves
    for (unsigned int i = 0; i<moves.size(); ++i)
    {
        CMove move = moves[i];

        // Get value of current move
        m_board.make_move(move);
        CMoveList tempMoves;
        m_board.find_legal_moves(tempMoves);
        bool checkMate = m_board.isKingInCheck();
        int val;
        if (tempMoves.size() == 0 && checkMate)
        {
            m_board.undo_move(move);
            return move;
        }
        else
        {
            val = -search(-999, 999, 4);
        }
        m_board.undo_move(move);

        std::cout << "info string " << val << " : " << move << std::endl;

        if (val > best_val)
        {
            second_best = best_moves[rand() % best_moves.size()];
            best_val = val;
            best_moves.clear();
            best_moves.push_back(move);
        }
        else if (val == best_val)
        {
            best_moves.push_back(move);
        }
    }

    if (best_moves.size() == 0)
    {
        std::cout << "BUG: No legal moves!" << std::endl;
        exit(1);
    }
    int size = best_moves.size();
    int index = rand() % size;
    best_move = best_moves[index];
    if (m_board.get_threefoldRepitationDraw() > 2)
    {
        if (size > 1)
        {
            if (index == 0)
            {
                index++;
            }
            else
            {
                index--;
            }
            best_move = best_moves[index];
        }
        else
        {
            best_move = second_best;
        }
    }
    return best_move;
} // end of find_best_move

Ошибка:

4 [main] open mchess 8784 cygwin_exception::open_stackdumpfile: Dumping stack trace to mchess.exe.stackdumpfile

Трассировка стека:

Frame        Function    Args
000FFFFBD60  0018005FAE9 (00000000000, 000FFFFCE00, 000FFFFBF68, 000FFFFDE50)
00000000002  0018006195A (00000000064, 00000000000, 00000000000, 00000000000)
000FFFFC040  00180125D3B (00000000000, 00000000000, 00000000000, 00000000000)
000FFFFC320  0018012231E (00000000080, 00000000000, 00000000000, 00000000000)
000FFFFC490  00180122814 (00000000000, 00000000000, 00000000000, 00000000006)
000FFFFC490  00180122A59 (7FFA8A4E5012, 00000004048, 0018022F508, 00180127E5C)
000FFFFC490  00180122D3F (0010040A180, 0010040A190, 000000003CD, 0018022F48F)
000FFFFC490  00180043395 (0000000003F, 0000000001E, 55854FFFC57, 00B00000009)
000FFFFFFFF  00100408683 (001FFFFFFF6, 00000000000, 00000000000, 00000000000)
000FFFFFFFF  0010040332D (00100406AD8, 001802441A0, FFFFFFFF00074940, 000FFFFC60B)
000FFFFCB40  001004034ED (00100000001, 000FFFFC6EB, 03600000000, 000FFFFC710)
000000003A9  00100406A2A (FFFFFFFFFFFFD680, 000FFFFC7CB, 00000000001, 000000003A6)
000FFFFFC56  00100406A63 (001800F64B0, 000FFFFC8AB, 02400000002, 000FFFFC8D0)
000000003A9  00100406A63 (00080210890, 00000000000, 00000000003, 00600095240)
000FFFFFC19  00100406F74 (00180198441, 00000000002, 0018014BC59, 003F8990F40)
003F89EC560  001004083C4 (00000000020, FF0700010302FF00, 00180049DAA, 00000000000)

Трассировка конца стека (может присутствовать больше фреймов стека)

Оригинальный код:

#include <stdlib.h> // exit()
#include "ai.h"
#include "CMoveList.h"

int AI::search(int alpha, int beta, int level)
{
    if (level == 0)
        return m_board.get_value(); 

    CMoveList moves;
    m_board.find_legal_moves(moves);
    int best_val = -999; 
    for (unsigned int i=0; i<moves.size(); ++i)
    {
        if (best_val >= beta)
        {
            break;
        }
        if (best_val > alpha)
        {
            alpha = best_val;
        }
        const CMove& move = moves[i];
        if (move.is_captured_piece_a_king())
        {
        return 900 + level;
        }
        m_board.make_move(move);
        int num = -search(-beta, -alpha, level-1);
        m_board.undo_move(move);

        if (num > best_val)
        {
            best_val = num;
        }
    }
    return best_val;
} 

CMove AI::find_best_move()
{
    CMoveList moves;
    m_board.find_legal_moves(moves);
    std::cout << "info string " << moves.size() << " legal moves." << std::endl;
    CMoveList best_moves; // Array of the (one or more) best moves so far
    int best_val = -999;
    for (unsigned int i=0; i<moves.size(); ++i)
    {
        CMove move = moves[i];
        m_board.make_move(move);
        int val = -search(-999, 999, 4);
        m_board.undo_move(move); 
        std::cout << "info string " << val << " : " << move << std::endl;
        if (val > best_val)
        {
            best_val = val;
            best_moves.clear();
            best_moves.push_back(move);
        }
        else if (val == best_val)
        {
            best_moves.push_back(move);
        }
    }
    if (best_moves.size() == 0)
    {
        std::cout << "BUG: No legal moves!" << std::endl;
        exit(1);
    }
    return best_moves[rand() % best_moves.size()];
} 

Буду признателен за любую помощь, поскольку не нашел полезной в Интернете.Спасибо

1 Ответ

0 голосов
/ 22 ноября 2018

Проблема заключалась в том, что список best_moves был пуст, поэтому его размер был равен нулю, и он пытался получить rand ()% ноль, поэтому произошло исключение

...