2015-12-01 145 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