2D数组(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((中显示的JButtons的2D阵列中。

我看到了NullPointerException发生的两种方式:

您在getColor中得到一个ArrayIndexOutOfBoundsException。在这种情况下,您将捕获异常并返回null

CCD_ 5正在返回CCD_。

在任何一种情况下,getColor都将返回null,这将导致在isOppositeisSame中调用.equals时抛出NullPointerException

在尝试对getColor调用.equals之前,您应该检查它的结果。然后您应该弄清楚getBackground返回null或抛出ArrayIndexOutOfBoundsException的原因。

因为@goto10已经给出了你需要寻找的方向,这里还有一些其他注意事项:

  • 你需要学会更好地分离关注点。特别是,您将显示代码与游戏规则代码混合在一起。有了正确的设计,几乎所有的程序都应该可以从命令行运行——GUI只是来帮助最终用户。

  • 当您有两个(或多个(相关参数时,实际上只有一个参数——一个包含它们的复合类。例如,用于搜索数组的xy参数实际上代表一个CoordinatePairLocationPoint实例。尽管这种可能性很小,但这将有助于避免未来出现问题——例如,如果有人意外地交换了searchN()中的yincrement参数,会发生什么?编写一个不可变的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()有点乱,因为播放/未播放的正方形之间的唯一区别是它的颜色。相关的规则端代码应该不知道显示端代码——没有绿色边的棋子(从技术上讲,也没有白色或黑色棋子(——有一个棋子是给玩家1的,还有一个棋子给玩家2的。即使在现实世界中,这也是一种仅显示的效果,而写着"白人获得4.5分"的规则实际上意味着"第二名的玩家获得4.5分的额外分数"(。此外,这两种方法不会为未播放的正方形返回相反的结果(.isSame()返回false(,这是不合乎逻辑的。

  • 每当您有一个类似元素的长列表(leadXplayableX变量集(时,请尝试将它们重新格式化为实际列表。如果你想制作一个3D版本,这也会有很大帮助。。。此外,还有一种方法可以使用所谓的策略模式(以及哈希图或数组列表(,使在不同方向上移动/搜索更加容易。

相关内容

  • 没有找到相关文章

最新更新