2015-12-01 147 views
0

randomEmpty()返回一个空的n×n网格上的随机坐标(方法工作)。 randomAdjacent()使用randomEmpty()在地图上选择一个EMPTY坐标。然后进行比较,看看这个坐标是否有VALID相邻坐标是NON-EMPTY。问题是randomAdjacent并不总是以相邻的非空空间返回空间坐标。它将始终返回有效的坐标,但不是后者。我无法发现问题。有人可以帮我找出问题吗?IF语句检查(工作不正常)

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)); 
} 

回答

1

至于答案:我被抬出优化的可读性代码。我认为这是最有可能

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

为getCell在1 - 基于坐标操作引起的问题,但I,J是从0开始。

你应该总体思考你的逻辑。我看到它的方式,你的代码可能永远不会终止,因为randomEmpty()可以在一段不确定的时间段内一遍又一遍地返回相同的字段。

我冒昧地重新编写你的,如果假设 - 如果级联成实用的方法更容易阅读:

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; 
    } 

鉴于我以前的有关评论随机()是不是最好的选择,如果你需要覆盖您的主要检查(给我一个空的单元格与一个非空的邻居)可以被重写为这样的:

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. 
    } 
+0

谢谢@Jan。我知道我可以浓缩我的陈述,但我选择削减角落,因为我是从一种方式而不是其他方式来思考的。我确实需要为$ find()$返回一个带有非空邻居的随机空字段,但这应该很容易做到。 – FutureUIUXDeveloper