Implementierung Tic tac toc

Naico

Mitglied
Hallo zusammen,

ich muss in meinem Kurs eine Aufgabe erledigen, die mich gerade echt nerven kostet, da ich im Grunde glaube zu wissen, wie es funktioniert, aber nicht in der Lage bin, dies fertigzustellen.

Ich habe eine fertige Tic Tac Toe Version von Java bekommen, die funktionert auch wunderbar etc pp.

Jetzt ist es unsere Aufgabe eine alternative methode des "Tic Tac Toe" Spielfelds zu implementieren, mittels einer Zeichenkette. Per StringBuilder sollen wir die 2Dimensionale Positionsangabe in eine Eindimensinale umwandeln usw usw. Ich stehe seit ein paar Stunden echt auf dem Schlauch...

Mein Lösungsansatz war - Wir sollen per new StringBuilder("000000000") eine Zeichenkette aufrufen, und da rein die jeweiligen positionen setzen etc. Mir ist auch klar, dass wenn ein Spielder dran ist und eine Position besetzt, mittels char da irgendwo ein X oder ein O rein muss. Ich komm echt nicht weiter... Hilfe :rtfm:
 
Die soll ich auch irgendwie verwenden. Zusätzlich soll ich setChar und indexOf verwenden nur :

Ich soll eine neue Klasse erzeugen namens "SpielfeldZeichenkette" und die methoden von einer anderen Klasse übernehmen. Die Methoden der anderen Klasse sind bedacht auf das 3x3 Feld z.b.
public int gibBesitzer(int zeile, int spalte) usw.

In meiner neuen Klasse muss ich ja nun auch mit int und chars arbeiten. Sprich, ein int kommt rein für zeile, spalte -> DANN muss ich aus int einen char machen und in meinem StringBuilder("000000000") halt eine position besetzen und dann den char wieder zu einem int umwandeln damit ich einen return habe. Verzweiflung pur, wenn man grundsätzlich weiß, wie es funktioniert, aber nicht umsetzen kann 🙁 🙁
 
Also das 2D Spielfeld hat Koordinaten (1,1),(1,2),(1,3),(2,1),...,(3,3) und das 1D Spielfeld 1,2,3,...,9?
Dann ist die Umrechnung ja eigentlich nicht so schwierig. Aus einer 2D Koordinate (x,y) kriegst du die 1D Koordinate (x-1)*3+y.
Für eine 1D Koordinate z kriegst du die 2D Koordinaten ( (z+2)/3 , (z-1)%3+1 ).
Beispiel: Für (x,y) = (2,3) kreigst du z = (2-1)*3+3 = 6
Für z = 6 kriegst du (x,y) = ( (6+2)/3 , (6-1)%3+1 ) = (2,3)

Mit den Koordinaten sollte es dir gelingen, die richtige Position entsprechend mit X oder O zu besetzen.
 
Also das 2D Spielfeld hat Koordinaten (1,1),(1,2),(1,3),(2,1),...,(3,3) und das 1D Spielfeld 1,2,3,...,9?
Ich denke, das Spielfeld hat (bzw. sollte haben) eigentlich (0,0), (0,1), ...(2,2) bzw. 0 ... 8. Dann geht auch die Umrechnung wesentlich einfacher:

Code:
x = z % 3
y = z / 3
z = y * 3 + x

Ark
 
Erstmal wünsche ich allen Frohe Weihnachten und bedanke mich für die zahlreichen Antworten 🙂

Ist steh nach wie vor bei folgendem Schritt auf dem Schlauch :

Ich habe in meinem BlueJ Fenster mehrere Klassen und ein SPielfeld interface, eine Testklasse und eine GUI. Mit der neuen Klasse die ich machen soll, diese SpielfeldKettevonZeichen da hab ich mein problem. Ich soll ja eine alternative Version des Spielfelds implementieren. Unser Übungsgruppenleiter meinte wir sollen in die neue klasse mit den zeichenketten die methoden von dem anderen interface übernehmen. aber die methoden sind z.b. besetzeposition (int spieler, int spalte, int zeile) usw. Das ganz soll nun mit den Operationen IndexOf, setChar und setCharAt gemacht werden. Sein Hinweis war - Int ist ein und rückgabewert, aber intern gehts mit chars. Meine Idee ->

Wert kommt per INT rein, Spieler 1 besetzt position 1,1 mit X dann muss ich ja in meinem Stringbuilder("00000000") durch umrechnen die position besetzen und auf dem Spielfeld wird aber das Feld mit einem X markiert. Ich steh ab dem Punkt auf dem Schlauch, wenn ein SPieler dran ist und ich diesen Stringbuilder erzeugt habe bzw. eine Position darin in diesem ("00000000") zu besetzen.

Danke nochmals im voraus
 
Ich steh ab dem Punkt auf dem Schlauch, wenn ein SPieler dran ist und ich diesen Stringbuilder erzeugt habe bzw. eine Position darin in diesem ("00000000") zu besetzen.

na mit genau der von dir beschriebenen Methode!

[c]setCharAt(position, char);[/c]

Die Position errechnest du wie schon oben beschrieben und der char wird ja anscheinend der Methode auch zugeführt ?! Zeig doch mal was du bis jetzt hast und wo genau das Problem liegt.
 
Das ist meine Klasse :
Java:
/**
 * Write a description of class SpielfeldZeichenkette here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class SpielfeldZeichenkette implements Spielfeld
{
    // instance variables - replace the example below with your own
    private StringBuilder _s1;
    /**
     * Constructor for objects of class SpielfeldZeichenkette
     */
    public SpielfeldZeichenkette()
    {
        _s1 = new StringBuilder ("000000000");
    }
    
   
    
    public int gibBesitzer(int zeile, int spalte)
    {
        return 0;
    }
    
    
    
    public void besetzePosition(int zeile, int spalte, int spieler)
    {

        
    }
    
    
    
    public boolean istVoll()
    {
        return false;
    }

}
 
Das ist meine Klasse :

Und wo hat sich deine Frage versteckt? 🙂

Java:
    public void besetzePosition(int zeile, int spalte, int spieler)
    {
 
        
    }
da rufst du halt jetzt [c] _s1.setCharAt(position, char);[/c] auf mit den richtigen Werten.
(Welche Werte werden eig. für [c]int spieler[/c] benutzt? 88 und 79 ? Oder welche Integer-Werte bekommst du da übergeben?
 
Hi, ich habe auch mal Tic Tac Toe programmiert gehabt und einen anderen Ansatz gewählt.

Mich würde mal deine Softwareüberlegung interessieren.

Ich hatte es mir damals so gedacht:
Was haben reguläre Spiele gemeinsam?

Da fiel mir ein das man ein Spielbrett braucht, dass aus Zeilen und Spalten besteht.
Java:
    int getRows(); // Spalte
    int getColumns(); // Zeile
byte getAtPosition(byte column, byte row);

Danach habe ich mir überlegt, dass das Spielbrett von einen Stein der beiden Spieler oder von keinen Stein belegt sein kann.

Java:
byte getPlayerOne();
byte getPlayerTwo();
byte getPlayerNone();

Da ich eine ADT selbst programmiert habe, der keinen konkreten Spieltypen enthält, sieht meine setAtPosition so aus :
Java:
RegularGame<M> setAtPosition(byte comlumn, byte row);

Weitere:
Java:
 /* 3. Welcher Spieler ist gerade am Zug?*/
    byte currentPlayer();
    byte otherPlayer(byte Player);

    /* 4. Gibt es noch weitere Spielzüge oder nicht */
    boolean noMoreMove();
    boolean ended(); // Bei TicTacToe ist das Spiel bei 9 Spielsteinen zuende

    /* Hat ein Spieler gewonnen */
    boolean wins(byte player);
    /* Spielzustand für einen bestimmten Spieler bewerten. */
    int evalState(byte player); // je höher, desto besser der Spielzustand für den Spieler


Das sind einiger meiner Ideen gewesen und vielleicht hilft es ja weiter.
Weiterhin würde ich überlegen mit dem Interface Cloneable zuarbeiten mit dem du flache oder auch tiefe Kopien eines Objekts machen kannst.


grüße


PS: Ich habe dass hier schnell zusammengeschrieben, da ich bei dir den schnellstart ins Proggen bemerke.

( viele forenmitglieser haben mir desöfteren in arsch getreten , wenn ich gleich los programmiert habe 😉 )

Deswegen nur der tipp von mir, vielleicht sehe ich es falsch und du hast schon alles überlegt , grüße
 
Und wo hat sich deine Frage versteckt? 🙂

Java:
    public void besetzePosition(int zeile, int spalte, int spieler)
    {
 
        
    }
da rufst du halt jetzt [c] _s1.setCharAt(position, char);[/c] auf mit den richtigen Werten.
(Welche Werte werden eig. für [c]int spieler[/c] benutzt? 88 und 79 ? Oder welche Integer-Werte bekommst du da übergeben?


Also muss ich darin dann ja, wenn spieler 1 dran ist, den wert umrechnen WO ins eindimensionale feld das X für spieler 1 hinmuss, und bei Spieler 2 das O dann. Vorausgesetzt, dass Feld ist frei.
 
So als anfang 😉
Java:
public void besetzePosition(int zeile, int spalte, int spieler)
    {
        int v1;
        v1 = ((zeile-1)*3+spalte);
        _s1.setCharAt(v1, 'X');
                
    }
 
@eraaa

Oh sorry, ich habe vergessen warum man das machen kann, hinzuschreiben.
Naja es ist eine Entwurfsentscheidung , dass ein Spielzug nicht den Spielstand modifizieren soll , sondern einen neunen Spielstand als Ergebnis berechnet.

Und dieser lässt sich halt am einfachsten aus einer Kopie erzeugen mit der Methode clone(). und das Interface Cloneable.

Und dann halt keine shallows sonder tiefe Kopien. Ein neues Objekt erzeugt das this Objekt und alle werte werden übernommen.

Sonst muss man halt mehrere Objekte erstellen , jeder Stein ein Objekt, wie auch immer.
Aber man kann ja einfach ne Kopie machen.


Ich habe also eine Kopie erzeugt, dann in der Kopie den nächsten Spieler als aktueller spieler gesetzt , den spielstein setzen lassen und den spielzug um 1 erhöht.

@naico ?



Ist deine Frage jetzt , wie man es implementiert?
Also übergebe doch einfach 1,1,1 und dann setze den Stein. Siehe eraa . Und dann noch schauen ...ahhh da ist schon ein Stein 😉

grüße
 
Die übergabe ist jetzt kein Problem mehr. Jetzt muss ich ja noch eine Abfrage einbauen, ob diese Position frei ist. Daran arbeite ich gerade.
 
So, nachdem ich nun was gegessen hab und meine Laune auch wieder besser geworden ist, dass habe ich bis jetzt gemacht, geht das ungefähr in die richtige Richtung?

Java:
/**
 * Write a description of class SpielfeldZeichenkette here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class SpielfeldZeichenkette implements Spielfeld
{
    // instance variables - replace the example below with your own
    private StringBuilder _s1;
    /**
     * Constructor for objects of class SpielfeldZeichenkette
     */
    public SpielfeldZeichenkette()
    {
        _s1 = new StringBuilder ("000000000");
    }
    
   
    
    public int gibBesitzer(int zeile, int spalte)
    {
        return 0;
    }
    
    
    
    public void besetzePosition(int zeile, int spalte, int spieler)
    {
        int v1;
        v1 = ((zeile-1)*3+spalte);
        if (spieler == 1)
        {
            _s1.setCharAt(v1, 'X');
        }
        if (spieler == 2)
        {
            _s1.setCharAt(v1, 'O');
        }
                
    }
    
    public char charAt(int index)
    {        
        return _s1.charAt(index);    
    }
    
        
    public boolean istVoll()
    {
        return false;
    }

}
 
Die Berechnung scheint falsch zu sein oder?

und
Java:
    public boolean istVoll()
    {
        return false;
    }

ist auch noch mal eine Überlegung wert 😀
 
Die Berechnung scheint falsch zu sein oder?

und
Java:
    public boolean istVoll()
    {
        return false;
    }

ist auch noch mal eine Überlegung wert 😀

Die Berechnun muss ich nochmal überarbeiten, das stimmt 🙂

Ich hab die Boolean methode nur auf false gesetzt, damit sich die klasse am anfang übersetzen ließ 🙂
 
Java:
  /**
     * 
     * @param zeile - (0,0) 1.Stelle für Zeile
     * @param spalte - (0,0) 2. Stelle für Spalte
     * @param spieler - playerOne , playerTwo
     */
    public void besetzePosition(int zeile, int spalte, int spieler)
    {
        /* Berechnen der Zeichenposition im StringBuilder*/
        int v1 = ((zeile-1)*3+spalte);
        // (0,0) = -3; (1,0) = 0 usw.
        
        int v2 = ((zeile*3)+spalte);
        // (0,0) = 0; (1,0) = 3; (2,0) = 6;
        // (0,1) = 1; (1,1) = 4; (2,1) = 7;
        // (0,2) = 2; (1,2) = 5; (2,2) = 8;
        
        /* Spieler übergeben */
        if (spieler == 1)
        {
            _s1.setCharAt(v1, 'X');
        }
        if (spieler == 2)
        {
            _s1.setCharAt(v1, 'O');
        }
                
    }

Java:
 public boolean istVoll(StringBuilder builder)
    {
       /* Schauen ob Spielbrett voll ist bzw. Strinbuilder */
       /* StringBuilder(CharSequence seq) */
       
       /* Überlege dir ob du den StringBuilder überprüfen illst , oder es das ganze
        * erst in toString umwandelst*/
       char[] a = new char[9];
       builder = new StringBuilder();
       builder.getChars(0, 8, a, 0);
       
       /* Nun hast du in char[] dein Characterdaten und kannst sie behandeln*/
       /* Es gibt auch andere MMöglichkeiten*/
      
       
       
       if(builder != null){
            
        }
        
       
    
        return false;
    }



Nun liegts wieder an dir, gruß
 
Nabend und danke an die vielen Antworten 🙂

@ Spin :

Ich werde mich morgen mal ransetzen und in die methode besetzeposition noch die Bedingung einfügen, dass ausserdem Überprüft wird ob an der Stelle nicht schon der andere Spieler sein X oder O hat.

Und die Boolean methode knöpfe ich mir morgen gleich auch noch mit vor....
 
Hurra, ich bin ein wenig weiter gekommen und habe nun wieder ein kleines problemchen 🙂

Ich habe diese Methode erweitert (die falsch ist irgendwie):
Java:
public int gibBesitzer(int zeile, int spalte)
    {  
        return 1;
    }
Wenn ich diese Methode SO lasse und mir über die Tic Tac Toe GUI ein Spielfeld erzeuge, sind alle positionen mit einem X belegt.

Wenn ich return 2 nehme, dann sind alle Positionen voll mit einem O. Bei return 0 ist das Spielfeld leer, aber er nimmt auch keine clicks an. jetzt hab ich bisschen rumgespielt bzw zeile spalte umgerechnet (bzw VERSUCHT umzurechnen in einen char und wieder zurück) damit ich ja die positionen belegen kann.

Jetzt sieht das ding so aus :
Java:
public int gibBesitzer(int zeile, int spalte)
    {  
        char a;
  
        int z2 = ((zeile*3)+spalte);
        
        a =(char) ('0'-45);
        return a;
    }

jetzt kommt diese Fehlermeldung aus einer anderen Klasse :
ArrayIndexOutOfExecption : 3

Ich will ja das Spielfeld erzeugen und dann da rumklicken und er soll die positionen nehmen....

In meiner Übungsmappe steht - Dieser befehlz hilft uns hierbei (char) ('0'-2)==2

Stehe mal wieder aufm Schlauch 🙂

Danke im voraus
 
[c](char) ('0'-2)==2[/c] gibt immer false aus, denn [c](char) ('0'-2)[/c] ist der Punkt '.', also sicher nicht 2.

Die Methode gibBesitzer, soll doch den besitzer einer Zelle zurückgeben. Wenn du jedesmal 1 oder 2 oder 0 zurückgibst, stimmt das doch nicht! Nicht jede Zelle gehört dem gleichen. Das ist ja der Punkt, dass du in dieser Methode herausfinden musst, ob sie 0, 1 oder 2 gehört, aber sicher nicht immer demselben.

In deiner abgewandelten Variante von getBesitzer berechnest du irgendein z2. Aber das verwendest du ja dann gar nicht mehr. Stattdessen gibst du immer den '0'-45 zurück, was immer 3 sein wird. Diesen Besitzer gibt es ja gar nicht. Das führt auch dazu, dass du in irgendeinem Array auf die Stelle 3 zugreifst, obwohl es nicht 3 Elemente besitzt.
 
Wie kann ich es denn so machen, dass sich ein leeres Spielfeld erstellt und dieses dann auch die Mausklicks annimmt und die positionen besetzt? Das frustrierende dabei ist, dass ich heute echt lang dran gesessen hab und irgendwie nicht voran komme :/
 
Hallo Marco,

nein leider noch nicht. Wir hatte mal vor 2 Monaten eine Übung, da war so ne Swing sache in einer Methode, aber darauf eingegangen wurde noch nicht, das soll wohl später noch kommen :autsch:
 
Jetzt ist es unsere Aufgabe eine alternative methode des "Tic Tac Toe" Spielfelds zu implementieren, mittels einer Zeichenkette. Per StringBuilder sollen wir die 2Dimensionale Positionsangabe in eine Eindimensinale umwandeln usw usw. Ich stehe seit ein paar Stunden echt auf dem Schlauch...


Ähm , warum willst du denn jetzt eine Oberfläche bauen?
Auf der du Mausklicks abfangen kannst usw.

Das ist doch quatsch. Versuch es mit deiner jetzigen Idee zu realisieren.
Kennst du die Methoden, die Strings bieten?

bzw. wo bleibst du denn jetzt hängen?
 

Zurück
Oben