开发国际象棋程序时初始化方向数组的意义是什么?

我对竞争性编程是新的,我经常注意到,许多伟大的编程人员在他们的代码中都有这四行(特别是涉及到数组):

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 }; 

这是什么意思?用什么技术?

这是一种将所有方向编码为数组的技巧 – 每一对di[i],dj[i]都是不同的方向。

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

(这里我已经说过左上angular是0,0,右下angular是4,4,并且显示了arrays的每个索引将从中心点X处移动到2,2。)

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

它的设置方式是,如果你在索引上做^1^是按位XOR),你会得到相反的方向 – 0和1是相反的,2和3是相反的,依此类推。 (另一种方法是从北方顺时针方向开始,然后^4就会朝相反的方向行进。)

现在你可以通过遍历你的didj数组testing所有的方向,而不需要自己写出每个方向(总共八个)(不要忘记做边界检查:) )

diKdjK形成所有骑士的方向,而不是所有相邻的方向。 在这里, ^1将沿着一个轴翻转, ^4将使相反的骑士飞跃。

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

对于那些觉得Patashu的解释难以遵循的人,我会试着澄清一下。

想象一下,你正在试图从一个棋盘上的某个点上考虑每一个可能的举动。

如果循环使用di和dj数组,则将di值解释为x偏移量,将dj值解释为y偏移量,即可涵盖每个可能的8个方向。

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

   |  di / 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数组可以用相同的方式来解释,以确定Knight棋子的可能棋步。 如果您不熟悉国际象棋,骑士将以L模式移动 – 一个方向的两个方格,然后一个方格的方格(或反之亦然)。

   |  diK / 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北

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

 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; }