java - IF 语句检查(无法正常工作)

标签 java arrays loops if-statement boolean

randomEmpty() 返回 n x n 空网格上的随机坐标(方法有效)。 randomAdjacent() 使用 randomEmpty() 在 map 上选择一个 EMPTY 坐标。然后进行比较以查看该坐标是否具有非空的有效相邻坐标。问题是 randomAdjacent 并不总是返回具有相邻非空空间的空间坐标。它将始终返回有效坐标,但不会返回后者。我看不出问题所在。有人可以帮我找出问题所在吗?

public int[] randomEmpty()
{
    Random r = new Random();
    int[] random = new int[2];
    int row = r.nextInt(array.length);
    int column = r.nextInt(array.length);
    while(!(isEmpty(row,column)))
    {
        row = r.nextInt(array.length);
        column = r.nextInt(array.length);
    }
    random[0] = row+1;
    random[1] = column+1;
    return random;        
}

public int[] randomAdjacent()
{
    int[] adjacentToX = new int[8];
    int[] adjacentToY = new int[8];
    int[] adjacentFrom = randomEmpty();
    int count;
    boolean isTrue = false;
    boolean oneAdjacentNotEmpty = false;

    while(!(oneAdjacentNotEmpty))
    {
        count = 0;

        if(validIndex(adjacentFrom,1,-1))
        {
            adjacentToX[count] = adjacentFrom[0]+1;
            adjacentToY[count] = adjacentFrom[1]-1;
            count++;
        }
        if(validIndex(adjacentFrom,0,-1))
        {               
            adjacentToX[count] = adjacentFrom[0];
            adjacentToY[count] = adjacentFrom[1]-1;
            count++;
        }
        if(validIndex(adjacentFrom,-1,-1))
        {          
            adjacentToX[count] = adjacentFrom[0]-1;
            adjacentToY[count] = adjacentFrom[1]-1;
            count++;
        }
        if(validIndex(adjacentFrom,-1,0))
        {        
            adjacentToX[count] = adjacentFrom[0]-1;
            adjacentToY[count] = adjacentFrom[1];
            count++;
        }
        if(validIndex(adjacentFrom,-1,1))
        {       
            adjacentToX[count] = adjacentFrom[0]-1;
            adjacentToY[count] = adjacentFrom[1]+1;
            count++;
        }
        if(validIndex(adjacentFrom,0,1))
        {         
            adjacentToX[count] = adjacentFrom[0];
            adjacentToY[count] = adjacentFrom[1]+1;
            count++;
        }
        if(validIndex(adjacentFrom,1,1))
        {         
            adjacentToX[count] = adjacentFrom[0]+1;
            adjacentToY[count] = adjacentFrom[1]+1;
            count++;
        }
        if(validIndex(adjacentFrom,1,0))
        {        
            adjacentToX[count] = adjacentFrom[0]+1;
            adjacentToY[count] = adjacentFrom[1];
            count++;
        }
        for(int i = 0; i < count; i++)
        {
            if(!(isEmpty(adjacentToX[i],adjacentToY[i])))  
            {
                oneAdjacentNotEmpty = true;
                isTrue = true;
            }
        }
        if(isTrue)
            break;
        else
            adjacentFrom = randomEmpty();           
    }
    return adjacentFrom;
}

public boolean validIndex(int[] a,int i, int j)
{
    try
    {
        Pebble aPebble = array[a[0]+i][a[1]+j];
        return true;
    }
    catch(ArrayIndexOutOfBoundsException e)
    {
        return false;
    }
}
public void setCell(int xPos, int yPos, Pebble aPebble)
{
    array[xPos-1][yPos-1] = aPebble;
}

public Pebble getCell(int xPos, int yPos)
{
    return array[xPos-1][yPos-1];
}

执行的 JUNIT 测试:

@Test
public void testRandomAdjacent() {
    final int size = 5;
    final Board board2 = new Board(size);
    board2.setCell(1, 1, Pebble.O);
    board2.setCell(5, 5, Pebble.O);
    int[] idx = board2.randomAdjacent();
    int x = idx[0];
    int y = idx[1];
    boolean empty = true;
    for (int i = x - 1; i <= x + 1; i++) {
        for (int j = y - 1; j <= y + 1; j++) {
            if ((i == x && j == y) || i < 1 || j < 1 || i > size || j > size) {
                continue;
            }
            if (board2.getCell(i, j) != Pebble.EMPTY)
                empty = false;
        }

    }
    assertFalse(empty);// NEVER gets SET TO FALSE
    assertEquals(Pebble.EMPTY, board2.getCell(x, y));
}

最佳答案

至于答案:我对代码的可读性进行了优化。我认为很有可能

if (board2.getCell(i, j) != Pebble.EMPTY)
            empty = false;

导致问题的原因是 getCell 在基于 1 的坐标中运行,但 i、j 是在基于 0 的坐标中运行。

你应该从整体上考虑你的逻辑。在我看来,您的代码可能永远不会终止,因为 randomEmpty() 可能会在不确定的时间段内一遍又一遍地返回相同的字段。

我冒昧地将您的 if-if-if 级联重新编码为更易于阅读的实用方法:

public boolean hasNonEmptyNeighbor(int[] adjacentFrom) {
    for(int i = -1; i <= 1; ++i) {
      for(int j = -1; j <= 1; ++j) {
        if(validIndex(adjacentFrom, i, j) //Still inside the board
             &&                           // AND
           !isEmpty(adjacentFrom[0]+i     //not empty
                      ,adjacentFrom[1]+j)) {
          return true;
        }
      }
    }
    return false;
  }

鉴于我之前关于 random() 的评论,如果您需要覆盖整个棋盘,那么 random() 不是最好的选择,您的主要检查(给我一个带有非空邻居的空单元格)可以重写如下:

  public void find() {
     List<Point> foundPoints = new ArrayList<Point>();
     for(int i = 0; i < Board.height; ++i) { //Assumes you have stored your height
       for(int j = 0; j < Board.width; ++j) { //and your width
         if(isEmpty(i, j) && hasNonEmptyNeighbor(new int[]{i,j})) {
            //Found one.  
            foundPoints.add(new Point(i, j));
         }
       }
     }
     //If you need to return a RANDOM empty field with non-empty neighbor
     //you could randomize over length of foundPoints here and select from that list.
   }

关于java - IF 语句检查(无法正常工作),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34013736/

相关文章:

JavaFX Controlsfx 库 Check-ComboBox 自动完成

java - 用Java填充二维数组

java - Java中获取文件所在驱动器的最佳方法是什么?

python - 尝试在 python 中创建一个循环,让用户输入数组索引的长度

php - 遍历数组并获取键和值

mysql - 带循环的动态添加列

java - 将所有新行分隔符从 cr 或 crlf on bytes 更改为 crlf

php - 使用 PHP 将 SQL 查询行添加到新数组

Java用一个数组填充多个数组

excel - VBA 循环 : Automate web form filling