围绕 x 轴翻转一维阵列板表示
Flip one dimensional array board representation about the x axis
我正在编写国际象棋 AI 程序,在执行方块 table 时遇到了问题。因为我只想每边有一个正方形 table,所以我需要一个函数来翻转保存有关 x 轴的值的一维数组。例如,这个数组:
[ 2, 4, 5,
3, 5, 0,
1, 4, 2 ]
将翻转为:
[ 1, 4, 2,
3, 5, 0,
2, 4, 5 ]
我使用以下方法使用嵌套循环为 0x64 数组实现了这一点(注意:该示例仅为 3x3,但以下函数针对 8x8 进行了调整);但是,我想知道是否有更有效的方法,因为时间是个问题。
public int[] gridFromPerspective(int[] grid){
int[] flippedGrid = new int[64];
for(int i = 7; i < 32; i += 8){
for(int j = 0; j < 8; j++){
flippedGrid[i-j] = grid[63-(i-j)];
flippedGrid[63-(i-j)] = grid[i-j];
}
}
}
我知道您可以使用 sq' = sq ^ 56
轻松高效地翻转位板,但不确定如何在一维数组的情况下使用此技术。任何建议将不胜感激。
这里有一个稍微简单的版本,它没有对网格大小进行硬编码。
private static int[] flipVertically(int[] grid) {
final int width = (int)Math.sqrt(grid.length);
int[] flippedGrid = new int[grid.length];
for (int i = 0; i < grid.length; i += width)
System.arraycopy(grid, i, flippedGrid, grid.length - width - i, width);
return flippedGrid;
}
您使用的方法实际上并没有绕x轴翻转棋盘,而是整体旋转了棋盘。本质上,grid[0]
将始终与 flippedGrid[63]
具有相同的值。如果你想从其他玩家的角度来看棋盘,这实际上是正确的,但是你可以将你的循环减少到
for (int i = 0; i < 64; i++) {
flippedGrid[i] = grid[63-i];
}
这应该会带来(非常)小的性能提升。
如果您确实想绕 x 轴翻转棋盘,可以使用 System.arraycopy
来提高性能:
for (int i = 0; i < 8; i++) {
System.arraycopy(grid, 8*i, flippedGrid, 64 - 8*(i+1), 8);
}
这样,您可以让 JVM 一次复制长度为 8(一行)的块,而不是复制单个值。
不管该方法应该做什么,您可能还想考虑只保留网格的翻转副本并适当地镜像更改。这样,您就无需旋转电路板,但代价是内存使用量更高(并且更难编码 and/or 维护)。
我正在编写国际象棋 AI 程序,在执行方块 table 时遇到了问题。因为我只想每边有一个正方形 table,所以我需要一个函数来翻转保存有关 x 轴的值的一维数组。例如,这个数组:
[ 2, 4, 5,
3, 5, 0,
1, 4, 2 ]
将翻转为:
[ 1, 4, 2,
3, 5, 0,
2, 4, 5 ]
我使用以下方法使用嵌套循环为 0x64 数组实现了这一点(注意:该示例仅为 3x3,但以下函数针对 8x8 进行了调整);但是,我想知道是否有更有效的方法,因为时间是个问题。
public int[] gridFromPerspective(int[] grid){
int[] flippedGrid = new int[64];
for(int i = 7; i < 32; i += 8){
for(int j = 0; j < 8; j++){
flippedGrid[i-j] = grid[63-(i-j)];
flippedGrid[63-(i-j)] = grid[i-j];
}
}
}
我知道您可以使用 sq' = sq ^ 56
轻松高效地翻转位板,但不确定如何在一维数组的情况下使用此技术。任何建议将不胜感激。
这里有一个稍微简单的版本,它没有对网格大小进行硬编码。
private static int[] flipVertically(int[] grid) {
final int width = (int)Math.sqrt(grid.length);
int[] flippedGrid = new int[grid.length];
for (int i = 0; i < grid.length; i += width)
System.arraycopy(grid, i, flippedGrid, grid.length - width - i, width);
return flippedGrid;
}
您使用的方法实际上并没有绕x轴翻转棋盘,而是整体旋转了棋盘。本质上,grid[0]
将始终与 flippedGrid[63]
具有相同的值。如果你想从其他玩家的角度来看棋盘,这实际上是正确的,但是你可以将你的循环减少到
for (int i = 0; i < 64; i++) {
flippedGrid[i] = grid[63-i];
}
这应该会带来(非常)小的性能提升。
如果您确实想绕 x 轴翻转棋盘,可以使用 System.arraycopy
来提高性能:
for (int i = 0; i < 8; i++) {
System.arraycopy(grid, 8*i, flippedGrid, 64 - 8*(i+1), 8);
}
这样,您可以让 JVM 一次复制长度为 8(一行)的块,而不是复制单个值。
不管该方法应该做什么,您可能还想考虑只保留网格的翻转副本并适当地镜像更改。这样,您就无需旋转电路板,但代价是内存使用量更高(并且更难编码 and/or 维护)。