2013-06-11 1 views
1

это я снова. Я пытаюсь сделать очень простую игру Battleships. Теперь я хочу, чтобы корабли были отделены хотя бы одной свободной ячейкой. Посмотрите на картинкуБоевые корабли не могут быть размещены на краю

enter image description here

Как вы видите, край полностью корабельного бесплатно, что делает доступным количество размещения гораздо меньше (или меньше? Извините за мой плохой английский).

«Поле» - это просто массив int [10] [10].

У меня есть очень грубый метод, чтобы проверить avaibality поместить корабль: (IS_WATER Const = 0)

private static boolean checkIfShipAvailable(int x, int y, int dir, int length) { 
     int counter = 0; 
     switch(dir) { 
     case DIRECTION_RIGHT: 
      try { 
       if(field[x-1][y] == IS_WATER) counter++;  
       if(field[x-1][y-1] == IS_WATER) counter++;  
       if(field[x-1][y+1] == IS_WATER) counter++;  
       if(field[x][y-1] == IS_WATER) counter++;  
       if(field[x][y+1] == IS_WATER) counter++;  
       if(field[x+1][y-1] == IS_WATER) counter++;  
       if(field[x+1][y+1] == IS_WATER) counter++;  

       if(field[x+length-1][y-1] == IS_WATER) counter++; 
       if(field[x+length-1][y+1] == IS_WATER) counter++; 
       if(field[x+length][y] == IS_WATER) counter++; 
       if(field[x+length][y-1] == IS_WATER) counter++; 
       if(field[x+length][y+1] == IS_WATER) counter++; 

      } catch (IndexOutOfBoundsException e) { 
       counter++; 
      } 
      Log.d(TAG, "Direction: Right. Counter = " + counter); 
      if (counter == 12) 
       return true; 
      break; 

     case DIRECTION_DOWN: 
      try { 
       if(field[x-1][y-1] == IS_WATER) counter++ ; 
       if(field[x][y-1] == IS_WATER) counter++ ; 
       if(field[x+1][y-1] == IS_WATER) counter++ ; 
       if(field[x-1][y] == IS_WATER) counter++ ; 
       if(field[x+1][y] == IS_WATER) counter++ ; 
       if(field[x-1][y+1] == IS_WATER) counter++ ; 
       if(field[x+1][y+1] == IS_WATER) counter++ ; 

       if(field[x-1][y+length-1] == IS_WATER) counter++ ; 
       if(field[x+1][y+length-1] == IS_WATER) counter++ ; 
       if(field[x-1][y+length] == IS_WATER) counter++ ; 
       if(field[x][y+length] == IS_WATER) counter++ ; 
       if(field[x+1][y+length] == IS_WATER) counter++ ; 

      } catch (IndexOutOfBoundsException e) { 
       counter++; 
      } 
      Log.d(TAG, "Direction: Down. Counter = " + counter); 
      if (counter == 12) 
       return true; 
      break; 
     } 
     return false; 
    } 

Это на 2-4 клеток кораблей. И 1-элементная корабля:

private static boolean checkIfOneAvailable(int x, int y) { 
     int counter = 0; 
     try { 
       if(field[x-1][y-1] == IS_WATER) counter++ ; 
       if(field[x][y-1] == IS_WATER)counter++ ; 
       if(field[x+1][y-1] == IS_WATER) counter++ ; 
       if(field[x-1][y] == IS_WATER) counter++ ; 
       if(field[x+1][y] == IS_WATER) counter++ ; 
       if(field[x-1][y+1] == IS_WATER) counter++ ; 
       if(field[x+1][y+1] == IS_WATER) counter++ ; 
       if(field[x][y+1] == IS_WATER) counter++ ; 
     } catch (IndexOutOfBoundsException e) {  
      counter++; 
     } 
     if (counter == 8) 
      return true; 
     return false; 

    } 

Не могли бы вы сказать мне, где ошибка и как я могу сделать корабли быть размещены даже на краях?

+0

Вы не хотите испытывать воду. Вы хотите проверить, нет ли еще какого-то корабля. – NeplatnyUdaj

+0

IS_WATER означает пустую ячейку – Groosha

+0

Я вижу это. Но если вы попытаетесь это сделать, проверив для кораблей, алгоритм будет легче понять. – NeplatnyUdaj

ответ

1

Если IndexOutOfBoundsException происходит все позднее if(field... линии до catch не выполняются, и счетчик больше не увеличивается.

Лучшее решение: создать метод, который принимает координаты и возвращает либо значение field[x][y] или специальное OUT_OF_BOUNDS значение (ловя IndexOutOfBoundsException или проверки границ)

+0

Вы имеете в виду (if ((поле [x + 1] [y] == IS_WATER) || myNewMethod == true)? – Groosha

+1

Вы избили меня до этого! В будущем он также может запустить приложение в режиме отладки и пройти метод, который дал бы более быстрый ответ, чем запрос переполнения стека, хотя это лишило бы нас от боевых действий за повторные точки хаха. –

+0

@ Kondra007 Нет, замените ваше поле [x + 1] [y] == IS_WATER' на 'myNewMethod (x + 1, y)! = IS_SHIP' –

2

Не испытать для воды. Проверьте, есть ли другое судно. Например:

private static boolean checkIfOneAvailable(int x, int y) {   
    if(x!=0 && y!=0 && field[x-1][y-1] == IS_SHIP) return false; 
    if(y!=0 && field[x][y-1] == IS_SHIP) return false; 
    ... 
    return true; 
} 

Обратите внимание, что я добавил проверки для границ массива в состояние. Использование исключения для управления потоком считается плохой привычкой главным образом потому, что оно медленное. При использовании этого подхода вы также получите прирост производительности от факта, что вам не всегда нужно проверять все окружающие поля. Как только вы обнаружите столкновение, вы получите результат.

Также нет смысла копировать код для более крупных кораблей. Пока вы не разместите корабль, вы все равно можете сделать такую ​​же проверку для каждого поля больших судов:

private static boolean checkIfAvailable(int x, int y, int dir, int length){ 
    for (int i = 0; i<length; i++){ 
     switch (dir) { 
      case DIRECTION_RIGHT: 
       if (!checkIfOneAvailable(x+i,y)) 
        return false; 
       break; 
      case DIRECTION_DOWN: 
       if (!checkIfOneAvailable(x,y+i)) 
        return false; 
       break; 
     }    
    } 
    return true; 
} 
+0

Я не думаю, что он применим для больших кораблей, так как поле [x + 1] [y], в то время как направление правильное всегда будет Например, дайте ложь, но это всего лишь примечание – Groosha

+0

Я не понимаю, почему это было бы b e false?Я думал, что вы поместите весь корабль после того, как вы проверите, можно ли его разместить. Итак, если у вас есть корабль 2 * 1, вы можете проверить, могут ли быть размещены обе части корабля. Где поймать? – NeplatnyUdaj

+0

Не могли бы вы взглянуть на это: http://pastebin.com/LeH6bANt ... никакие корабли не размещены на нижней и правой стороне. – Groosha

Смежные вопросы