2016-12-06 4 views
-1

Цель состоит в том, чтобы свести к минимуму количество выстрелов, которые я беру на борту линкора, который генерируется случайным образом. Мой метод fireShot() должен определить, была ли точка в моем 2D-массиве уже снята, промах или попадание.Battleship Shot Firing [Java]

public boolean fireShot() 
{ 

Random rand = new Random(); 

int i = rand.nextInt(10); //generate 2 random numbers for rows and columns 
int j = rand.nextInt(10); 
Point shot = new Point(i,j); 

while (mapState[i][j] != empty){ 
     j = rand.nextInt(10); 
     i = rand.nextInt(10); 
     mapState[i][j] = shotAt; 
} 

boolean hit = battleShip.shoot(shot); 

if(hit == false){ 
    mapState[i][j] = miss; 
} 

else if(hit == true){ 
    mapState[i][j] = hitInt; 
    huntMode(i,j); 
} 

return false; 
} 

Метод battleShip.shoot возвращает логическое значение, если точка попадает на лодку.

Проблема в том, что эффективность одинакова и не пропускает элементы, которые уже были пропущены или удалены.

+3

что ваша проблема? –

+0

@WasiAhmad это не меняет эффективность вообще. Программа должна пропустить все элементы, которые уже были удалены или пропущены, но, похоже, это не так. –

+0

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

ответ

1

Итак, вы сохраняете значения I и J в двух местах: как i и j, а также в переменной shot. В цикле while вы назначаете новые значения i и j, но не shot, поэтому при вызове battleShip.shoot() оно всегда устанавливается на исходное значение. Я предлагаю не создавать shotPoint, пока вы не позвоните battleShip.shoot(). Кроме того, я предлагаю использовать цикл do {} while() вместо while, поэтому вам не нужно дублировать случайные вызовы. Вам также не нужно проверить hit == true вы можете просто сделать if (hit) ... else ... что-то вроде этого:

public boolean fireShot() { 
    Random rand = new Random(); 
    int i, j; 

    do { 
     j = rand.nextInt(10); 
     i = rand.nextInt(10); 
    } while (mapState[i][j] != empty); 

    mapState[i][j] = shotAt; 

    boolean hit = battleShip.shoot(new Point(i, j)); 

    if (hit) { 
     mapState[i][j] = hitInt; 
     huntMode(i, j); 
    } else { 
     mapState[i][j] = miss; 
    } 

    return false; 
} 
0

Я удалил мой предыдущий ответ, и теперь пытаюсь решить проблему, что ваш код страдает от.

int i = rand.nextInt(10); //generate 2 random numbers for rows and columns 
int j = rand.nextInt(10); 

while (mapState[i][j] != empty){ 
     j = rand.nextInt(10); 
     i = rand.nextInt(10); 
     mapState[i][j] = shotAt; 
} 

В приведенном выше фрагменте кода, например, если i = 4 and j = 6 и был снят раньше, то вы должны ввести время цикла, так как условие mapState[i][j] != emptyempty = 0 где. Затем вы снова создаете пару чисел и назначаете shootAt, а затем снова проверяете условие цикла while, который всегда будет ложным из-за инструкции внутри этого цикла. (Вы должны столкнуться бесконечный циклом здесь)

Единственный раз, когда вы можете вернуть значение из метода fireShot(): если для случайных чисел пары i, j генерируемой перед входом в то время цикла, состояние доски пусто (никогда не стреляло до того). Правильно? Надеюсь, теперь вы поймете ошибку. Вот почему @YonaAppletree изменил ваш код следующим образом.

Random rand = new Random(); 
int i, j; 

do { 
    j = rand.nextInt(10); 
    i = rand.nextInt(10); 
} while (mapState[i][j] != empty); 

mapState[i][j] = shotAt; 

Теперь этот цикл do-while найдет пустую ячейку с доски, чтобы снимать на: то, что вы на самом деле намеревались сделать. Но ответ @LorisSecuro предоставлен более достойным, и вы должны следовать этому.

Сообщите мне, если вы считаете, что я сказал, что это неверно.

2

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

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

Для этого вы можете создать List из не использовали Points и использовать rand, чтобы получить индекс в этом List. Объект в этом индексе будет неиспользуемой точкой, которая получает выстрел.Как только вы это сделаете, вы удалите Point из List, так что следующий rand все равно будет генерировать индекс, указывающий на неиспользованную точку.

Например, сначала сгенерировать List неиспользованных точек:

int maxX = 10; 
int maxY = 10; 

// create the list with all the map positions: (0,0)(0,1)...(9,9) 
List<Point> pointsToTry = new ArrayList<Point>(); 
for (int iy = 0; iy < maxY; iy++) { 
    for (int ix = 0; ix < maxX; ix++) { 
     pointsToTry.add(new Point(ix, iy)); 
    } 
} 

Тогда при каждом выстреле вы просто:

// get a random index of an unused point 
int i = rand.nextInt(pointsToTry.size()); 
// remove that point from the list so it will not be picked again 
Point shot = pointsToTry.remove(i);