# Array Abfrage will nichts so wie ich will....



## phreeak (16. Januar 2012)

Tag,

ne Abfrage eines Array möchte nicht so wie ich will..


Die Methode in der Klasse Spielfeld wird wie folgt aufgerufen,


```
if (feld.spielfeldVoll(eingabe)) {
             istGueltig = false;
             consolenausgaben.BildschirmAusgaben("ReiheVoll");
        }
```

die Methode,


```
public boolean spielfeldVoll(int eingabe) {
    boolean istVoll = true;
              for (int i = 5; i >=0; i--) {
                if (spielfeld[i][eingabe]== ' ') {
                 istVoll = false;
                }
            } 
    return istVoll;
    }
```

spielfeld ist als klassen variable deklariert, also


```
public class Spielfeld {
       
       char[][] spielfeld = new char [6][7];
..
....
......
```

so, standart Wert true, also das die reihe "voll" ist.
Wenn er die Reihe durch geht und er finden ein leeres Feld bzw. "leerzeichen" soll er istVoll auf false setzen, da die Reihe ja nicht voll ist. Dies macht er aber nicht.

Grad kein Schimmer, wieso er nicht will..

Zuvor ging es.

Hatte Anfangs das komplette Programm in einer Klasse, wo spielfeld immer an die Methoden übergeben wird. (Das Array wurde am Anfang definiert).. jetzt nachdem ich mein Programm in verschiedenen Klassen aufgeteilt habe, mag er nicht mehr.


----------



## vfl_freak (17. Januar 2012)

Moin,



> Dies macht er aber nicht.


Und das heißt was 

Wo und wie wird "spielfeld" denn gefüllt ?
Wieso ist es sicher, dass dort KEIN Blank vorkommt ?

Gruß
Klaus


----------



## Herbertus (17. Januar 2012)

Deine Abfrage ist falsch.


```
if( spielfeld[i][eingabe] == '\u0000' )
```

Muss sie lauten.


----------



## phreeak (17. Januar 2012)

vfl_freak hat gesagt.:


> Moin,
> 
> 
> Und das heißt was
> ...



das spielfeld wird in einer anderen Methode mit leerzeichen gefült und auf der Console ausgegeben. (leerzeichen, damit die | und __ nicht so gequetscht aussehen). In der Abfrage wird ja auf nen leerzeichen abgefragt ob ne reihe voll ist (mitm char) oder leer ist (bzw. nen leerzeichen ist)

@Herbertu, klappt leider nicht,

er führt die methode nun aus, aber erkennt nicht wenn ne reihe voll ist.


Zuvor hat er die methode aus ausgeführt, hat aber immer "reihe voll" ausgegeben obwohl  nur 1 feld belegt war.


----------



## vfl_freak (17. Januar 2012)

Moin,



phreeak hat gesagt.:


> In der Abfrage wird ja auf nen leerzeichen abgefragt.


Eben darum meine Frage ;-)

Gruß
Klaus


----------



## phreeak (17. Januar 2012)

was meinst mit blank?! jedenfalls sagte er, dass die reihe voll war, obwohl nix drinnen ist, halt nur, die leerzeichen, mit dennen ich das Feld gefüllt habe. Darauf frage ich ja auch ab...


Komischerweise klappt es ja im ersten Programm, wo alles in einer Klasse steht. Nach der aufteilung klappt es aber nimmer. <.<


----------



## vfl_freak (17. Januar 2012)

Moin,



phreeak hat gesagt.:


> was meinst mit blank?!


na, Leerzeichen (auf Englisch) :-D



phreeak hat gesagt.:


> jedenfalls sagte er, dass die reihe voll war, obwohl nix drinnen ist, halt nur, die leerzeichen, mit dennen ich das Feld gefüllt habe. Darauf frage ich ja auch ab...



Also: Dein *' '* steht nur mal für ein Blank (= Leerzeichen) oder in HEX 0x20 und ist was anderes als 0x00 oder eben '\u0000'.

Worauf soll denn dort nur geprüft werden 

Gruß
Klaus


----------



## Herbertus (17. Januar 2012)

Also jetzt bin ich auch verwirrt. 

Wenn du auf ein LEERZEICHEN überprüfen willst, wäre meins natürlich auch falsch. Prüfst du, ob überhaupt irgendwas gesetzt ist, wäre meins richtig.

Kannst du es bitte nochmal SAUBER formulieren (Eventuell kannst du auch einfach nur mehr Code einfügen, damit es nachvollziehbar wird, was du willst)


----------



## phreeak (17. Januar 2012)

Kp 

ich fülle das Spielfeld so


```
public void setzeSpielfeld() {
               
               for(int i = spielfeld.length - 1; i >= 0; i--) {
          for(int j = spielfeld[i].length - 1; j >= 0; j--) {
              spielfeld[i][j] = ' ';
          }
       }
       zeigeSpielfeld();      
    }
```

also mitm normalen leerzeichen.....

hier,


```
public int setzeSpielstein(int feld, char spieler) {
        boolean istWahr = false;
        int reihe = 0;
        for (int i = spielfeld.length - 1; i >= 0 && !istWahr; i--) {
            if (spielfeld[i][feld]== ' ') {
                spielfeld[i][feld] = spieler;
                istWahr = true;
                reihe = i;
            }
        }
        zeigeSpielfeld(); 
        return reihe;
    }
```

frag ich die reihe ebenfalls ab, um den Spielstein zusetzen..er geht die reihe von unten z.B 5,0 nach oben hoch und setzt den Spielstein erst dann, wenn spielfeld[x][y] = ' ' ist... klappt hier wunderbar.

aber das hier ist eh das kleinste Problem.. Hab auch noch Probleme mit meiner Subklasse (Kapier das mit der Subklasse noch nicht wirklich)



Herbertus hat gesagt.:


> Also jetzt bin ich auch verwirrt.
> 
> Wenn du auf ein LEERZEICHEN überprüfen willst, wäre meins natürlich auch falsch. Prüfst du, ob überhaupt irgendwas gesetzt ist, wäre meins richtig.
> 
> Kannst du es bitte nochmal SAUBER formulieren (Eventuell kannst du auch einfach nur mehr Code einfügen, damit es nachvollziehbar wird, was du willst)



nein soll  ur überprüft werden ob ein LEERZEICHEN drinnen ist...


----------



## Herbertus (17. Januar 2012)

So, man(! ). Nochmal neuer Post.

Also es geht, wie ich gerade lesen konnte ja, wenn alles in einer Klasse steht.

Dann zeig mal deine Klassen^^


----------



## phreeak (17. Januar 2012)

das ganze programm oder die klasse?!
Es funktionierte noch, als das Programm in einer Klasse war.. nachdem Aufteilen in Klassen klappte es aufeinmal nicht mehr..

Das ganze Programm, wo es in einer Klasse war, hat ca. 450 zeilen..
Die Klasse Spielfeld nun, wo es drinnen steht 216..


```
ackage viergewinnt_aufgabe2;

     /** ******************************************
     * Klasse die das Spielfeld setzt, anzeigt und den Spieler setzt
     ************************************************/
public class Spielfeld {
       
       private char[][] spielfeld = new char [6][7];
     /** ******************************************
     * Sezt das Spielfeld
     ************************************************/     
    public void setzeSpielfeld() {
               
               for(int i = spielfeld.length - 1; i >= 0; i--) {
          for(int j = spielfeld[i].length - 1; j >= 0; j--) {
              spielfeld[i][j] = ' ';
          }
       }
       zeigeSpielfeld();      
    }
     /** ******************************************
     * Zeigt das Spielfeld an
     ************************************************/      
    public void zeigeSpielfeld() {
        for (int i=0;i<6;i++) {
            for (int j=0;j<7;j++) {
                System.out.print("|"+spielfeld[i][j]);
            }
            System.out.println();
            System.out.println("--------------");
        } 
                 for (int j=1;j<8;j++) {
                    System.out.print("|"+j); 
                 }
                 System.out.println("");
                 System.out.println();
    }
    
        /** ******************************************
     * Prüft Senkrechte, Waagerechte und Diagonale Zeilen ob es ein Sieger gibt
     * oder ob es Unentschieden endett
     * @param feld - Feld des Arrays
     * @param reihe - Reihe des Arrays
     * @param spieler - Aktueller Spieler
     ************************************************/    
    public char hatGewonnen(int feld, int reihe, char spieler) {
        boolean istunentschieden = true;
        char sieger = ' ';
        for(int i = spielfeld.length - 1; i >= 0; i--) {
          for(int j = spielfeld[i].length-1; j >= 0; j--) {
              if(spielfeld[i][j] == ' ')
              istunentschieden = false;
          }
        } 
        if (istunentschieden) {
              sieger = '?';
        }
        
        //vertikal nach unten
        
        int zaehler=0;
        int _reihe = reihe;
        int _feld = feld;
 
        for (int i = reihe; i<6;i++) {
            if (spielfeld[_reihe][_feld] == spieler) {
            _reihe++;    
            zaehler++;
            }
        }
        
        if (zaehler>=4){
            sieger = spielfeld[reihe][feld];
            return sieger;
        }

        sieger = hatGewonnenHor(feld, reihe, spieler, sieger);
        sieger = hatGewonnenDia(feld, reihe, spieler, sieger);
        
        return sieger;
    }
    
    /** ******************************************
     * Prüft Horizontal ob ein Gewinner feststeht
     * @param feld - Feld im Array
     * @param reihe - reihe die der Spieler angegeben hat
     * @param spieler - Aktueller Spieler
     * @param sieger - Zeigt den Sieger an
     ************************************************/    
    public char hatGewonnenHor(int feld, int reihe, char spieler, char sieger) {
         //horizontal nach rechts
        int _reihe = reihe;
        int _feld = feld;
        int z = feld;
        int zaehler = 0;
        for (int i = feld; i<7;i++) {
          if (spielfeld[_reihe][_feld] == spieler)  {
                _feld++;
                zaehler++;
          
          }
        }
        //nach links
        for (int c = feld; c>0;c--) {
            if (spielfeld[_reihe][z-1] == spieler)  {
                z--;
                zaehler++;
            }
        }

        if (zaehler>=4){
            sieger = spielfeld[reihe][feld];
            return sieger;
        }
        return sieger;
    }
    
     /** ******************************************
     * Prüft Diagonal ob ein Gewinner feststeht
     * @param feld - Feld im Array
     * @param reihe - reihe die der Spieler angegeben hat
     * @param spieler - Aktueller Spieler
     * @param sieger - wenn Aktueller sieger ist, wirds in Sieger gespeichert
     ************************************************/   
    public char hatGewonnenDia(int feld, int reihe, char spieler, char sieger) {
         //diagonal nach links unten
        int _reihe = reihe;
        int _feld = feld;
        int z = feld;
        int j = reihe;
        int zaehler = 0;
        for (int i = feld, c = reihe;i>=0 && c<6;i--,c++) {
          if (spielfeld[_reihe][_feld] == spieler)  {
              _reihe++;
              _feld--;
              zaehler++;
          }
        }
        // rechts oben
          for (int i = reihe, c = feld;i>0 && c<6;i--,c++) {
          if (spielfeld[j-1][z+1] == spieler)  {
              j--;
              z++;
              zaehler++;
          }
        }
       
        if (zaehler>=4){
            sieger = spielfeld[reihe][feld];
            return sieger;
        }  
        
        
        //diagonal nach rechts unten
        _reihe = reihe;
        _feld = feld;
        z = feld;
        j = reihe;
        zaehler = 0;
        for (int i = reihe, c = feld; i<6 && c<7;i++,c++) {
          if (spielfeld[_reihe][_feld] == spieler)  {
              _reihe++;
              _feld++;
              zaehler++;
          }
        }
        //links oben
        for (int i = feld, c = reihe;i>0 && c>0;i--,c--) {
          if (spielfeld[j-1][z-1] == spieler)  {
              j--;
              z--;
              zaehler++;
          }
        }
        
        if (zaehler>=4){
            sieger = spielfeld[reihe][feld];
            return sieger;
        }
        return sieger;
    
    }
    
     /** ******************************************
     * Eingabe des Spielers wird in das Spielfeld gesetzt
     * @param feld - Feld des Arrays
     * @param spieler - Der Spieler, der am Zug ist
     ************************************************/  
    public int setzeSpielstein(int feld, char spieler) {
        boolean istWahr = false;
        int reihe = 0;
        for (int i = spielfeld.length - 1; i >= 0 && !istWahr; i--) {
            if (spielfeld[i][feld]== ' ') {
                spielfeld[i][feld] = spieler;
                istWahr = true;
                reihe = i;
            }
        }
        zeigeSpielfeld(); 
        return reihe;
    }
    
    public boolean reiheVoll(int eingabe) {
    boolean istVoll = true;
              for (int i = 5; i >=0; i--) {
                if (spielfeld[i][eingabe]== ' ') {
                 istVoll = false;
                }
            }
    return istVoll;
    }
}
```


ist die Spielfeld klasse.. ist das wichtigere..
Mein Prof meinte vorhin, dass es an meinem "Laptop" liegt, dass ich was falsch eingestellt habe. Hab aber nix umgestellt....


----------



## Herbertus (18. Januar 2012)

Naja, wenn es geht, wenn du es in einer Klasse hast und danach nicht mehr, dann hast du i-was falsch aufgemacht oder greifst falsch drauf zu. Daher wäre es ratsam auch alles zu posten, damit es nachvollziehbar wird, was du getan hast.
Du rufst bestimmt Spielfeld von der anderen Klasse auf und da scheint ja i-was nicht zustimmen.

Und nein, nur weil man es aufteilt und dann nicht mehr läuft, ist das kein Problem des Laptops. Das ist und bleibt Unfug.


----------



## IluOMat (18. Januar 2012)

Mach dein Spielfeld mal static, damit du "immer auf dasselbe" Spielfeld zugreifst..


```
private static char[][] spielfeld = new char[6][7];
```


----------



## phreeak (19. Januar 2012)

dürfen keine statischen variablen benutzen bei der Aufgabe. Ist verboten 



```
/** ******************************************
     * Checkt ob die Eingabe zwischen 0 und 6 und ob die Reihe voll ist oder nicht
     * @param eingabe - Eingabe des Spielers
     ************************************************/  
    public boolean istEingabeGueltig (int eingabe) {
        boolean istGueltig = true;
        boolean istVoll = true;
        Spielfeld feld = new Spielfeld();
        ConsolenAusgaben consolenausgaben = new ConsolenAusgaben();
        if (eingabe>6 || eingabe<0) {
                 consolenausgaben.BildschirmAusgaben("FalscheZahl");  
                 istGueltig = false;
                 istVoll = false;
        }
        if (istGueltig) {
            istVoll = feld.reiheVoll(eingabe);
        }
        
        if (istVoll) {
             istGueltig = false;
             consolenausgaben.BildschirmAusgaben("ReiheVoll");
        }
        return istGueltig;
    }
```

hier wird die klasse aufgerufen bzw. reiheVoll()

Hier soll er einfach in die Klasse Spielfeld in die Methode reiheVoll() und diese prüft ob die Senkrechte Reihe voll ist, wo der Spieler sein Spielsetin reinsetzen will... er gibt dann halt true oder false zurück an istEingabeGueltig()


----------



## Herbertus (19. Januar 2012)

Du erstellst dir jedes mal ein neues Spielfeld, dass ist dir klar, oder?
So kann es auch nie voll sein, ....bzw. es ist immer nur 1Zug pro Spielfeld gespeichert.

D.h. du musst das spielfeld-Array statisch machen oder die Klasse nur 1mal erstellen und dann immer wieder benutzen.

also in der gepostet Klasse eine Variable einlegen, ...und darauf immer zugreifen.


```
private Spielfeld sf = null;

public DeineKlasse(){ // von der aufrufenden Klasse der Konstruktor
                                        // ich kenne ja dein Aufbau nicht und das hier ist nur ein Beispiel.
      sf = new Spielfeld();
}
```

So ungefähr. Und dann in der Methode istEingabeGueltig fragst du nach, ob sf.reiheVoll

So benutzt du immer das selbe Spielfeld.^^


----------



## genodeftest (19. Januar 2012)

@phreeak: Wie wäre es mit einem Attribut für diese Klasse, d.h. eine private, Klassenweit sichtbare Variable?


----------



## phreeak (19. Januar 2012)

hmm.. Aber wenn ich jedesmal nen neues Spielfeld mache, wieso läuft das Spiel ganz normal, wenn ich diese Abfrage rausnehme?  in der Klasse Spielfeld ist ebenfalls ne ähnliche Abfrage, um den Spielstein zusetzen, und die funktioniert auch und erkennt ob nen spielstein gesetzt ist oder ob nen leerzeichen drinnen ist, zeigt nach jedem Zug das Spielfeld richtig an und auch den Gewinner...

ehhh... checks grad nicht. Ist mein erstens Semster.. vorher noch nie Java gehabt.


----------



## Herbertus (19. Januar 2012)

> Aber wenn ich jedesmal nen neues Spielfeld mache, wieso läuft das Spiel ganz normal, wenn ich diese Abfrage rausnehme?


Es funktioniert auch, wenn du sie drin lässt. In der Abfrage jedoch erstellst du dir ein neue Klasse Spielfeld und fragst das ab, anstatt das vermutlich die richtige Klasse abzufragen.



> in der Klasse Spielfeld ist ebenfalls ne ähnliche Abfrage, um den Spielstein zusetzen, und die funktioniert auch und erkennt ob nen spielstein gesetzt ist oder ob nen leerzeichen drinnen ist


Die Abfrage funktioniert auch so und die in der Klasse Spielfeld auch, da die Klasse in sich sich ja nicht neu erstellt und das abfragt, sondern sich selbst.


Ich weiß nicht, wie ich es erklären kann, bin in sowas nicht gut.
Aufjedenfall ist es nicht sinnig bei jeder Abfrage eine neue Klasse Spielfeld zuerstellen und die abzufragen. 
Du solltest schon immer die gleiche Klasse Spielfeld abfragen.

Daher ist deine Zeile in der Methode istEingabeGueltig 

```
Spielfeld spielfeld = new Spielfeld();
```
nicht richtig.

Du erstellst dir in der abfragenden Klasse eine Klassenvariable

```
private Spielfeld sf = null;
```

Und dann änderst du die die Zeile in der Methode istEingabeGueltig  zu

```
if(sf == null){
sf = new Spielfeld();
}
```

Und anstatt das du dann nach 
	
	
	



```
feld.reiheVoll
```
 abfragst, fragst du nach 
	
	
	



```
sf.reiheVoll
```
 ab


Damit du immer die selbe Klasse Spielfeld abfragst und dir nicht zwischendurch einfach eine zusätzliche anlegst und darin rumabfragst.

Ggf. musst du dann andere Methoden in der abfragenden Klasse ebenfalls anpassen. (sf dann benutzen!) - kenne ja dein Code nicht.


----------



## phreeak (20. Januar 2012)

hmm muss ich zum schluss machen... muss nun erstmal ne Klasse für den Spieler erstellen mit ner vererbung usw.
Statt nen neuen Thread zumachen, kann ich ne kurze Frage dazu stellen, ob ich sie richtig habe?! Funktionieren tuts, aber ka obs auch wirklich ne vererbung ist mit extends..


----------



## sheel (20. Januar 2012)

phreeak hat gesagt.:


> Statt nen neuen Thread zumachen, kann ich ne kurze Frage dazu stellen


Ja.

Und extends ist ganz echte Vererbung, ja.


----------



## phreeak (21. Januar 2012)

supi,

Ist ja nen Vier Gewinnt Spiel, sollten ne vererbung mit dem Spieler machen. Benutz aber statt Spieler 1 und Spieler 2 immer Spielsteine (x und o) und lass die halt nach jedem Zug wechseln.

Hab nun die Klasse Spieler


```
package viergewinnt_aufgabe2;

public class Spieler {

    char spielstein;
    
public Spieler(char spielstein) {
     this.spielstein = spielstein;
}


}
```

und Klasse SubSpieler


```
package viergewinnt_aufgabe2;

class SupSpieler extends Spieler {
   char spieler1;
   char spieler2;
   
   
   public  SupSpieler(char spielstein) {
        super(spielstein);
        spieler1 = 'x';
        spieler2 = 'o';
    }
   
   public void WechselSpielerstein() {
       if (spielstein == spieler1) {
           spielstein = spieler2;
           
       }
       else {
           spielstein = spieler1;
           
       }
   }
}
```

in der Spielsteuerung übergib ich zuerst den "Beginerstein" mit


```
SupSpieler aspieler = new SupSpieler('x');
```

Der ruft den Konstruktur von SupSpieler (Subklasse) auf, wo er mit 
	
	
	



```
super(spielstein)
```
 den wert an Spielstein in der Klasse Spieler übergibt.

und wechsel den Spieler dann mit


```
aspieler.WechselSpielerstein();
```


Meine Frage nur,  ist das wirklich so richtig?! Muss am Dienstag abgeben und die Typen im Praktika wollen alles 100% Pro-mässig haben, obwohl ich find, fürs 1. Semester es schons etwas schwer ist. Die meisten Programmieren ja erst seit 3 Monaten.


hier mal die Spielsteuerung,


```
/** ******************************************
     * Klasse die nach der Hauptklasse alle weiteren Schritte regelt
     ************************************************/
public class Spielablauf {
     /** ******************************************
     * Hauptprozedure die das Spiel steuert, solang bis ein Sieger feststeht 
     * @param spieler - aktueler Spieler
     * @param spielmodi - 1 für Mehrspieler, 0 für Einzelspieler
     ************************************************/    
    public void starteSpiel(int spielmodi) {
       Spielfeld feld = new Spielfeld();
       SpielerEingabe eingeben = new SpielerEingabe();
       ConsolenAusgaben ausgeben = new ConsolenAusgaben();
       Computer v_spieler = new Computer();
       SupSpieler aspieler = new SupSpieler('x');
       int reihe = 0;
       int eingabe;
       char sieger = ' ';
 
       feld.setzeSpielfeld();  // erstellt das Spielfeld 
        do {
            
            if ((spielmodi == 1) && (aspieler.spielstein == 'o')) {
           eingabe = v_spieler.PcEingabe();
            }
            else {
                System.out.println("Spielerstein "+aspieler.spielstein+" ist am Zug");
            // holt die Eingabe in welcher Reihe der Spieler/Computer sein Sielstein setzt
            eingabe = eingeben.holeEingabe();
            }
            // setzt den Spielstein in ein freies Feld in der reihe und gibt die Reihe zurück
            reihe = feld.setzeSpielstein(eingabe, aspieler.spielstein);
            // übergibt x,y kooridnaten innerhalb des Arrays und prüft ob 4 Spielsteine in einer Reihe existieren.
            sieger = feld.hatGewonnen(eingabe, reihe, aspieler.spielstein);
            aspieler.WechselSpielerstein();
         
        }
        while (sieger == ' ');
        ausgeben.zeigeGewinner(sieger);
    }
}
```


----------



## phreeak (23. Januar 2012)

Hab nun in der Klasse SpielerEingabe


```
class SpielerEingabe {
   
   private Spielfeld sf = null;
   ...
```

gemacht und in der Methode IstEingabeGueltig dieses


```
if(sf == null){
        sf = new Spielfeld();
        }
```

und ruf die Methode in der anderen Klasse, dann mit


```
sf.reiheVoll(eingabe)
```

auf, aber dennoch gibt mir die Methode immer zurück, dass eine Reihe voll ist.


----------

