繁体   English   中英

2D数组中的搜索功能崩溃(Java)

[英]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 ,这将导致在您在isOppositeisSame调用.equals时引发NullPointerException

尝试在其上调用.equals之前,应检查getColor的结果。 然后,您应该弄清楚为什么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()有点.isOpposite()在一起,因为已播放/未播放方块之间的唯一区别是颜色。 相关的规则端代码应该不知道显示端代码-根本没有绿色的东西(技术上也不是白色或黑色的东西-玩家1有一块,而玩家1有一块玩家2。即使在现实世界中,这也是一种显示效果,规则“白人获得4.5分”确实意味着“第二名玩家获得4.5分”。 另外,这两个方法不会为未播放的正方形返回反结果( .isSame()返回false),这是不合逻辑的。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM