[英]Search function crash in 2D Arrays (Java)
我正在为CS简介课制作一个黑白棋游戏。
我在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
,这将导致在您在isOpposite
或isSame
调用.equals
时引发NullPointerException
。
尝试在其上调用.equals
之前,应检查getColor的结果。 然后,您应该弄清楚为什么getBackground
返回null
或引发ArrayIndexOutOfBoundsException
。
因为@ goto10已经给出了您需要查看的方向,所以这里有一些其他注意事项:
您需要学习更好的关注点分离。 具体来说,您正在将显示代码与游戏规则代码混合在一起。 通过适当的设计,几乎所有程序都应该可以从命令行运行-GUI 仅用于帮助最终用户。
当您有两个(或多个)相关参数时,实际上只有一个-包含它们的复合类。 例如,用于搜索数组的x
和y
参数实际上表示一个CoordinatePair
, Location
或Point
实例。 尽管这里的可能性很小,但是这将有助于避免将来出现问题-例如,如果有人不小心交换了searchN()
的y
和increment
参数会发生什么? 编写一个不变的Point
类并使用它-它将彻底消除该问题:
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
),但不是该方法的“一部分”。 副作用使得很难对物体的状态进行“推理”(弄清楚正在发生的事情),并且很难很好地测试实际的噩梦 。 编写完全取决于传入的对象(希望不可改变)状态的方法,和“主机”的不可改变状态( this
)对象可能会稍微有些难度,但更容易推论; 几乎所有(或可能完全)不可变的系统更容易考虑,并且您可以免费获得线程安全/并行执行。
您的方法.isSame()
和.isOpposite()
有点.isOpposite()
在一起,因为已播放/未播放方块之间的唯一区别是颜色。 相关的规则端代码应该不知道显示端代码-根本没有绿色的东西(技术上也不是白色或黑色的东西-玩家1有一块,而玩家1有一块玩家2。即使在现实世界中,这也是一种显示效果,规则“白人获得4.5分”确实意味着“第二名玩家获得4.5分”。 另外,这两个方法不会为未播放的正方形返回反结果( .isSame()
返回false),这是不合逻辑的。
每当您有一长串相似元素( leadX
和playableX
变量集)时,请尝试将其重新格式化为实际列表。 如果您想制作3D版本,这也将大有帮助。此外,还有一种方法可以使用所谓的“ 策略模式” (以及哈希图或数组列表)来简化在不同方向上的移动/搜索。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.