2016-12-06 1 views
-1

Ziel ist es, die Anzahl der Schüsse zu minimieren, die ich auf einem zufällig erzeugten Schlachtschiffbrett erhalte. Meine fireShot() -Methode soll bestimmen, ob der Punkt in meinem 2D-Array bereits beschossen wurde, ein Fehlschlag oder ein Treffer.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; 
} 

Die battleShip.shoot Methode gibt einen boolean, wenn der Punkt ein Boot trifft.

Das Problem ist, dass die Effizienz die gleiche ist und Elemente, die bereits verpasst oder getroffen wurden, nicht überspringt.

+3

was ist dein Problem? –

+0

@WasiAhmad verändert es die Effizienz überhaupt nicht. Das Programm sollte alle Elemente überspringen, die bereits getroffen oder verpasst wurden, aber das scheint es nicht zu tun. –

+0

Möchten Sie eine Zufallszahl generieren, die vorher nicht generiert wurde? Was meintest du mit Effizienz? Warum sollte das Programm alle Elemente überspringen, die bereits getroffen oder verpasst wurden? Deine Frage ist noch nicht klar! –

Antwort

1

So speichern Sie die I- und J-Werte an zwei Stellen: als i und j und auch in der shot Variable. In der while-Schleife weisen Sie i und j neue Werte zu, jedoch nicht shot. Daher wird der Wert immer auf den ursprünglichen Wert gesetzt, wenn Sie battleShip.shoot() aufrufen. Ich schlage vor, die shotPoint nicht zu erstellen, bis Sie battleShip.shoot() anrufen. Außerdem schlage ich vor, eine do {} while() Schleife anstelle von while zu verwenden, so dass Sie die zufälligen Anrufe nicht duplizieren müssen. Sie brauchen auch nicht hit == true zu überprüfen, die Sie gerade if (hit) ... else ... So etwas wie dies tun können:

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

ich meine Antwort entfernt haben und nun versuchen, ein Problem zu adressieren, die Ihr Code leidet.

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

In dem obigen Code-Schnipsel, zum Beispiel wenn i = 4 and j = 6 und es vor geschossen wurde, dann würden Sie die while-Schleife eingeben, da die Bedingung mapState[i][j] != empty wo empty = 0 ist. Dann generieren Sie erneut ein Zahlenpaar und weisen shootAt zu und überprüfen dann erneut die Bedingung der while-Schleife, die aufgrund der mapState[i][j] = shotAt;-Anweisung innerhalb dieser Schleife immer falsch ist. (Sie sollen hier eine Endlosschleife auftreten)

Das einzig Mal, wenn Sie einen Wert von Ihrer fireShot() Methode zurückgeben können, ist: Wenn für das Zufallszahlenpaar i, j erzeugt, bevor die while-Schleife eintritt, Board Zustand leer ist (nie geschossen vor). Recht? Hoffentlich können Sie den Fehler jetzt verstehen. Deshalb hat @YonaAppletree den Code folgendermaßen geändert.

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; 

Nun ist diese do-while-Schleife eine leere Zelle aus dem Board finden zu schießen: was Sie eigentlich tun sollen zu. Aber die Antwort @LorisSecuro zur Verfügung gestellt ist mehr wert und Sie sollten folgen.

Lassen Sie mich wissen, wenn Sie denken, was auch immer ich gesagt habe, ist falsch.

2

Ihr Code ist nicht effizient, weil er versucht, ungenutzte Punkte nach dem Zufallsprinzip zu finden, was mehr und mehr Versuche erfordert, sobald die Karte mehr und mehr gefüllt ist.

Daher sollten Sie versuchen, Zufallszahlen in der gesamten Karte zu vermeiden, aber nur in der Teilmenge von Punkten, die nicht bereits verwendet wurden.

zu tun, damit Sie eine List von nicht verwendet schaffen könnte Points und verwenden rand einen Index in diesem List zu erhalten. Das Objekt in diesem Index wird ein unbenutzter Punkt sein, der aufgenommen wird.Sobald Sie das tun, entfernen Sie das Point aus dem List, damit das nächste rand immer noch einen Index erzeugt, der auf einen unbenutzten Punkt zeigt.

Zum Beispiel zunächst die List ungenutzter Punkte generieren:

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

Dann wird bei jedem Schuss Sie einfach:

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