Uniaufgabe : TicTacToe

HuMaHi

Mitglied
Hallo

Hoffentlich ist das hier das richtige Forum, ist ja eigentlich eine Art Hausaufgabe, aber geht ja auch um ein Spiel

Wir haben von der Uni als Projekt (Zählt zur Abschlussklausur dazu) eine Aufgabe bekommen ein Spiel (TicTacToe) zu programmieren. Leider ist ein Teil davon schon vorgegeben und ehrlich gesagt kapiert keiner von uns wie das ganze anfangen soll.

Das ganze läuft als Blue-J Projekt und wir haben als Vorgabe eine abstrakte Klasse Spiel und eine abstrakte Klasse Spieler in denen die Methoden für das Spielfeld/wer dran ist usw. stehen. (wir sollen davon später noch ein Vier Gewinnt ableiten, aber das is erstmal nicht so wichtig)

Leider finden wir da überhaupt keinen Einstieg, da unsere erste Aufgabe ist, eine Methode zu schreiben die zurückgibt ob Spieler 1 oder Spieler 2 dran, zusätzlich soll in der Methode init geschrieben werden das immer Spieler 1 anfängt.

Die vorgegebene Methode Init sieht so aus:

Java:
    public void init(Spieler spieler1, Spieler spieler2) {
        if (beendet) {
            this.spieler1 = spieler1;
            this.spieler2 = spieler2;
            beendet = false; // Spiel starten!
            // Aufgabe 1b: Dafuer sorgen, dass Spieler 1 anfaengt!
            Spieler naechster(2);
        }
    }

Die Methode für den Spieler der als nächstes dran ist (Die soll Spieler naechster() heißen) sollen wir dann noch selbst schreiben, wir haben uns da sowas in der Art überlegt:

Java:
   public int Spieler naechster (int werspielt)
    {
        if (werspielt == 1)
        {   
            System.out.println("Spieler 2 ist an der Reihe");
            return werspielt = 2;
        }
        
        if (werspielt == 2)
        {
            System.out.println("Spieler 1 ist an der Reihe");
            return werspielt = 1;
        }
           
    }
Wahrscheinlich nicht die eleganteste Lösung, aber sicher machbar... hätten wir nicht das Problem mit Init.

Wir stehen da im Moment total auf dem Schlauch, ist die erste Aufgabe und weil da alles drauf aufbaut kommen wir auch nicht weiter.

Kann uns da jemand weiterhelfen?

MfG HuMaHi
 
Zuletzt bearbeitet:

Illuvatar

Top Contributor
(Die soll Spieler naechster() heißen)

Die Methode bei euch heißt aber [c]Spieler naechster (int werspielt)[/c] - und da liegt das Problem ;) Es geht nämlich darum dass eure Klasse von sich aus wissen soll, welcher Spieler dran ist - d.h. ohne von außen die Information zu kriegen, wer spielt.
Das heißt ihr braucht eine Instanzvariable [c]private int werspielt[/c]. In der init-Methode setzt ihr diese Variable dann auf den passenden Wert, und in der naechster-Methode ändert ihr den Wert und gebt den neuen Wert zurück.
 

babuschka

Top Contributor
Hallo,
willkommen im Forum!

Ein schönes Propro habt ihr da bekommen, ich finde es besser als den Vorgänger.
Nun, wie ihr das genau machen sollt steht doch in der Aufgabenstellung:
Sie können sich dazu z. B. eine Referenz auf den aktuellen
Spieler oder einen Index im Objekt speichern
Der erste Vorschlag wäre bei den gegebenen Code vermutlich angemessener. Jetzt müsst ihr nur noch herausfinden, wie ihr es hinbekommt, dass Spieler 1 auch anfängt.
(Die soll Spieler naechster() heißen)
So sollte sie auch wirklich heißen, also keine Parameter, die Aufgabenstellung macht nämlich Sinn (auch wenn es manchmal nicht so aussieht, man könnte das auch ganz anders lösen ;) )

Gruß,

JohnMcLane
 

HuMaHi

Mitglied
public int Spieler naechster (int werspielt)

Also du musst dich schon für einen Rückgabetyp entscheiden
Danke Danke Danke für ein riesen AHA-Erlebnis

Aber jetz nochmal, wir haben diese 2 vorgegebenen (abstrakten) Klassen:

erstens Spiel (verwendet Spieler):
Java:
import java.util.*;


public abstract class Spiel {
    
    /**
     * Erster Spieler.
     */
    private Spieler spieler1;

    /**
     * Zweiter Spieler.
     */
    private Spieler spieler2;

    /**
     * Ist das Spiel gerade beendet?
     */
    
    
    
    private boolean beendet = true;
    
    
    
    /**
     * Initialisiert und startet ein Spiel, sofern es noch nicht läuft.
     * 
     * @param spieler1 Erster Spieler (fängt immer an).
     * @param spieler2 Zweiter Spieler.
     */
    public void init(Spieler spieler1, Spieler spieler2) {
        if (beendet) {
            this.spieler1 = spieler1;
            this.spieler2 = spieler2;
            beendet = false; // Spiel starten!
            // Aufgabe 1b: Dafuer sorgen, dass Spieler 1 anfaengt!
          
        }
    }
    
    
    
    
    
    /**
     * Zeigt das Spielfeld an und beendet das Spiel, falls ein Spieler gewonnen hat.
     */
    public abstract void updateSpielfeld();
    
    /**
     * Ermittelt den Gewinner des Spiels.
     * 
     * @return Gewinner des Spiels.
     */
    public abstract Spieler gewinner();
    
    
    
    
    
    
    /**
     * Beendet das Spiel.
     */
    protected void beenden() {
        this.beendet = true;    
    }
    
    
    
    
    
    
    /**
     * Ist das Spiel gerade beendet?
     */
    public boolean beendet() {
        return this.beendet;
    }
    
    

    
    // Aufgabe 1b: public Spieler naechster()


    
    // Aufgabe 1c: public Spieler spielen()


}

und die Klasse Spieler (die von Spiel verwendet wird):

Java:
public abstract class Spieler {

    /**
     * Satz von acht verschiedenen Spielsteinen.
     */
    private static char[] symbole = new char[] {'X','O','#','+','*','§','=','%'};

    /**
     * Name des Spielers.
     */
    private String name;
    
    /**
     * Spielstein des Spielers.
     */
    private char symbol;
    
    /**
     * Erzeugt einen neuen Spieler.
     * 
     * @param nummer Spielernummer (1 bis 8), daraus ergeben sich Name und Spielstein.
     */
    public Spieler(int nummer) {
        this.name = "Spieler " + nummer;        
        this.symbol = symbole[nummer - 1];
    }
    
    /**
     * Führt so lange einen Zug aus, bis dieser gültig ist.
     */
    public abstract void zug();
    
    /**
     * Gibt den Spielernamen zurück.
     * 
     * @return Spielername.
     */
    public String toString() {
        return name;
    }
    
    /**
     * Gibt den Spielstein zurück.
     * 
     * @return Spielstein.
     */
    public char symbol() {
        return this.symbol;
    }
    
}

wir haben uns jetzt das hier überlegt:
beides in der Klasse Spieler:

für Aufgabe b, also Spieler naechster():
Java:
private Spieler werspielt;

    public Spieler naechster()
    {
        if(werspielt == spieler1) return werspielt = spieler2;
        
        else return werspielt = spieler1;
    }
also einmal die Variable werspielt vom Typ Spieler, die dann in Spieler naechster() benutzt wird um zurückzugeben wer spielt.
In der Init Methode haben wir dann noch werspielt = spieler2 stehen, eben um dafür zu sorgen das immer Spieler 1 spielt.
Würde das so funktionieren? Syntax-Fehler sinds schonmal nicht.

Und um direkt mal auf die Aufgabe c) zu kommen, die haben wir soo versucht:
Java:
    public Spieler spielen()
    {
        updateSpielfeld();
        while (beendet() == false && gewinner() == null) 
        {
            naechster();
            werspielt.zug();  // <<-- darum gehts vorallem
            updateSpielfeld();
        }
        beenden();
        return gewinner();
    }
Das ganze soll also erstmal das Spielfeld updaten und danach halt solange spielen bis es zuende ist, also es einen Gewinner gibt oder das Spielfeld voll ist.
Nur bei dem Teil
Java:
werspielt.zug();
sind wir uns nicht sicher ob das so überhaupt geht. Laut aufgabenstellung soll an der Stelle der Spielzug ausgeführt werden, die Methode dafür ist in der Klasse Spieler, also müsste da ja
Java:
Spieler.zug();
stehen, dann weiß unser Zug aber nicht wer den Zug ausführt, also werspielt, dann führt ja entweder spieler1 oder spieler2 den Zug aus... kommt das so ungefähr hin?
 

babuschka

Top Contributor
Servus,
Zuerst einmal solltet ihr sehr genau aufpassen, wenn ihr im Internet Code zu dem Programmierprojekt postet, das kann euch schnell negativ angerechnet werden, auch wenn es nur sehr wenig ist...
Dann einmal solltet ihr nicht davon ausgehen, dass alle Forenmitglieder hier euer Projekt kennen, also solltet ihr den Anderen vielleicht auch einmal genau darlegen, was genau in den Aufgaben steht (also nichts mit Aufgabengliederung Teil a,b,c etc ;) )
if(werspielt == spieler1)
werspielt ist ein Objekt vom Typ Spieler. Ihr solltet in der Vorlesung sicherlich schon gelesen haben, dass man Objekte nicht mit == vergleicht. Schaut am Besten noch einmal in eure Unterlagen oder sucht hier im Forum ;)

Ich wüsste nicht, dass die Methode zug() in der Klasse Spieler statisch ist

dann weiß unser Zug aber nicht wer den Zug ausführt
Da die Methode zug() in der Spieler-Klasse angesiedelt ist spricht eigentlich nichts dagegen, dass ihr das doch wisst? zug() wird in eurem Spiel also entweder auf dem Objekt spieler1 oder spieler2 ausgeführt, da werspielt nur diese beiden Werte annehmen kann.

Gruß,

JohnMcLane
 

HuMaHi

Mitglied
Also daran das das posten von Code aus dem Projekt vlt nich so günstig ist hab ich garnicht bedacht, aber gut

jetzt nochmal zu deinen Antworten

Zum Thema Objekte vergleichen hab ich jetzt einen ganzen Haufen Sachen gefunden, compare(), compareTo() und equals()... so wirklich hab ich den Unterschied jetzt aber nicht verstanden, bzw. vermute ich mal das ich equals() brauche?

Spieler.zug() geht nicht weil statisch, hab ich tatsächlich übersehen. Aber auch hier hab ich wieder einen Haufen Zeug gefunden.
Weil zug() eben nicht statisch ist kann ich nicht die Methode aufrufen, bzw. aufrufen ohne ein erstelltes Objekt vom Typ Spieler. Anders gesagt geht Spieler.zug() nicht
Spieler Test = new Spieler und danach Test.zug() müsste aber gehen? Oder vertu ich mich da jetzt auch wieder?

Und als letztes, wenn das was ich oben jetzt gesagt habe stimmt, kann ich zug() dann mit werspielt.zug() ausführen, wenn ich in werspielt entweder Objekt Spieler1 oder Objekt Spieler2 speichere? Also würde der Zug dann vom jeweiligen Spieler ausgeführt?

Vlt eher ne Sache für das Anfängerforum, aber wo ich schonmal hier bin...
 

babuschka

Top Contributor
Servus,
Zum Thema Objekte vergleichen hab ich jetzt einen ganzen Haufen Sachen gefunden, compare(), compareTo() und equals()... so wirklich hab ich den Unterschied jetzt aber nicht verstanden, bzw. vermute ich mal das ich equals() brauche?
Die Unterschiede findest Du, indem Du z.B. hier suchst: Java API . Ja, Du kannst equals nehmen. Ich sehe gerade mit Schrecken, dass das so explizit nicht in euren Folien steht...?

Spieler.zug() geht nicht weil statisch, hab ich tatsächlich übersehen. Aber auch hier hab ich wieder einen Haufen Zeug gefunden.
Weil zug() eben nicht statisch ist kann ich nicht die Methode aufrufen, bzw. aufrufen ohne ein erstelltes Objekt vom Typ Spieler. Anders gesagt geht Spieler.zug() nicht
Spieler Test = new Spieler und danach Test.zug() müsste aber gehen? Oder vertu ich mich da jetzt auch wieder?
Spieler Test = new Spieler; erstellt ein Objekt vom Typ Spieler, darauf kannst du die Methode zug() ausführen, da es sich bei Test (Variablen schreibt man übrigens klein, Coding Conventions!) um ein Objekt handelt.

Und als letztes, wenn das was ich oben jetzt gesagt habe stimmt, kann ich zug() dann mit werspielt.zug() ausführen, wenn ich in werspielt entweder Objekt Spieler1 oder Objekt Spieler2 speichere? Also würde der Zug dann vom jeweiligen Spieler ausgeführt?
Im Prinzip ist es egal, ob jetzt Spieler 1 oder 2 in werspielt referenziert ist (dafür musst Du sorgen ;) ), die Hauptsache ist, dass es sich dabei um ein Objekt der Klasse Spieler handelt, wie Du schon richtig erkannt hast.

Gruß,

JohnMcLane
 

Ähnliche Java Themen


Oben