开发国际象棋程序时初始化方向数组的意义是什么?
我对竞争性编程是新的,我经常注意到,许多伟大的编程人员在他们的代码中都有这四行(特别是涉及到数组):
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
就会朝相反的方向行进。)
现在你可以通过遍历你的di
和dj
数组testing所有的方向,而不需要自己写出每个方向(总共八个)(不要忘记做边界检查:) )
diK
和djK
形成所有骑士的方向,而不是所有相邻的方向。 在这里, ^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; }