自动矢量边界检查而不会崩溃我的程序

时间:2017-01-15 04:53:59

标签: c++ vector chess

我正在创造一个有效的国际象棋游戏

我的国际象棋引擎有一块板。该板是2D板[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..}
}

我的问题是验证广场是否在我的董事会内。请让我详细说明。例如,当查看A2 pawn的可能移动时,pawn可以向上移动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 [] [],这样当我尝试访问超出范围的索引时,它会抛出错误信息或什么东西而不会崩溃我的程序?

由于

1 个答案:

答案 0 :(得分:1)

你正在混淆两个不同的问题。

首先是如何确保游戏防止棋子在棋盘外结束。这是 not 错误处理;你必须确保这件作品永远不会在那里结束。换句话说,您必须将程序逻辑限制为有效的移动,然后才能将选项呈现给用户(或者AI组件,就此而言)。如果您想要捕获从at抛出的异常,然后将电路板恢复到有效状态,请停在那里并且不要那样做。这是最好的例外滥用。

第二个是如何处理代码中的错误导致的错误。你可能已经编写了代码来阻止游戏将棋子放在棋盘外,但你可能犯了一个错误,因为我们都这样做了,所以你最终会得到非法的矢量索引。在这种情况下,由operator[]引起的崩溃实际上是一件好事,因为立即终止有缺陷的程序通常是最好的事情。替代方案是以某种方式继续&#34;并继续使用损坏的数据和破坏的游戏规则,甚至可能没有足够快地注意到错误。

因为不能保证错误的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