二维数组中的搜索函数崩溃(Java)
我正在为我的入门CS课程制作一个reversi游戏 我在SearchN()中发现了一个错误,该错误会导致它给出错误的playableN标志,并创建了isSame()作为解决方法 现在,当我尝试移动时,游戏正在崩溃 我已将错误隔离到isPlayable(),这会导致程序停止运行,而不会显示错误消息 我认为这是因为程序在搜索范围之外;但是,当我运行.isPlayable(0,0)时,它会返回一个NullPointerException(我也不太知道如何摆脱它) 因此,在处理未播放的空间时一定会出现一些错误 有人有什么想法吗二维数组中的搜索函数崩溃(Java),java,arrays,multidimensional-array,jbutton,Java,Arrays,Multidimensional Array,Jbutton,我正在为我的入门CS课程制作一个reversi游戏 我在SearchN()中发现了一个错误,该错误会导致它给出错误的playableN标志,并创建了isSame()作为解决方法 现在,当我尝试移动时,游戏正在崩溃 我已将错误隔离到isPlayable(),这会导致程序停止运行,而不会显示错误消息 我认为这是因为程序在搜索范围之外;但是,当我运行.isPlayable(0,0)时,它会返回一个NullPointerException(我也不太知道如何摆脱它) 因此,在处理未播放的空间时一定会出现一
/**
* a method to return the color of a tile
*@params x y tile coordinates
*/
public Color getColor(int x, int y){
try{
return buttons[x][y].getBackground();
}
catch(ArrayIndexOutOfBoundsException e){
return null;
}
}
/**
* a method to determine whether a tile has been played
*@params x y tile coordinates
*/
public boolean isPlayed(int x, int y){
if(this.isBlack(x,y) || this.isWhite(x,y)){
return true;
}else{
return false;
}
}
/**
* a method to determine whether a tile has a color opposite to a given color
*@params x y c tile coordinates and color to compare
*/
public boolean isOpposite(int x, int y, Color c){
if(this.isPlayed(x,y)){
return(!(this.getColor(x,y).equals(c)));
} else
return false; // this was giving the false playableN flag
}
/**
* a method to determine weather a tile has the same color as the one given
*@params x y c tile coordinates and color to compare
*/
public boolean isSame(int x, int y, Color c){
if(this.isPlayed(x,y)){
return(this.getColor(x,y).equals(c));
}else{
return false;
}
}
/**
* a method used to check tiles north of an attempted play to verify legal moves
*@params x y c tile coordinates and comparing color
*/
public void searchN(int x, int y, int increment, Color c){
if(increment>1 && (this.isSame(x-increment,y, c))){
playableN = true;
leadN = false;
} else {
if(this.isOpposite(x-increment,y,c)){
leadN=true;
}
}
}
/**
* a method used to determine if a tile is playable
*@params x y tile coordinates
*/
public boolean isPlayable(int x, int y){
this.searchN(x,y,1,turnColor);
// search 7 other directions
while(leadN||leadNE||leadE||leadSE||leadS||leadSW||leadW||leadNW){
int i = 2;
if(leadN)
this.searchN(x,y,i,turnColor);
// search 7 other directions
i++;
}
if(playableN||playableNE||playableE||playableSE||playableS||playableSW||playableW||playableNW)
return true;
else
return false;
}
**所有磁贴都是黑色、白色或默认的磁贴颜色(绿色),并且在gridLayout()中显示的JButton的2D数组中。我发现有两种方式会发生
NullPointerException
:
您在getColor
中获得了一个ArrayIndexOutOfBoundsException
。在这种情况下,您将捕获异常并返回null
或
getBackground
正在返回null
在这两种情况下,getColor
都将返回null
,这将导致在调用时抛出null点异常
在尝试调用getColor上的.equals
之前,应该检查getColor的结果。然后你应该弄清楚为什么getBackground
返回null
或者ArrayIndexOutOfBoundsException
被抛出。我发现有两种方式可以发生NullPointerException
:
您在getColor
中获得了一个ArrayIndexOutOfBoundsException
。在这种情况下,您将捕获异常并返回null
或
getBackground
正在返回null
在这两种情况下,getColor
都将返回null
,这将导致在调用时抛出null点异常
在尝试调用getColor上的.equals
之前,应该检查getColor的结果。然后你应该弄清楚为什么getBackground
返回null
或者ArrayIndexOutOfBoundsException
被抛出。因为@goto10已经给出了你需要查看的方向,下面是一些其他注意事项:
- 您需要更好地分离关注点。具体来说,您将显示代码与游戏规则代码混合在一起。如果设计得当,几乎所有的程序都应该可以从命令行运行——GUI只是用来帮助最终用户的
- 当您有两个(或更多)相关参数时,实际上只有一个参数—一个包含它们的复合类。例如,用于搜索数组的
x
和y
参数实际上表示一个坐标点
、位置
或点
实例。尽管这种可能性很小,但这将有助于避免将来出现问题——例如,如果有人意外地交换了searchN()
中的y
和increment
参数,会发生什么情况?编写一个不可变的点
类并使用它-它将完全消除该问题:
public final class Point {
// Yes, public variables are almost universally frowned upon, with good reason.
// Here, though, it's kind of the 'point'
public final int x;
public final int y;
// Note: private constructor - can't call this from outside.
private Point(final int x, final int y) {
this.x = x;
this.y = y;
}
// Static factory method for construction instead.
// It is left as an exercise for the reader to implement caching.
public static Point fromCoordinates(final int x, final int y) {
return new Point(x, y);
}
}
您需要实现一个好的.hashCode()
和.equals()
方法来实现这一点,但是Eclipse(或任何其他好工具)给出的应该是好的。使用不可变对象有一些性能方面的考虑,但对于您的需要,这不是问题
- 努力使方法产生尽可能少的副作用;也就是说,尽量使它们修改尽可能少的外部状态(最好是NO)。这包括作为对象一部分的状态(例如
leadN
),但不是方法的“一部分”。副作用使我们很难对一个对象的状态进行“推理”(弄清楚发生了什么),并使测试成为一场真正的噩梦。编写完全依赖于传入对象的(希望是不可变的)状态以及“主机”(此
)对象的不可变状态的方法可能有点困难,但更容易推理;几乎所有(或者可能完全)不可变的系统更容易思考,并且您可以免费获得线程安全/并行执行
- 您的方法
.isSame()
和.isoposite()
有点混乱,因为播放/未播放的方块之间的唯一区别是颜色。相关的规则端代码应该不知道显示端代码-没有绿色边的代码(从技术上讲,也没有白色或黑色的棋子——有一个棋子是给玩家1的,一个棋子是给玩家2的。即使在现实世界中,这也是一种只显示的效果,而“白色获得4.5额外分数”的规则实际上意味着“第二名的玩家获得4.5额外分数”)。此外,这两种方法不会为未播放的方块返回相反的结果(.isSame()
返回false),这是不符合逻辑的
- 每当你有一个类似元素的长列表(leadX
和playableX
变量集)时,尝试将它们重新格式化为一个实际的列表。如果你想制作一个3D版本,这也会非常有帮助……此外,还有一种方法可以使用已知的(以及哈希映射或数组列表)使在不同方向移动/搜索更加容易
因为@goto10已经给出了您需要查看的方向,下面是一些其他注意事项:
- 你需要学习如何更好地分离关注点。特别是,你将显示代码与游戏规则代码混合在一起。通过正确的设计,几乎所有的程序