开发国际象棋程序时,用给定值初始化下面的方向数组有什么意义?

问题描述 投票:0回答:3

我是竞争性编程的新手,我经常注意到,许多 C/C++ 程序员的代码中都有这四行(特别是涉及数组的代码):

int di[] = { 1, -1, 0, 0, 1, -1, 1, -1 };
int dj[] = { 0, 0, 1, -1, 1, -1, -1, 1 };
int diK[] = { -2, -2, -1, 1, 2, 2, 1, -1 };
int djK[] = { -1, 1, 2, 2, 1, -1, -2, -2 };

这到底意味着什么以及技术的用途是什么?

chess
3个回答
85
投票

这是一种将所有方向编码为数组的技术 - 每对

di[i],dj[i]
都是不同的方向。

如果我们想象在位置 x,y 有一个棋子,并且我们想要添加它的 x 和 y 值以将其移动到附近的位置,1,0 是东,-1,0 是西,0, 1 为南,0,-1 为北,依此类推。

(这里我说过左上角是 0,0,右下角是 4,4,并显示了数组的每个索引从中心点 X 到 2,2 处的移动量。)

.....
.536.
.1X0.
.724.
.....

它的设置方式,如果你对索引执行

^1
^
是按位异或),你会得到相反的方向 - 0 和 1 是相反的,2 和 3 是相反的,依此类推。 (另一种设置方法是从北开始顺时针旋转 - 然后
^4
即可到达相反的方向。)

现在,您可以通过循环

di
dj
数组来测试从给定点开始的所有方向,而不需要在自己的行上写出每个方向(总共八个!)(只是不要忘记进行边界检查:) )

diK
djK
形成所有骑士方向,而不是所有相邻方向。在这里,
^1
将沿一个轴翻转,
^4
将使对面的骑士跳跃。

.7.6.
0...5
..K..
1...4
.2.3.

65
投票

对于那些觉得 Patashu 的解释难以理解的人,我会尝试澄清。

想象一下,您正在尝试考虑从棋盘上的给定点出发的所有可能的行动。

如果循环 di 和 dj 数组,将 di 值解释为 x 偏移量,将 dj 值解释为 y 偏移量,则可以覆盖可能的 8 个方向中的每一个。

假设正 x 是东,正 y 是南(如 Patashu 的答案),你会得到以下结果;

 |迪/x | DJ/Y |方向
--+------+------+------------
0 | 1 | 0 |东方
1 | -1 | 0 |西方
2 | 0 | 1 |南
3 | 0 | -1 |北
4 | 1 | 1 |东南
5 | -1 | -1 |西北
6 | 1 | -1 |东北
7 | -1 | 1 |西南

diK 和 djK 数组可以用相同的方式解释,以确定骑士棋子的可能移动。如果您不熟悉国际象棋,骑士会按 L 型移动 - 两个方格朝一个方向移动,然后一个方格与该方向成直角(反之亦然)。

 |迪克/x | djK/y |方向
--+--------+--------------------+----------------
0 | -2 | -1 |西2个,北1个
1 | -2 | 1 |西2个,南1个
2 | -1 | 2 | 1 西,2 南
3 | 1 | 2 | 1 东,2 南
4 | 2 | 1 | 2 东,1 南
5 | 2 | -1 | 2 东,1 北
6 | 1 | -2 | 1 东,2 北
7 | -1 | -2 | 1 西,2 北

1
投票

一小段代码,用于检查所有方向上可能的移动量,它使用定义的数组。

int di[] = { 1, -1, 0, 0, 1, -1, 1, -1 };
int dj[] = { 0, 0, 1, -1, 1, -1, -1, 1 };
int movesPossible[8];
int move = 0;
int posx, posy; // position of the figure we are checking

for (int d=0; d<8; d++) {
  for (move = 1; board.getElt(posx+di[d]*move, posy+dj[d]*move)==EMPTY; move++) ;
  movesPossible[d] = move-1;
}
© www.soinside.com 2019 - 2024. All rights reserved.