首页 > 解决方案 > 如何在不实际增加数组大小的情况下在数学上具有数组边框?

问题描述

所以我有一个由 64 个方格的一维数组表示的游戏板,我想知道一个棋子何时试图逃离边界。

例如:假设国际象棋游戏中的国王在 X 上:

0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 X 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

用方向向量很容易计算出被攻击的方块:

-9, -8, -7,
-1,      1,
 7,  8,  9

0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 1 1 1 0 0
0 0 0 1 X 1 0 0
0 0 0 1 1 1 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

如果他在棋盘的上边缘或下边缘:我只需添加一个 if 来检查 square + directionvector[i] > 63 还是 square + directionvector[i] < 0

所以:

0 0 0 1 X 1 0 0
0 0 0 1 1 1 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

当它位于侧边缘时,问题就来了:

0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1
1 0 0 0 0 0 1 X
1 0 0 0 0 0 1 1
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

正如您在上面看到的,这就是它将“跳”到错误的地方。

你知道有什么方法可以检查吗?谢谢

标签: arraysvectorchess

解决方案


在您的程序开始时,您可以预先计算每个棋子和每个方格的合法移动并将它们存储在某个地方。

假设您的方格编号从 0 到 63,那么KING_MOVES[i]将存储方格上国王的合法移动ii范围从 0 到 63)。例如,KING_MOVES[0] = { 1, 8, 9 }KING_MOVES[31] = { 22, 23, 30, 38, 39 }。同样,对于角落里的骑士,KNIGHT_MOVES[0] = { 10, 17 }.

  0  1  2  3  4  5  6  7
  8  9 10 11 12 13 14 15
 16 17 18 19 20 21 22 23
 24 25 26 27 28 29 30 31
 32 33 34 35 36 37 38 39
 40 41 42 43 44 45 46 47
 48 49 50 51 52 53 54 55
 56 57 58 59 60 61 62 63

每个方格的合法步数是不同的(国王在中央有 8 步,而在角落只有 3 步)。您可以单独存储合法移动的数量(例如NUM_KING_MOVES[31] = 5),也可以使用 -1 或 64 等特殊值终止每个列表。

要预先计算这些列表,您可以将每个一维数字转换为一对(行、列)坐标并天真地生成移动,并进行边界检查。对于 31 格上的国王,您将 31 转换为(第 3 行,第 7 列)。当向右移动时,你最终在(第 3 行,第 8 列),这是非法的,所以你放弃了这一步。当移动到左上角时,您最终会到达(第 2 行,第 6 列),这是合法的,因此您将其转换回一维表示:2 * 8 + 6 = 22。将此移动附加到KING_MOVES[31]和等等。

这为您提供了两全其美的优势:更快、更短的移动生成代码,不会因填充而在每个板上浪费内存。缺点是几千字节的额外内存。

如果您走这条路,您还可以查看位以更快地生成移动。


推荐阅读