# Vier Gewi nnt - Sieger ermitteln



## Mr.Vain (20. Jun 2012)

Hallo,

möchte gerne das Spiel Vier Gewi nnt in Java programmieren.

Habe dazu eine GUI mit einer JTable. Die Zellen werden mittels ENUM einen Wert übergeben (leer, sp1, sp2).

Die Übergabe der Werte, bzw Setzen eines Steins erfolgt mittels Button über den Spalten.


Meine Frage:  

Habt ihr eine Idee, wie ich ermitteln kann, ob jemand gewonnen hat? Gibt es da evl eine "einfache" Lösung?


----------



## Final_Striker (20. Jun 2012)

Was ist denn für dich eine "einfache" Lösung?


----------



## Mr.Vain (20. Jun 2012)

naja, 

ich bin gerade am überlegen, wie ich die Methode am effektivsten schreibe, um zu prüfen ob es einen Sieger gibt.


Ach ja, die Tabelle ist ein zweidimensionales Array mit 7 Spalten und 6 Zeilen


----------



## Royal-Sarge (20. Jun 2012)

ich hatte das gleiche thema auch schonmal behandelt, aber ich habe nur eine sehr aufwendige methode parat, auch wenns copy+paste ist.

Du machst folgendes: du machst eine verändernde methode, die erstellst du aber private.
Danach machst du eine if-Abfrage für die (ich nenn sie jetzt mal x und y Achse) Achsen, also x und y.
dann gehst du durch, wenn der ganz linke kreis auf der x achse und die darauf folgenden 3 die gleiche farbe haben, dann hat der spieler gewonnen. das gleiche machst du für alle spalten und auch die y achse. danach musst du dasselbe für die diagonalen, aber das wird der schwierigste teil. Nachdem du das alles mit copy+paste erstellt hast, musst du nur noch am ende der methode, mit der der spieler einen "coin" in die spalte einwirft, schreiben, dass er diese methode ausführen soll. Das ganze kombiniert man dann mit einer Systemausgabe und fertig. Das ist zwar die glaube ich aufwendigste, aber wie du geschrieben hast "einfachste", weils nur copy+paste ist

Edit: was ich noch sagen will, die Gewinnüberprüfung brauchst du nicht zwingend, das ist nur eine "Verschönerung", denn du hast ja bereits so wie ich es verstanden habe, das Spielfeld grafisch dargestellt. Wenn man dann nicht sieht, dass man gewonnen hat, macht man entweder das originale Spiel kaputt oder man muss einfach nur strohdumm sein


----------



## Marco13 (20. Jun 2012)

Erstmal wäre es natürlich extrem häßlich, sowas direkt auf der JTable oder dem TableModel zu machen :autsch: Hast du keine Klasse für das Spielfeld? Mach' dir zumindest ein 

```
interface Board {
    int getWidth();
    int getHeight();
    Piece getPiece(x,y); // Piece ist ein enum
}
```
Notfalls kann die erste Implementierung für die ersten Tests ja auf die bestehenden Strukturen (d.h. die Tabelle) zugreifen... immernoch häßlich, aber wenigstens EIN entkoppelnder Schritt...

Das eigentliche Problem... von der Vorgehensweise her würde mir auch kaum was anderes einfallen, als das, was Royal-Sarge geschrieben hat, aber wenn da von "copy & paste" die Rede ist, klingt das nach if-Abfragen, die man mit Schleifen abdecken sollte. Auf Basis so eines Board-Interfaces könnte die Überprüfung GROB und im halb-Pseudocode schnell hingeschrieben wohl etwa so aussehen

```
private static Piece getWinner(Board board)
{
    for (int x=0; x<board.getWidth()-4; x++)
    {
        for (int y=0; y<board.getHeight()-4; y++)
        {
            Piece first = board.getPiece(x,y);
            if (first != Piece.NONE)
            {
                // Prüfe, ob bei (x,y) eine waagerechte,
                // diagonale oder senkrechte 4er-Reihe
                // anfängt, die nur aus dem 'first' Piece
                // besteht. 
                if (hasLine(board, first, x, y, 1, 0)) return first;
                if (hasLine(board, first, x, y, 1, 1)) return first;
                if (hasLine(board, first, x, y, 0, 1)) return first;
            }
        }
    }
    return Piece.NONE;
}

private static boolean hasLine(Board board, Piece piece, int x, int y, int dx, int dy)
{
    int cx = x + dx;
    int cy = y + dy;
    // Prüfe die nächsten 3 Felder in der angegebenen Richtung
    for (int n=1; n<4; c++)
    {
        if (board.getPiece(cx, cy) != piece)
        {
            // Da ist ein Piece, das NICHT dem ersten der Reihe
            // entspricht, also ist es keine 4er-Reihe
            return false;
        }
        cx += dx;
        cy += dy;
    }
    return true;
}
```

Hm. Eigentlich ist das gar kein _Pseudo_code...


----------



## Titanpharao (20. Jun 2012)

Das Spiel geht die runde wegen dem Wettbewerb wa ?


----------



## Mr.Vain (21. Jun 2012)

Andere Frage.

Hab ja ein JTable als Spielfeld. Dahinter steckt eine zweidimensionales Array aus Enumerations.

Nun möchte ich je nach ENUM ein Icon in die Zelle packen. Wie mache ich das am besten?


----------



## Marco13 (21. Jun 2012)

Eigener CellRenderer How to Use Tables (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Swing Components)


----------



## Mr.Vain (21. Jun 2012)

Irgendwie verstehe ich nicht ganz, was ich  machen muss.

Muss ich nun eine neue Klasse schreiben, die vom DefaultTableRenderer erbt und da eine Methode überschreiben?


Wie mache ich das denn und wie bekomme ich dann ein Icon (je nach Inahlt) in die Zelle?


----------



## Marco13 (22. Jun 2012)

Ja, davon erben und die Methode überschreiben. Das Objekt ("value") das dort übergeben wird, ist der Tabelleneintrag an der jeweiligen Stelle. Man kann abhängig davon sowas machen wie
if (value.equals(something)) setIcon(someIcon);
else setIcon(someOtherIcon);


----------

