2017-01-15 12 views
1

Я создаю рабочую шахматную игруАвтоматическая проверка границ вектора без сбоев моей программы

Мой шахматный движок имеет доску. Плата представляет собой двумерную панель [Y] [X], а внутри нее Pieces. Пьесы - это перечисления, и он представляет черные части, белые части и НЕТ.

class ChessBoard 
{ 
    vector<vector<Piece>> board(); //I made it 8*8 in the constructor 
    enum Piece{NONE, white pieces, black pieces etc..} 
} 

Проблема заключается в том, что квадрат находится внутри моей доски. Пожалуйста, позвольте мне уточнить. Например, при взгляде на возможные ходы для А2 пешки, пешка может либо двигаться вверх 1 2 или захвата влево, вправо или Мимоходом налево направо:

(X,Y+1), (X,Y+2), (X+1,Y+1), (X-1,Y+1), (X+1,Y+2), (X-1,Y-2) 

Однако, как вы знаете, X-1 будет вызывать кусок, чтобы выйти за пределы.

Да, я мог бы реализовать простую функцию bool isSquareValid(). Но это означает, что когда я пытаюсь получить доступ или установить board[][], мне нужно вызвать эту функцию.

Есть ли способ реализовать Board [] [], так что, когда я пытаюсь получить доступ к связанным индексам, он выдает сообщение об ошибке или что-то, не сбивая мою программу?

Thanks

+0

Невозможно реализовать 'operator [] []', за исключением использования двух 'operator []' в тандеме. 'std :: vector' предоставляет функцию' at() 'member, которая проверяет допустимые индексы, но необходимо исключить исключения для предотвращения завершения программы. Обратите внимание, что 'vector > board (8 * 8)' задает вектор, содержащий 64 'vector ', каждый из которых не имеет элементов. Он не создает массив 8x8 в любой форме. – Peter

+0

Конечно, в шахматах пешка не может двигаться через другие части, даже если квадрат назначения находится на доске. – Peter

+0

Да, я знаю, я написал код psuedo, чтобы показать, что плата была 8 * 8 ... В любом случае, я действительно не хочу делать, если (isValidSquare (x, y)) EVERYTIME Я пытаюсь посмотреть или получить доступ к доске. ... Есть ли разумный способ сделать это? Я подумал, что, возможно, это плата размером 10 * 10 с внешним слоем, поскольку ERROR может помочь. – Telenoobies

ответ

1

Вы смешиваете две разные проблемы.

Во-первых, как убедиться, что игра предотвращает попадание части за пределы доски. Это не обработка ошибок; вы должны убедиться, что кусок никогда не заканчивается там в первую очередь. Другими словами, вы должны ограничить логику программы действительными ходами до того, как выбор даже будет представлен пользователю (или к компоненту ИИ, если на то пошло). Если вам пришла в голову идея поймать исключение, сброшенное с at, а затем вернув плату в правильное состояние, остановитесь прямо там и не делайте этого. Это будет исключение злоупотребления в его самом лучшем виде.

Во-вторых, как обращаться с ошибкой в ​​результате ошибки в коде. Возможно, вы написали код, чтобы не допустить, чтобы игра помещала фигуры за пределы доски, но вы, возможно, допустили ошибку, потому что все мы это делаем, поэтому вы все-таки закончите с незаконными векторными индексами. В этом случае авария, вызванная operator[], на самом деле хорошая вещь, потому что немедленное прекращение багги-программы, как правило, лучшее, что может случиться с вами. Альтернативой является «как-то продолжить» и продолжать испорченные данные и нарушать правила игры, возможно, даже не замечая ошибку достаточно быстро.

Потому что это не гарантирует, что неправильно operator[] вызов приводит к сбою, и заставляет библиотеку времени выполнения для выполнения проверки может быть немного громоздким (неправильный operator[] индекс формально неопределенное поведение, конечно), вы можете добавить некоторые assert ваших собственных утверждений и убедитесь, что NDEBUG не мешает им выполнять свою работу.

Это становится значительно проще, если вы оберните std::vector в своем собственном классе. Пока вы на него, вы можете упростить доступ элемент с operator():

class Board 
{ 
public: 
    Piece& operator()(int x, int y) 
    { 
     assert(x >= 0); 
     assert(x < 16); 
     assert(y >= 0); 
     assert(y < 16); 
     return data[y][x]; 
    } 

    Piece operator()(int x, int y) const 
    { 
     assert(x >= 0); 
     assert(x < 16); 
     assert(y >= 0); 
     assert(y < 16); 
     return data[y][x]; 
    } 

    Board() 
    { 
     for (int row_index = 0; row_index < 16; ++row_index) 
     { 
      data.emplace_back(16, Piece::None); 
     } 
    } 

private: 
    std::vector<std::vector<Piece>> data; 
}; 

отметить также, что std::vector является плохим выбором для шахматной доски, потому что шахматные доски не дают усадки или расти. Вместо этого используйте вместо этого std::array.

+0

Итак, когда я пытаюсь получить доступ к положению на доске, я просто делаю, если (доска (x, y)) .. Мне очень нравится это решение ... – Telenoobies