# Euer Feedback zu meinem Code ist gefragt



## Betty (23. Okt 2015)

Guten Abend ihr Lieben,

dies ist mein erster Post in diesem Forum. Bin die Betty und ganz frisch dabei, was das Programmieren angeht. Ich dachte, ich programmiere aus Spaß das Spiel TicTacToe nach, um ein erstes Gefühl für die sprache zu bekommen... soweit scheint es auch sehr gut zu funktionieren...
der bisher hier eingefügte Code ist noch nicht ganz vollständig...
zum einen fehlt mir noch eine Art KI, damit man gegebenenfalls auch alleine gegen den Computer spielen kann... zum anderen muss ich verhindern, dass die schon belegten spielfelder beim nächsten durchlauf überschrieben werden können, aber das mach ich später...

ich bin erstmal total neugierig darauf, was ihr von meinem code haltet bzw. würde mich sehr über kritik (positiv sowie negativ) freuen, um zu wissen, wie ich mit dem bisher getippten darstehe...

Ich kompilier alles über den editor /cmd und lass das auch direkt da ausführen... also keine entwicklungsumgebung momentan...

und hier der code... hab zwei java klassen... eine main, in der dann die klasse funktionen aufgerufen wird, in der eben die restlichen funktionen sich befinden


```
//Main Klasse
import libs.*;
import java.io.*;

public class Main{

    public static void main(String args[]) throws IOException{

        Funktionen f = new Funktionen();
      
        f.starteProgramm();
    }
}
```



```
//TicTacToe
//Klasse Funktionen
//hier sind alle Methoden hinterlegt
package libs;

import java.io.*;

public class Funktionen{

    static boolean kontrolle = false;

    public void starteProgramm() throws IOException{

        System.out.println("\nGuten Tag und Willkommen zum Spiel.\n" +
            "Moechtest du eine Runde TicTacToe spielen? \n");

        while(kontrolle == false){

            System.out.print("[j] - fuer Ja und [n] - fuer Nein ! \n\n" );

            System.out.print("\t-> ");
            BufferedReader inputEingabe = new BufferedReader (new InputStreamReader(System.in));
            String ein = inputEingabe.readLine();
            char eingabe = ein.charAt(0);

            System.out.println("\n");

            switch(eingabe){
                case 'j':
                    mitspielerabfrage();
                    kontrolle = true;
                    break;
                case 'n':
                    System.out.println("Bis dahin, werter Benutzer! ");
                    System.exit(0);
                    break;

                default:
                    System.out.println("### Ungueltige Benutzereingabe! Bitte gebe was gueltiges ein ! ###");
                    break;      
        }
    }
}

//Mitspielerabfrage
    void mitspielerabfrage() throws IOException{

        System.out.println("Moechtest du alleine oder gegen einen Mitspieler spielen?\n");

        while(kontrolle == false){
            System.out.println("[a] - fuer Alleine und [m] - fuer Mitspieler!\n");
            System.out.print("\t-> ");
            BufferedReader inputMit = new BufferedReader (new InputStreamReader(System.in));
            String mit = inputMit.readLine();
            char mitspieler = mit.charAt(0);

            System.out.print("\n");

            switch(mitspieler){
                case 'a':
                ladeKISpiel();
                kontrolle = true;
                //System.exit(0);
                break;

                case 'm':
                ladePvPSpiel();
                kontrolle = true;
                break;

                default:
                System.out.println("\n###\tFalsche Eingabe !\t###\n");
                break;
        }
    }
}

//Funktion, die Spiel mit KI laedt
    void ladeKISpiel()throws IOException{
        System.out.println("\n###\tKannst du den Computer besiegen ? \t###\n\n");

        System.exit(0);
    }

//Funktion, die ein neues PvP - Spiel laedt
    void ladePvPSpiel()throws IOException{

    System.out.println("\n###\tLasset die Spiele beginnen ! \t###\n\n");

//benoetigter Kleinkram
    String[][] spielwelt = new String [3][3];
    String str = "|\t";
    String leer = "_";
    String spieler1 = "X";
    String spieler2 = "O";
    boolean laeuft = false;
    boolean feldwert = true;
    boolean benutzer= false;
    int eingabe1a = 0;
    int eingabe1b = 0;
    int eingabe2a = 0;
    int eingabe2b = 0;
    int eingabe1 = 0;
    int eingabe2 = 0;
    int i = 0;
    int j = 0;
    int m = 0;
    int durchlauf = 0;

//Ausgabe Feld
    for (i=0; i<3; i++){  
        for(j=0; j<3; j++){
            m++;
                Integer meinInteger = new Integer(m);    //Wrapper Klasse
                String ziffer = meinInteger.toString();
                spielwelt[i][j] = ziffer;
                str += spielwelt[i][j] + "\t";
            }

        System.out.println("\n" + str + "|");
        System.out.println("\n");
        str = "|\t";
    }

    System.out.println("Waehle bitte eine Ziffer um dein Zeichen zu setzen !\n");

//leere Spielfelder
    for (i=0; i<3; i++){
        for(j=0; j<3; j++){
            spielwelt[i][j] = leer;
        }
    }

//Das Herzstueck
    for(;;){

    while (laeuft == false){

        int n = 0;
        benutzer = false;

//Benutzereingabe von Spieler 1
while(benutzer == false){
    try{
        System.out.print("\nSpieler 1, welches Feld ? \n -> ");
        BufferedReader input1a = new BufferedReader (new InputStreamReader(System.in));
        String ein1 = input1a.readLine();
        eingabe1 = Integer.parseInt(ein1);
        benutzer = true;
    }catch(NumberFormatException nfe){
        System.out.println("\n### Sry man, falsches Zeichen ! ###\n");
    }
}

//Koordinaten von Spieler 1
        switch (eingabe1){
            case 1:
            eingabe1a = 0;
            eingabe1b = 0;
            break;

            case 2:
            eingabe1a = 0;
            eingabe1b = 1;
            break;

            case 3:
            eingabe1a = 0;
            eingabe1b = 2;
            break;

            case 4:
            eingabe1a = 1;
            eingabe1b = 0;
            break;

            case 5:
            eingabe1a = 1;
            eingabe1b = 1;
            break;

            case 6:
            eingabe1a = 1;
            eingabe1b = 2;
            break;

            case 7:
            eingabe1a = 2;
            eingabe1b = 0;
            break;

            case 8:
            eingabe1a = 2;
            eingabe1b = 1;
            break;

            case 9:
            eingabe1a = 2;
            eingabe1b = 2;
            break;

            default:
            System.out.println("\n### Du hast dich wohl vertippt man ! ###");
            break;
        }

//ueberprueft, ob die Felder schon belegt sind und erhoeht dementsprechend den zaehler
        for (i=0; i<3; i++){
            for(j=0; j<3; j++){
                feldwert = spielwelt[i][j].equals(leer);
                if(feldwert == false){
                    n++;
                }
            }
        }

        benutzer = false;

//Benutzereingabe von Spieler 2
if (n < 8){
        while (benutzer == false){
    try{
        System.out.print("\nUnd was nimmst du, Spieler 2 ? \n -> ");
        BufferedReader input2a = new BufferedReader (new InputStreamReader(System.in));
        String ein2 = input2a.readLine();
        eingabe2 = Integer.parseInt(ein2);
        benutzer = true;
    }catch(NumberFormatException e){
            System.out.println("\n### Sry man, falsches Zeichen ! ###\n");
        }
    }
}
        System.out.println();

//Koordinaten von Spieler 2 werden festgelegt
        switch (eingabe2){
            case 1:
            eingabe2a = 0;
            eingabe2b = 0;
            break;

            case 2:
            eingabe2a = 0;
            eingabe2b = 1;
            break;

            case 3:
            eingabe2a = 0;
            eingabe2b = 2;
            break;

            case 4:
            eingabe2a = 1;
            eingabe2b = 0;
            break;

            case 5:
            eingabe2a = 1;
            eingabe2b = 1;
            break;

            case 6:
            eingabe2a = 1;
            eingabe2b = 2;
            break;

            case 7:
            eingabe2a = 2;
            eingabe2b = 0;
            break;

            case 8:
            eingabe2a = 2;
            eingabe2b = 1;
            break;

            case 9:
            eingabe2a = 2;
            eingabe2b = 2;
            break;

            default:
            System.out.println("Du hast dich wohl vertippt man! ");
            break;
        }

//Felder werden belegt
        for (i=0; i<3; i++){  

            for(j=0; j<3; j++){

                spielwelt[eingabe1a][eingabe1b] = spieler1;
                spielwelt[eingabe2a][eingabe2b] = spieler2;

                str += spielwelt[i][j] + "\t";

                }

            System.out.println("\n" + str + "|");
            System.out.println("\n");
            str = "|\t";

            }

//ueberpruefe, ob gewonnen wurde - zuerst fuer spieler 1 und danach fuer spieler 2
        if (spielwelt[0][0] == spieler1 && spielwelt[0][1] == spieler1 && spielwelt[0][2] == spieler1){
            System.out.println("### Gewonnen hat Spieler 1 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[0][0] == spieler2 && spielwelt[0][1] == spieler2 && spielwelt[0][2] == spieler2){
            System.out.println("### Gewonnen hat Spieler 2 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[1][0] == spieler1 && spielwelt[1][1] == spieler1 && spielwelt[1][2] == spieler1){
            System.out.println("### Gewonnen hat Spieler 1 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[1][0] == spieler2 && spielwelt[1][1] == spieler2 && spielwelt[1][2] == spieler2){
            System.out.println("### Gewonnen hat Spieler 2 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[2][0] == spieler1 && spielwelt[2][1] == spieler1 && spielwelt[2][2] == spieler1){
            System.out.println("### Gewonnen hat Spieler 1 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[2][0] == spieler2 && spielwelt[2][1] == spieler2 && spielwelt[2][2] == spieler2){
            System.out.println("### Gewonnen hat Spieler 2 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[0][0] == spieler1 && spielwelt[1][0] == spieler1 && spielwelt[2][0] == spieler1){
            System.out.println("### Gewonnen hat Spieler 1 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[0][1] == spieler2 && spielwelt[1][1] == spieler2 && spielwelt[2][1] == spieler2){
            System.out.println("### Gewonnen hat Spieler 2 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[0][2] == spieler1 && spielwelt[1][2] == spieler1 && spielwelt[2][2] == spieler1){
            System.out.println("### Gewonnen hat Spieler 1 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[0][0] == spieler2 && spielwelt[1][0] == spieler2 && spielwelt[2][0] == spieler2){
            System.out.println("### Gewonnen hat Spieler 2 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[0][1] == spieler1 && spielwelt[1][1] == spieler1 && spielwelt[2][1] == spieler1){
            System.out.println("### Gewonnen hat Spieler 1 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[0][2] == spieler2 && spielwelt[1][2] == spieler2 && spielwelt[2][2] == spieler2){
            System.out.println("### Gewonnen hat Spieler 2 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[0][0] == spieler1 && spielwelt[1][1] == spieler1 && spielwelt[2][2] == spieler1){
            System.out.println("### Gewonnen hat Spieler 1 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }
        else if (spielwelt[0][0] == spieler2 && spielwelt[1][1] == spieler2 && spielwelt[2][2] == spieler2){
            System.out.println("### Gewonnen hat Spieler 2 ! ###\n\n");
                nochmalSpielen();
                System.exit(0);
        }

//falls alle Felder voll sind
            if(n == 8){
                System.out.println("\n###\tSorry man, alle Felder voll!\t###\n\n");
                nochmalSpielen();
                System.exit(0);

                }
            }
        }
    }

//Funktion, die erneutes Spielen abfragt  
    void nochmalSpielen()throws IOException{

        System.out.println("Was jetzt? \n");

        while(kontrolle == false){

        System.out.println("[n] - fuer neues Spiel und [b] - fuer Beenden!\n");
        System.out.print("\t -> ");
        BufferedReader inputWahl = new BufferedReader (new InputStreamReader(System.in));
        String ein2 = inputWahl.readLine();  
        char eingabe2 = ein2.charAt(0);

        System.out.println("\n");

        switch(eingabe2){
            case 'n':
            mitspielerabfrage();
            kontrolle = true;
            break;

            case 'b':
            System.out.println("\t### Au revoir! ###");
            System.exit(0);
            break;

            default:
            System.out.println("\n###\tVllt vertippt?\t###\n");
            break;
        }
    }
}

}//Klammer der Klasse Funktionen: alle Funktionen müssen hier vor angelegt werden!
```


----------



## Joose (23. Okt 2015)

Für den Anfang in Ordnung natürlich könnte man an manchen Stellen etwas optimieren 

Beispiel:

```
boolean kontrolle = false;
// diese bedingunen ....
if(kontrolle == false) 
if (kontrolle == true) 
// .... kann man zu folgenden vereinfachen
if(!kontrolle)
if(kontrolle)
```
In den if-Bedingungen musst du einen boolschen Ausdruck angeben, aber die Abfragen auf "==false" bzw. "==true" sind dabei nicht notwendig. Da die Variable "kontrolle" selbst schon ein boolscher Ausdruck ist.
Das "!" vor dem boolean Ausdruck negiert diesen. Für Anfänger ist es mit == false leichter zu lesen, aber je mehr man sich mit Java beschäftigt umso mehr kommt einem die vereinfachte Schreibweise unter.

Du hast ein sehr sehr lange if/else Konstrukt um zu prüfen ob Spieler 1 oder Spieler 2 gewonnen hat.
Zuerst: in jedem Block schreibst du den Gewinnern hin und rufst die Methode "nochmalSpielen" auf. Diesen Teil könnte man in eine eigene Methode auslagern. Willst du nämlich die Siegerausgabe anpassen musst du das ganze 14x anpassen!


```
void spielerHatGewonnen(int spieler) {
     System.out.println("### Gewonnen hat Spieler " + spieler + " ! ###\n\n");
     nochmalSpielen();
   }
```

Auch den Codeteil wo du die Benutzereingabe von Spieler 1 und Spieler 2 verarbeitest ist doppelt, lagere diesen teil ebenfalls in eigene Methoden aus.
(Achtung vor dem Aufruf prüfen ob die Eingabe korrekt sein kann. > 0 und <=9

```
int[] getKoordinaten(int feldWahl) {
     int[] koordinaten = new int[2];
     switch (feldWahl){
       case 1:
         koordinaten[0] = 0;
         koordinaten[1] = 0;
         break;
       case 2:
         koordinaten[0] = 0;
         koordinaten[1] = 1;
         break;
       case 3:
         koordinaten[0] = 0;
         koordinaten[1] = 2;
         break;
       case 4:
         koordinaten[0] = 1;
         koordinaten[1] = 0;
         break;
       case 5:
         koordinaten[0] = 1;
         koordinaten[1] = 1;
         break;
       case 6:
         koordinaten[0] = 1;
         koordinaten[1] = 2;
         break;
       case 7:
         koordinaten[0] = 2;
         koordinaten[1] = 0;
         break;
       case 8:
         koordinaten[0] = 2;
         koordinaten[1] = 1;
         break;
       case 9:
         koordinaten[0] = 2;
         koordinaten[1] = 2;
         break;
     }
     return koordinaten;
   }
```

Sehr oft werden BufferedReader erstellt um eine Zeile einzulesen, entweder erstelle am Anfang max 1. (du liest ja alles von der gleichen Konsole) oder lagere diesen Code ebenfalls in eine eigene Methode aus.


```
String readLine() {
     BufferedReader reader = new BufferedReader (new InputStreamReader(System.in));
     return reader.readLine();  
   }
```


----------



## Dompteur (23. Okt 2015)

Ich nehme an, dass du das Programm schon ausprobiert hast und dass es funktioniert.
Daher erst einmal Gratulation.

Ich bin mir nicht sicher, ob du bewußt die Stringvergleiche mit "==" machst. Normalerweise werden Strings mit equals verglichen. In deinem Fall ist "==" richtig, da es sich um dieselbe Instanz handelt. Allerdings kann das nach hinten losgehen, wenn man da nicht sehr genau aufpasst.

Deine Kontrollstruktur ist problematisch. Du rufst deine Methoden so auf, dass du eine Rekursion erhälst. Du hast anscheinend vorgehabt das anders zu lösen, aber nicht durchgezogen. Zumindest entnehme ich das der lokalen Variable "laeuft", die immer false bleibt und in der while-Schleife verwendet wird.
exit(0) sollte in deinem Programm eigentlich gar nicht nötig sein.

Dann ist es auffällig, dass die Methode "ladePvPSpiel" recht lang ist.
Da solltest du ansetzen. Einerseits solltest du nach doppelten Code suchen und diesen in eigene Methoden herauslösen. 2 Beispiele wurden ja schon genannt.
Andererseits sollen Methode auch zur Strukturierung verwendet werden. Dabei kann ein abgeschlossener Code-Block als Methode herausgezogen werden.
In der erwähnten Methode hast du verschiedene Blöcke, die alle mit einem Kommentar beginnen.
Aus dem Inhalt des Kommentars lässt sich meist ein guter Methodenname herleiten.


Dann machst du vieles explizit, wo du auch auch einfache Mathematik einsetzen kannst.
Bsp: Die Umwandlung der Zellennummer in Zeilen/Spalten deines Arrays.


```
private int getZeilenNummer (int feldWahl) {
      return ( feldWahl-1) / 3;
   }
private int getSpaltenNummer (int feldWahl) {
      return ( feldWahl-1) % 3;
   }
```
 
Ein anderes Beispiel für explizites Aufzählen ist die Überprüfung, ob ein Spieler gewonne hat.
Statt beispielsweise für jede Zeile einen Block zu kopieren, kannst du auch eine for-Schleife verwenden.


----------

