我正在创造一个有效的国际象棋游戏
我的国际象棋引擎有一块板。该板是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 [] [],这样当我尝试访问超出范围的索引时,它会抛出错误信息或什么东西而不会崩溃我的程序?
由于
答案 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
。