我长期以来一直是stackoverflow的潜伏者,并且通常总能找到一个现有的线程来回答我的任何问题,但是现在我必须自己提出一个问题,因为我还没有找到答案。< / p>
我负责用Java制作的Checkers游戏的AI用于学校作业。我设计了它,以便当AI检测到它可以进行的跳跃时,它将检查是否有任何跳跃导致双跳,如果是,则选择移动而不是随机单跳。
以下是如何做到的:
1)将电路板存放在&#34;备份&#34;变量(8x8 2d阵列的&#39;对象)并检查是否有任何跳跃
2)如果是这样,请调用方法&#34; doubleJumps&#34;经历了每次可能的跳跃
3)对于每一步,另一种方法&#34;推测跳跃&#34;被调用,它返回由给定跳转
产生的新8x8板阵列4)然后,doubleJumps接受这个新的棋盘并通过它搜索更多的跳跃,换句话说是双跳。
但是我在备份数组中得到了一个nullpointer异常......而且我已经将它追溯到这段代码(删除了不相关的部分):
private static int[][] doubleJumps() {
final Piece[][] backup = BoardLayout.getLayout(); //fetches the board from the game
for(int i=0; i<8; i++) {//iterate through board; all rows
for (int j=0; j<8; j++) {//iterate through all columns
if(backup[i][j] != null){
if (backup[i][j].getCol()==colAI && PieceLogic.mustJump(i, j, false)) {//if the current piece is CPU and can jump
if (PieceLogic.canJump(i, j, i-2, j-2)){//if the jump is up left
final Piece[][] newBoard = speculateJump(i, j, i-2, j-2);//speculate the jump
此时备份[i] [j]突然变为空。我无法理解为什么要这样做,因为speculateJumps方法对数组&#39; backup&#39;没有任何引用。只有在我调用speculateJumps时才会发生这种情况,否则备份数组将保持不变。以下是speculateJumps的代码:
private static Piece[][] speculateJump(int x1, int y1, int x2, int y2) {//this function returns a hypothetical 2d board array that results from a given jump
Piece[][] board = BoardLayout.getLayout();
int removeX = (x1+x2)/2;
int removeY = (y1+y2)/2;
board[x2][y2] = board[x1][y1];
board[x1][y1] = null;
board[removeX][removeY]= null;
if (x2==0) {
board[x2][y2].promote();
}
return board;
}
因为你可以看到它完全独立于备份阵列。需要注意的一点是,speculateJumps与doubleJumps在同一个类中。我完全被这个难过了。很感谢任何形式的帮助。提前谢谢
答案 0 :(得分:0)
您正在操纵board
内的speculateJump
数组,这是BoardLayout.getLayout()
返回的数组。在doubleJumps
内,您还backup
保持(上一个)返回值getLayout()
。
我的猜测是getLayout()
(你没有显示代码)不创建新数组,但每次返回相同的数组。这意味着board
实际上指向相同数组而backup
和speculateJump
修改实际主板而不是工作副本。
我认为你误解了final
的含义。 final
变量是一个只能分配一次的变量。虽然backup
和board
本身永远不会指向不同的数组,但数组本身仍然可以通过这些变量进行修改:
int[] a = new int[] { 1, 2, 3 };
final int[] b = a;
b[1] = 4;
System.out.println(a[1]); // -> 4
如果您想确保speculateJump
不修改原始主板(getLayout()
返回的数组),您需要“克隆”返回的数组,以确保您正在处理数据的副本。这样,您可以修改副本而不会影响原始数组。在你的情况下,它甚至更棘手,因为你有一个二维数组(一个数组的数组),所以你需要做一个“深度克隆”。