+ Antworten
Ergebnis 1 bis 9 von 9

Thema: SchiffeVersenken

  1. #1
    User Bit Themenstarter

    Registriert seit
    27.06.2016
    Fachbeiträge
    5
    Genannt
    0 Post(s)
    Hallo erstmal
    Ich lerne jetzt seit ca. einem Jahr Java und wir (also meine Klasse) sind grade dabei ein Schiffe Versenken zu programmieren. Ich komme bei dem automatischen Schiffe setzen nicht weiter, bzw bei dem Prüfen ob der Hof des Schiffes frei ist.

    Hier mal mein Code:
    Java Code:
    1.  
    2.  public boolean pruefeHof(int startX, int startY, int laenge, boolean lage) {
    3.         int breite = 3;
    4.  
    5.         if (lage) { //waagerecht  ,
    6.             for (int y = startY - 1; breite > 0; breite--, y++) {
    7.                 int xLaenge = laenge + 2;
    8.                 for (int x = startX - 1; xLaenge > 0; xLaenge--, x++) {
    9.                     if (spielDaten[x][y] != 0) {
    10.                         return false;
    11.                     }
    12.                 }
    13.             }
    14.         } else { //senkrecht
    15.             for (int x = startX - 1; breite > 0; breite--, x++) {
    16.                 int xLaenge = laenge + 2;
    17.                 for (int y = startY - 1; xLaenge > 0; xLaenge--, y++) {
    18.                     if (spielDaten[x][y] != 0) {
    19.                         return false;
    20.                     }
    21.                 }
    22.             }
    23.         }
    24.  
    25.         return true;
    26.  
    27.     }
    Und jetzt noch das Alle Schiffe setzen programm:
    Java Code:
    1.  
    2. public void setzeAlleSchiffe() {
    3.         int laenge = 3;
    4.         for (int anz = 5; anz >= 0; anz--) {
    5.             boolean lage = wuerfel.nextBoolean();
    6.             if (lage) { //waagerecht
    7.                 do {
    8.                     int startX = wuerfel.nextInt((12 - (laenge + 1)) - 2) + 2;
    9.                     int startY = wuerfel.nextInt((12 - 2) - 2) + 2;
    10.  
    11.                 } while (pruefeHof(startX, startY, laenge, true));
    12.             } else { //senkrecht
    13.                 do {
    14.                     int startX = wuerfel.nextInt((12 - 2) - 2) + 2;
    15.                     int startY = wuerfel.nextInt((12 - (laenge + 1)) - 2) + 2;
    16.  
    17.                 } while (pruefeHof(startX, startY, laenge, false));
    18.  
    19.             }
    20.         }
    21.     }

    Entschuldigung falls ich nerve, aber ich weiß echt nicht was ich falsch mach... Vielleicht liegt das auch daran, dass ich jetzt seit 2Tagen nur noch diesen Code anstarre. Ich sollte wirklich mal ne Pause machen
    Und danke im Vorraus
    Geändert von JavaHasstMich (27.06.2016 um 18:13 Uhr) Grund: Titel, Java-Tags

  2. #2
    Global Moderator Viertel Gigabyte Avatar von SlaterB
    Registriert seit
    06.08.2008
    Fachbeiträge
    2.701
    Genannt
    277 Post(s)
    was ist ein 'Hof eines Schiffes'?
    was genau machen deine Methoden, was genau geht nicht?
    alles beschreiben

    wenn Zufall dabei ist (würfel), dann ist das für Untersuchungen immer ungünstig,
    Thema könnte enden wie dieses hier zuletzt
    https://forum.byte-welt.net/sonstige...tes-tuple.html

    verwende wenigstens new Random(42) oder so für konstante Resultate

    verwende System.out.println() um dir alles auszugeben, was ist der Stand des spielDaten-Arrays?
    welche x/y-Felder werden alles in einem Durchgang abgefragt, inwiefern gefällt dir das Ergebnis nicht?
    Hansa wird Meister

  3. #3
    User Bit Themenstarter

    Registriert seit
    27.06.2016
    Fachbeiträge
    5
    Genannt
    0 Post(s)
    Soo hab nochmal drübergescheut und Sachen überarbeitet das Pruefe Hof sieht jetzt so aus
    Java Code:
    1.  
    2. public boolean pruefeHof(int startX, int startY, int laenge, boolean lage) {
    3.         int breite = 3;
    4.  
    5.         if (lage) { //waagerecht  ,
    6.             for (int y = startY - 1; breite > 0; breite--, y++) {
    7.                 int xLaenge = laenge + 2;
    8.                 for (int x = startX - 1; xLaenge > 0; xLaenge--, x++) {
    9.                     if (spielDaten[x][y] != 0) {
    10.                         return false;
    11.                     }
    12.                 }
    13.             }
    14.         } else { //senkrecht
    15.             for (int x = startX - 1; breite > 0; breite--, x++) {
    16.                 int xLaenge = laenge + 2;
    17.                 for (int y = startY - 1; xLaenge > 0; xLaenge--, y++) {
    18.                     if (spielDaten[x][y] != 0) {
    19.                         return false;
    20.                     }
    21.                 }
    22.             }
    23.         }
    24.  
    25.         return true;
    26.  
    27.     }

    Ich werde das auch im Main Part nochmal überarbeiten, damit es jeder als erstes list, das hier ist nur für den Fall, dass es schon welche gelesen haben.

    *** Edit ***

    Also, dann muss ich das wohl erklären xD
    Der pruefeHof part prüft, ob die Umliegenden Felder des Arrays bereits mit einem Schiff (!=1 bei der if-Abfrage) schon mit einem Schiff belegt sind, damit das UP die Schiffe mit mindestens einem Feld abstand setzt.
    Also sprich so:
    000 0=zu prüfendes Feld
    0x0 x= geplantes Schiff
    0x0
    0x0
    000

    Ich bekomme beim compilieren immer den "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1"
    und zwar bei dein Zeilen
    Java Code:
    1.  
    2. for (int y = startY - 1; xLaenge > 0; xLaenge--, y++) {
    3.                     if (spielDaten[x][y] != 0) {
    4.                         return false;
    5.                     }

    sowie bei
    Java Code:
    1.  
    2. do {
    3.                     int startX = wuerfel.nextInt((12 - 2) - 2) + 2;
    4.                     int startY = wuerfel.nextInt((12 - (laenge + 1)) - 2) + 2;
    5.  
    6.                 } while (pruefeHof(startX, startY, laenge, false));

    Das ganze auch noch umgekehrt, wenn das Schiff waagerecht liegen soll.
    Java Code:
    1.  
    2. for (int x = startX - 1; xLaenge > 0; xLaenge--, x++) {
    3.                     if (spielDaten[x][y] != 0) {
    4.                         return false;
    5.                     }
    6.                 }

    sowie bei

    Java Code:
    1.  
    2. do {
    3.                     int startX = wuerfel.nextInt((12 - (laenge + 1)) - 2) + 2;
    4.                     int startY = wuerfel.nextInt((12 - 2) - 2) + 2;
    5.  
    6.                 } while (pruefeHof(startX, startY, laenge, true));

    das spielDaten Array, ist ein int Array
    Java Code:
    1.  
    2. private int[][] spielDaten = new int[12][12];

    Ich würde gerne nicht Zufahlszahlen benutzen, jedoch ist das ein bisschen seltsam, da er die Zahlen ja würfeln soll.
    Geändert von Marco13 (27.06.2016 um 19:11 Uhr) Grund: Mehr Java tags

  4. #4
    User Floppy Disc Avatar von Sen-Mithrarin
    Registriert seit
    26.10.2013
    Fachbeiträge
    755
    Genannt
    63 Post(s)
    @SlaterB
    Hier hat mal wieder der Spam-Filter zugeschlagen - der top-post ist noch nicht für alle verfügbar - bitte mal freigeben =P
    Biskuit ... das is' glaub ich fast so 'ne Suppe
    ein vergruseltes 2016 und so ...
    "Darf ich dir noch was anbieten?" - "Du meinst außer Steaks, Bier, Kippen und nen Lapdance?"

  5. #5
    User Megabyte Avatar von Timothy_Truckle
    Registriert seit
    01.08.2013
    Ort
    Wasserkuppe
    Fachbeiträge
    1.329
    Genannt
    85 Post(s)
    Blog-Einträge
    5
    Wenn ich das Problem richtig verstehe geht es um die Initialisierung des Spielfeldes und dabei um die Regel, dass die Schiffe in jeder Richtung ein Feld abstand haben müssen.

    Mein Ansatz wäre ja mal wieder ein ganz anderer:
    1. Es gibt neben dem Spielfeld-Array noch eine Liste aller verfügbaren Zellen, die für ein Schiff verwendet werden können. Das sind am anfang alle.


    2. Zellen des Spielfeldes Sind Objekte, die sich selbst aus dieser Liste Austragen, wenn sie einem Schiff zugeordnet werden.
      Java Code:
      1. interface CellResevedListener {
      2.    void unavailable(Cell cell);
      3. }
      4. class Cell{
      5.    private final CellResevedListener cellResevedListener;
      6.    public Cell(CellResevedListener cellResevedListener){
      7.       this.cellResevedListener=cellResevedListener;
      8.    }
      9.    public void addToShip(){
      10.      cellResevedListener.unavailable(this);
      11.    }
    3. Das Spiel erzeug für jede Zelle so einen CellResevedListener :
      Java Code:
      1. Collection<cell> availableCells = new ArrayList<>();
      2. for(int i=0;i<width;i++)
      3.   for(int j=0;j<heigth;j++){
      4.      Cell cell = new Cell (me) ->availableCells.remove(me));
      5.      gameBoard[i][j]=cell;
      6.   }
    4. Eine Zelle kennt ihre Nachbarn
      Die Zuordnung der Nachbarn mus in einer weiteren iteration über das Spielfeld-Array erfolgen, weil man ja zu dem Zeitpunkt, wo man eine Zelle erstell, die zukünftigen Zellen noch nicht hat...
      Java Code:
      1. class Cell{
      2. // dies hier ist zusätzlich in der Cell-Classe
      3.   private final Collection<Cell> neighbours  = new ArrayList<>();
      4.   public void addNeighbours(Collection<Cell> neighbours){
      5.      this.neighbours .clear();
      6.      this.neighbours.addAll(neighbours);
      7.   }
      8. }
    5. Die Zelle weiß. ob sie zu einem Schiff gehört:
      Java Code:
      1. class Cell{
      2. // alles hier zuzätzlich!!!
      3.    private boolean isShip =false;
      4.    public void addToShip(){
      5.      this.isShip = true;
      6.    }
      7. }
    6. Eine Zelle sagt Ihren Nachbar, wenn sie zu einem Schiff zugeordnet wurde:
      Java Code:
      1. class Cell{
      2.    public void addToShip(){
      3.      cellResevedListener.unavailable(this);
      4.      // neu in der Methode
      5.       for(Cell neighbour: neighbours  )
      6.           neighbour.youAreShipNeigbour();
      7.    }
      8.    
      9. // neue Methode
      10.    private void youAreShipNeigbour(){
      11.      
      12.    }
    7. Auch eine Nachbarzelle trägt sich auch aus der Verfügbarenliste aus
      Java Code:
      1. class Cell{
      2.    private void youAreShipNeigbour(){
      3.      // neu in der Methode
      4.      cellResevedListener.unavailable(this);
      5.    }

    Ab jetzt kann man ohne weitere Checks davon ausgehen, dass eine Zelle, die man aus availableCells holt mindestens ein Feld von seinen Nachbarn entfernt ist.

    bye
    TT
    Geändert von Timothy_Truckle (27.06.2016 um 19:05 Uhr)

  6. #6
    Global Moderator Viertel Gigabyte
    Registriert seit
    05.08.2008
    Fachbeiträge
    4.913
    Genannt
    309 Post(s)
    Mal ganz konkret: Exceptions sind schon was feines. Man sieht, in welcher Zeile der Fehler aufgetreten ist. Und wenn der, der die Exception wirft, kein A... gewissenhaft gearbeitet hat, dann sieht man sogar, WAS falsch war.

    In diesem Fall: Wenn da eine "ArrayIndexOutOfBoundsException: -1" fliegt, dann sieht man, dass in diesem Fall...
    Java Code:
    1.  
    2. for (int y = startY - 1; xLaenge > 0; xLaenge--, y++) {
    3.     if (spielDaten[x][y] != 0) {
    4.         return false;
    5. }
    wohl entweder "x" oder "y" -1 sein muss. Und y könnte -1 sein, wenn "startY==0" ist.

    Was auch immer da genau geprüft wird, habe ich nicht nachvollzogen, aber wie man das Problem umgeht, kann man zumindest leicht andeuten:
    Java Code:
    1.  
    2. int minY = startY - 1;
    3. if (minY < 0) minY = 0;
    4. for (int y = minY; .... ) {
    5.     ....
    6. }
    (es gibt vermutlich elegantere Lösungen, auf verschiedenen Ebenen, aber ... zumindest sollte obiges nachvollziehbar sein)

  7. #7
    User Bit Themenstarter

    Registriert seit
    27.06.2016
    Fachbeiträge
    5
    Genannt
    0 Post(s)
    Danke an allle habs selbst nochmal neu geschrieben und jetzt gehts
    Falls ihr das auch und den code wollt schreibt mich an

  8. #8
    Global Moderator Floppy Disc Avatar von Landei
    Registriert seit
    31.07.2013
    Ort
    Sandersdorf-Brehna
    Fachbeiträge
    991
    Genannt
    164 Post(s)
    Blog-Einträge
    27
    Nebenbei wird das Problem, beim Überprüfen der Nachbarfelder "über den Rand" zu kommen, in vielen Brettspiel-Implementierungen so gelöst, dass man rings um das eigentliche Feld noch eine (oder bei Schach wegen der Springer zwei) Reihen "toter" Felder legt - sozusagen auch ein Art "Hof". Natürlich muss man die Indizes entsprechend anpassen, die dann 1- statt 0-basiert sind.

  9. #9
    Global Moderator Viertel Gigabyte
    Registriert seit
    05.08.2008
    Fachbeiträge
    4.913
    Genannt
    309 Post(s)
    Das macht man speziell bei Schach nicht zuletzt für die Performance (da gibt's eine Menge Infos dazu unter https://chessprogramming.wikispaces....Representation ). Nach den hier offenbar zu vermittelnden Infos "Was ist ein Array?" und "Was ist eine if-schleife?" ( ) würde ich persönlich eher Empfehlungen in der Richtung geben, dass es irgendwo eine boolean isValid(int x, int y) oder sowas wie List<Point> getNeighbors(int x, int y) geben könnte...

+ Antworten Thema als "offen" markieren

Direkt antworten Direkt antworten

Besser den Spatz in der Hand als die Taube auf dem ...

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Ähnliche Themen

  1. Schiffeversenken Extreme
    Von sunjojo im Forum Spiele- und Multimedia-Programmierung
    Antworten: 7
    Letzter Beitrag: 16.06.2014, 21:35
  2. Hilfe bei iTunes
    Von Jango im Forum Spielwiese
    Antworten: 3
    Letzter Beitrag: 24.01.2014, 09:34
  3. Hilfe bei Rekursion
    Von Unregistriert im Forum Java-Grundlagen
    Antworten: 3
    Letzter Beitrag: 05.04.2013, 17:12
  4. Hilfe
    Von Bruchapplet im Forum Hausaufgaben
    Antworten: 1
    Letzter Beitrag: 30.10.2010, 20:58
  5. Hilfe
    Von Dendem im Forum Java-Grundlagen
    Antworten: 10
    Letzter Beitrag: 20.07.2009, 16:26

Berechtigungen

  • Neue Themen erstellen: Ja
  • Themen beantworten: Ja
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •