OOP- Eine Klasse in mehrere Klassen aufteilen

darkkeks

Mitglied
Hey, ich hab folgendes Programm siehe Bild. Ich versuche es dauernd in mehrere Unterklassen einzuteilen, nur will das Programm nicht funktionieren. Ich wollte das Programm in eine Main-Klasse, Feld-Klasse, Spieler Klasse, Logik Klasse und Computer gegner einteilen. Habe es mit Vererbung probiert, will aber nicht funktionieren 🙁 Sind die Vorgeschlagen Klasse so wie ich die einteilen wollte eventuell nicht so gut gewählt? Ich habe hier jetzt nur die Zwei Klassen gepostet sodass das Spiel funktioniert mit einer Main und eine Spiellogik klasse.

Main-Klasse
Java:
public class Main {

    public static void main(String[] args) {
         System.out.println("Koordinaten : \n\n00 |01 |02  \n-----------\n10 |11 |12 \n-----------\n20 |21 |22  \n-----------\n");
            Scanner sc = new Scanner(System.in);
            Spiellogik spiel = new Spiellogik();

            for (int i = 0;i<3;i++) //Feld mit Leerzeichen füllen
              {
                for (int j = 0;j<3;j++)
                spiel.feldflaeche [i][j]="   ";
              }// for() ende
            System.out.println("Drücke 1 für Spiel Spieler gegen Computer \nDrücke 2 für 1vs1");
              int n=sc.nextInt();
              switch(n)
              {
              case 1:
              {
                while(spiel.count<=9)
              { 
              if(spiel.count%2!=0) 
                {
                spiel.player= 'X';
                 
                
                System.out.println("\nGeben Sie die x und y koordinaten ein ");
                System.out.println("Spieler "+spiel.player+" ist am Zug\n");
                spiel.setzen();
                }
              else spiel.botO();
              }//while()ende
              }//case 1 zuEnde

          case 2: 
             {
              while(spiel.count<=9)
              { 
              if(spiel.count%2!=0) spiel.player = 'X';
              else spiel.player = 'O';
                System.out.println("\nGeben Sie die x und y koordinaten ein ");
                System.out.println("Spieler "+spiel.player+" ist am Zug\n");
                spiel.setzen();
              }// while() ende
              }// case 2 ende
              }//switch ende
              if (spiel.count>9)System.out.println("\n Spiel ist vorbei! \n");
            }// main() ende
            
         

    }


Spiellogik Klasse

Java:
import java.util.Scanner;

public class Spiellogik {
    public String [][] feldflaeche;
    public static int count = 1;
    public static char player;
    
    public Spiellogik() {
        feldflaeche = new String [3][3];
    }


    public  void print() { // Feld drucken
        int i = 0;
        do {
            int j = 0;
            System.out.print(feldflaeche[i][j]+"|");
            System.out.print(feldflaeche[i][j +1]+ "|");
            System.out.println(feldflaeche[i][j+2]);
            System.out.println("-----------");;
            i++;
        }while(i<3);
    }
    /**
     * Methode Random Computergegner setzten 
     */
     public  void botO() //
        {
          player = 'O'; System.out.println("\n__________________________________________\n");
          int arr[]={00,01,02,10,11,12,20,21,22};
          int r = (int)(Math.random()*8);
          int xy=arr[r],x,y; 
          x=xy/10;y=xy%10;
          if(arr[r]!=-1)
          {
          if (feldflaeche[x][y]=="   ")
         {feldflaeche[x][y]=" O ";arr[r]=-1;count++;print();isWin();}
          }
        }    
     public void setzen() { //Spieler setzen Methode
         Scanner scan = new Scanner(System.in);
         int xy = scan.nextInt(),x,y;
            y=xy%10;xy=xy/10;x=xy%10; 
            if (feldflaeche[x][y]=="   ") 
            {feldflaeche[x][y]=" "+player+" ";count++;print();isWin();} //
            else System.out.println("\n Fläche ist belegt\n");
            }// if end
     
     public void isWin() //Logik gewinner ermitteln 
     { 
       switch(player)
       {
       case 'X':
       {
       String s = " X  X  X ";
       if((feldflaeche[0][0]+feldflaeche[0][1]+feldflaeche[0][2]).equals(s))
       {System.out.println("X hat Gewonnen!"); count=10;}
       if((feldflaeche[1][0]+feldflaeche[1][1]+feldflaeche[1][2]).equals(s))
       {System.out.println("X hat Gewonnen!"); count=10;}
       if((feldflaeche[2][0]+feldflaeche[2][1]+feldflaeche[2][2]).equals(s))
       {System.out.println("X hat Gewonnen!"); count=10;}
       if((feldflaeche[0][0]+feldflaeche[1][0]+feldflaeche[2][0]).equals(s))
       {System.out.println("X hat Gewonnen!"); count=10;}
       if((feldflaeche[0][1]+feldflaeche[1][1]+feldflaeche[2][1]).equals(s))
       {System.out.println("X hat Gewonnen!"); count=10;}
       if((feldflaeche[0][2]+feldflaeche[1][2]+feldflaeche[2][2]).equals(s))
       {System.out.println("X hat Gewonnen!"); count=10;}
       if((feldflaeche[0][0]+feldflaeche[1][1]+feldflaeche[2][2]).equals(s))
       {System.out.println("X hat Gewonnen! "); count=10;}
       if((feldflaeche[0][2]+feldflaeche[1][1]+feldflaeche[2][0]).equals(s))
       {System.out.println("X hat Gewonnen! "); count=10;}
       }// case 'X' ende
       break;

     case 'O':
       {
         String s =" O  O  O ";
       if((feldflaeche[0][0]+feldflaeche[0][1]+feldflaeche[0][2]).equals(s))
       {System.out.println("O hat Gewonnen!"); count=10;}
       if((feldflaeche[1][0]+feldflaeche[1][1]+feldflaeche[1][2]).equals(s))
       {System.out.println("O hat Gewonnen!"); count=10;}
       if((feldflaeche[2][0]+feldflaeche[2][1]+feldflaeche[2][2]).equals(s))
       {System.out.println("O hat Gewonnen!"); count=10;}
       if((feldflaeche[0][0]+feldflaeche[1][0]+feldflaeche[2][0]).equals(s))
       {System.out.println("O hat Gewonnen!"); count=10;}
       if((feldflaeche[0][1]+feldflaeche[1][1]+feldflaeche[2][1]).equals(s))
       {System.out.println("O hat Gewonnen!"); count=10;}
       if((feldflaeche[0][2]+feldflaeche[1][2]+feldflaeche[2][2]).equals(s))
       {System.out.println("O hat Gewonnen!"); count=10;}
       if((feldflaeche[0][0]+feldflaeche[1][1]+feldflaeche[2][2]).equals(s))
       {System.out.println("O hat Gewonnen!"); count=10;}
       if((feldflaeche[0][2]+feldflaeche[1][1]+feldflaeche[2][0]).equals(s))
       {System.out.println("O hat Gewonnen!"); count=10;}
       }// case 'O' ende
       }// switch() ende
     }// isWin() ende
    
}
 
Zuletzt bearbeitet von einem Moderator:
Ich versuche es dauernd in mehrere Unterklassen einzuteilen, nur will das Programm nicht funktionieren.
Als erstes solltest Du Deine Klassen an Fachlichkeiten ausrichten und nicht an technischen Gegebenheiten. Dazu gehört dann auch, Darstellung und Logik zu trennen. Bei TicTacToe könnte man z. B. einen Datentyp für die Spieler, das Spielfeld und das Spiel erwarten.

Unabhängig davon: Objekte vergleicht man mit equals und nicht mit ==.

Noch unabhängiger davon: was funktioniert denn nicht?
 
Also generell sollte eine Unterteilung "visuell" erfolgen. Also was hast Du für Elemente?
Und wenn man etwas nach Betrachtung zerlegt, dann finden sich dubiose "Logik" oder Controller in der Regel nicht. Was für Gegenstände hast Du denn so? Du hast Spieler, Spielfeld, ....

Dann gehört die Logik zu den Elementen. Wenn Du also ein Spielfeld hast, dann gehört zum Spielfeld auch. wie dieser initialisiert wird. Also von außen kann nur sowas die spielfeld.init() aufgerufen werden. Aber nie sowas wie eine verschachtelte Schleife mit spielfeld.fels[j]=" ";
Nur das Spielfeld weiß, wie die Datenstrukturen intern aufgebaut sind und wie diese zu initialisieren sind.

Stell Dir das evtl. so vor, dass die Gegenstände durch Menschen dargestellt werden. Dan bin ich das Spielfeld. Ich habe einen Block mit Notizen: Was ich mir wie aufschreibe, geht die anderen nichts an. Und dann gibt es klare Dinge, die man mich fragen oder die man mir sagen kann. So kann der "Würfel" gefragt werden nach einem neuen Würfelergebnis. Was der "Würfel" dann macht, ist ihm überlassen, aber es kommt ein Würfelergebnis zurück.

Beim Spielfeld kann dann z.B. gesagt werden: Spieler A rückt 3 Felder vor. Dann weiss das Spielfeld, wie und was da zu tun ist.

So solltest Du Dir überlegen, was Du da an Elementen hast und diese darstellen. Da geht es auch noch nicht um Vererbung oder so. Das kommt später. Dann kann es halt eine Klasse Spieler geben, die die Grundregeln hat und davon abgeleitet sind dann MenschlicherSpieler und ComputerSpieler oder so... aber erst einmal musst Du alles identifizieren. Was für Elemente gibt es? Mit Welchen anderen Elementen interagieren sie? Was müssen sie für Eigenschaften haben? Was für Veralten haben sie?
 
Ok. Also das Programm Tic Tac Toe so wie das hier gepostet wurde funktioniert, nur wie gesagt möchte ich es strukturell besser und übersichtlicher gestalten also objektorientiert. Ich möchte es ganz simpel in der Konsole ausgeben können nutze eclipse. Ich möchte es noch nicht grafisch darstellen.
Ich habe kurz den Code in mehren Klassen eingeteilt:
Einmal in einer Feld Klasse, die das Feld erzeugt und initialisiert. Datentyp wäre ein String array
Dann eine Spieler Klasse mit den Datentyp Char mit der Methode, um X oder O zu setzten.
Dann eine Computergegner auch vom selben Datentyp wie Spieler ist und eine Methode hat die Random die X's und O's in das Feld setzt. Dann eine Logik also die Methode um zu erkennen ob man drei Zeichen in einer Reihe, Spalte oder Diagonal vorhanden ist und eine Main Klasse wo das Spiel gestartet wird und man auswählen kann ob man eine 1 VS Computergegner Spiel spielen.

Main Klasse

import java.util.Scanner;

public class TicTakToe_Main {
public static void main(String[] args) {
System.out.println("Koordinaten : \n\n00 |01 |02 \n-----------\n10 |11 |12 \n-----------\n20 |21 |22 \n-----------\n");
Scanner sc = new Scanner(System.in);
Spiellogik spiel = new Spiellogik(); //Field Class
Spieler player1 = new Spieler('X'); // New Class of Player


System.out.println("Drücke 1 für Spiel Spieler gegen Computer \nDrücke 2 für 1vs1");
int n=sc.nextInt();
switch(n)
{
case 1:
{
while(spiel.count<=9)
{
if(spiel.count%2!=0)
{
spiel.player= 'X';


System.out.println("\nGeben Sie die x und y koordinaten ein ");
System.out.println("Spieler "+spiel.player+" ist am Zug\n");
player1.setzen();
}
else spiel.botO();
}//while()ende
}//case 1 zuEnde

case 2:
{
while(spiel.count<=9)
{
if(spiel.count%2!=0) spiel.player = 'X';
else spiel.player = 'O';
System.out.println("\nGeben Sie die x und y koordinaten ein ");
System.out.println("Spieler "+spiel.player+" ist am Zug\n");
player1.setzen();
}// while() ende
}// case 2 ende
}//switch ende
if (spiel.count>9)System.out.println("\n Spiel ist vorbei! \n");
else System.out.println("Unentschieden");
}// main() ende


Feld Klasse

import java.util.Scanner;

public class Feld { //Field class
public String [][] feldflaeche;
public int count = 1;


public Feld() {
feldflaeche = new String [3][3];
}


public void print() { //print field
int i = 0;
do {
int j = 0;
System.out.print(feldflaeche[j]+"|");
System.out.print(feldflaeche[j +1]+ "|");
System.out.println(feldflaeche[j+2]);
System.out.println("-----------");;
i++;
}while(i<3);
}
public void init(){
for (int i = 0;i<3;i++)
{
for (int j = 0;j<3;j++)
spiel.feldflaeche [j]=" ";
spiel.print();
}// for() ende

Klasse Logik

public class Logik{

}
public void isWin() //Gewinner ermitteln
{
switch(player)
{
case 'X':
{
String s = " X X X ";
if((feldflaeche[0][0]+feldflaeche[0][1]+feldflaeche[0][2]).equals(s))
{System.out.println("X hat Gewonnen!"); count=10;}
if((feldflaeche[1][0]+feldflaeche[1][1]+feldflaeche[1][2]).equals(s))
{System.out.println("X hat Gewonnen!"); count=10;}
if((feldflaeche[2][0]+feldflaeche[2][1]+feldflaeche[2][2]).equals(s))
{System.out.println("X hat Gewonnen!"); count=10;}
if((feldflaeche[0][0]+feldflaeche[1][0]+feldflaeche[2][0]).equals(s))
{System.out.println("X hat Gewonnen!"); count=10;}
if((feldflaeche[0][1]+feldflaeche[1][1]+feldflaeche[2][1]).equals(s))
{System.out.println("X hat Gewonnen!"); count=10;}
if((feldflaeche[0][2]+feldflaeche[1][2]+feldflaeche[2][2]).equals(s))
{System.out.println("X hat Gewonnen!"); count=10;}
if((feldflaeche[0][0]+feldflaeche[1][1]+feldflaeche[2][2]).equals(s))
{System.out.println("X hat Gewonnen! "); count=10;}
if((feldflaeche[0][2]+feldflaeche[1][1]+feldflaeche[2][0]).equals(s))
{System.out.println("X hat Gewonnen! "); count=10;}
}// case 'X' ende
break;

case 'O':
{
String s =" O O O ";
if((feldflaeche[0][0]+feldflaeche[0][1]+feldflaeche[0][2]).equals(s))
{System.out.println("O hat Gewonnen!"); count=10;}
if((feldflaeche[1][0]+feldflaeche[1][1]+feldflaeche[1][2]).equals(s))
{System.out.println("O hat Gewonnen!"); count=10;}
if((feldflaeche[2][0]+feldflaeche[2][1]+feldflaeche[2][2]).equals(s))
{System.out.println("O hat Gewonnen!"); count=10;}
if((feldflaeche[0][0]+feldflaeche[1][0]+feldflaeche[2][0]).equals(s))
{System.out.println("O hat Gewonnen!"); count=10;}
if((feldflaeche[0][1]+feldflaeche[1][1]+feldflaeche[2][1]).equals(s))
{System.out.println("O hat Gewonnen!"); count=10;}
if((feldflaeche[0][2]+feldflaeche[1][2]+feldflaeche[2][2]).equals(s))
{System.out.println("O hat Gewonnen!"); count=10;}
if((feldflaeche[0][0]+feldflaeche[1][1]+feldflaeche[2][2]).equals(s))
{System.out.println("O hat Gewonnen!"); count=10;}
if((feldflaeche[0][2]+feldflaeche[1][1]+feldflaeche[2][0]).equals(s))
{System.out.println("O hat Gewonnen!"); count=10;}
}// case 'O' ende
}// switch() ende
}// isWin() ende


}

Spieler Klasse

import java.util.Scanner;

public class Spieler {
private char player;

public Spieler(char spieler) {
this.player = spieler;
}

public char getPlayer() {
return player;
}

public void setPlayer(char player) {
this.player = player;
}
public void setzen() {
Scanner scan = new Scanner(System.in);
int xy = scan.nextInt(),x,y;
y=xy%10;xy=xy/10;x=xy%10;
if (feldflaeche[x][y]==" ")
{feldflaeche[x][y]=" "+player+" ";count++;print();isWin();} //
else System.out.println("\n Fläche ist belegt\n");
}


}

Computergegner Klasse

public class Computergegner {

public Computergegner(char spieler) {
super(spieler);

}
public void botO() {//setting method of Bot Player

System.out.println("\n__________________________________________\n");
int arr[]={00,01,02,10,11,12,20,21,22};
int r = (int)(Math.random()*8);
int xy=arr[r],x,y;
x=xy/10;y=xy%10;
if(arr[r]!=-1)
{
if (feldflaeche[x][y]==" ")
{feldflaeche[x][y]=" O ";arr[r]=-1;count++;print();isWin();}
}
}
}

 
Problem ist ich habe ja in einigen Klassen wie bspw die Spieler Klasse beim setzten einige funktionen der Feld Klasse. Wie bringe ich diese Elemente zusammen bzw. ist das so richtig? Ist mein Ansatz so richtig? Ich glaube nicht 😀 oder?
 
Es geht schon in die richtige Richtung, ist aber noch alles zu stark miteinander vermischt. Den Scanner solte es nur in main geben. Die Objekte bringst Du zusammen, indem Du sie miteinander bekannt machst. Das kann im Konstruktor passieren oder über Setter. Über Schnittstellen (Java interface) lassen sich Klassen entkoppeln.
 
Es geht schon in die richtige Richtung, ist aber noch alles zu stark miteinander vermischt. Den Scanner solte es nur in main geben. Die Objekte bringst Du zusammen, indem Du sie miteinander bekannt machst. Das kann im Kon
Es geht schon in die richtige Richtung, ist aber noch alles zu stark miteinander vermischt. Den Scanner solte es nur in main geben. Die Objekte bringst Du zusammen, indem Du sie miteinander bekannt machst. Das kann im Konstruktor passieren oder über Setter. Über Schnittstellen (Java interface) lassen sich Klassen entkoppeln.
Wie meinst du das mit Setter? Und wie könnte man ein Interface einbauen bzw. Was bedeutet das wenn ich ein Interface einbaue. Das mit dem interfaces habe ich irgendwie nie verstanden
 
Ein Setter ist eine Methode, deren Name üblicherweise mit set beginnt, zum Einstellen eines Attributs (Dein setPlayer ist ein Setter). Du kannst andere Objekte entweder bei der Objekterzeugung als Argument des Konstruktors mitgeben und/oder über Setter einstellen.

Ein Interface spezifiziert einfach die Methoden, die ein Objekt, das diese Schnittstelle anbietet, implementieren muss.
 

Zurück
Oben