自动矢量边界检查而不会破坏我的程序

Automatic vector boundary checking without crashing my program

本文关键字:我的 程序 边界 检查      更新时间:2023-10-16

我正在创建一个工作的国际象棋游戏

我的国际象棋引擎有一块棋盘。该板是一块2D板[Y][X],其中的是Pieces。碎片是枚举,它表示黑色碎片、白色碎片和NONE。

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

我的问题是验证一个正方形是否在我的板内。请允许我详细说明。例如,当查看A2典当的可能移动时,典当可以向上移动12,或者捕获左-右,或者通过左-右:

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

然而,正如你所知,X-1会导致棋子出界。

是的,我可以实现一个简单的boolisSquareValid()函数。但这意味着,当我试图访问或设置board[][]时,我需要调用这个函数。

有没有一种方法可以实现Board[][],这样当我试图访问越界索引时,它会抛出错误消息或其他什么,而不会破坏我的程序?

感谢

您混淆了两个不同的问题。

第一个问题是如何确保游戏防止一个棋子出现在棋盘之外。这不是错误处理;你必须确保作品一开始就不会出现在那里。换句话说,在向用户(或AI组件)提供选择之前,您必须将程序逻辑限制为有效的移动。如果你想捕捉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

相关文章: