# vier gewinnt programmieren - aber wie



## TF135 (18. Mai 2009)

Ich programmiere "4 gewinnt" mittels GUI ... im Netz habe ich ein Beispiel gefunden, allerdings funktioniert es bei mir nicht:

Einfaches Vier Gewinnt mit GUI - Java - Coder Forum

In der Comandozeile von Eclipse steht FOO und das wars dann.

Von Abschreiben hat ma ja noch nie viel gelernt, also hab ich mich selber ans Werk gemacht.
Mein Spiel soll die Dimension 10 haben - sprich 10 x 10 Felder = 100
Ich könnte jetzt sinnfrei 100 Buttons anlegen ... Button1, 2. Aber sicher gibt es elegantere Lösungen. Mir schwebt ein Array von Buttons vor - geht das, wenn ja wie oder macht man das vielleicht ganz anders, besten Dank vorab.


----------



## ARadauer (18. Mai 2009)

mhn 10 mal 10, eher 10 arrays wo 10 buttons drin sind.... so könntest du es versuchen...


----------



## Schandro (18. Mai 2009)

Von der Syntax her geht das so:
JButton[][] area = new JButton[10][10];
Du musst aber noch jedem Element im Array ein neuen JButton zuweisen, automatisch werden die nicht erstellt, das Array stellt nur einen Haufen Referenzen/Varaiblen bereit die am Anfang noch alle auf "null" zeigen.


----------



## Marco13 (18. Mai 2009)

```
private JLabel[] field = new JLabel[42];
```
Ausgerechnet 42. Klassisch.

Die Frage "wie macht man das" kann nicht benatwortet werden - höchstens mit Gegenfragen wie "Wie viel Arbeit willst du dir machen?". Ein Array von Buttons wäre eine einfache (nicht schöne, aber einfache) Option.

```
JButton buttons[][] = new JButton[10][10]; // Auch klassisch ;)
...
buttons[0][2] = new JButton("X");
buttons[0][2].addActionListener(...)
```


----------



## TF135 (18. Mai 2009)

also - wie immer - man möchte sich so wenig wie möglich arbeiten machen, ich mir auch allerdings habe ich das Problem, daß mir die Java-Welt sehr fremd ist und dann wieder gilt, jede Lösung die einem einfällt ist eine gute Lösung.

Erst dachte ich (die max. Dimension ist 15) ich tippe 225 Buttons - wird einer davon gedrückt male ich entweder ein x oder o rein und deaktiviere ihn (irgendwie). Das is mal sehr häslich und ich sitze vermutlich Jahre ... da kam ich auf die Idee mit Array ... irgendwie ist das auch ned viel schöner, aber da ihr mit Java mehr zu Streich kommt wie ich, fällt euch sicher was vielleicht total triviales ein.


----------



## Schandro (18. Mai 2009)

> Erst dachte ich (die max. Dimension ist 15) ich tippe 225 Buttons - wird einer davon gedrückt male ich entweder ein x oder o rein und deaktiviere ihn (irgendwie). Das is mal sehr häslich und ich sitze vermutlich Jahre ... da kam ich auf die Idee mit Array ... irgendwie ist das auch ned viel schöner,


*WAS??*

Du vergleichst grade 10.000 extrem hässliche undynamische Codezeilen
mit ca. 100 dynamischen Zeilen.

Lies dich mal in das Thema Arrays (vllt. sogar Collections) ein bevor du sowas behauptest.

Eine viel bessere Lösung als Arrays/Collections gibts für sowas nicht.


----------



## diggaa1984 (18. Mai 2009)

TF135 hat gesagt.:


> Erst dachte ich (die max. Dimension ist 15) ich tippe 225 Buttons - wird einer davon gedrückt male ich entweder ein x oder o rein und deaktiviere ihn (irgendwie). Das is mal sehr häslich und ich sitze vermutlich Jahre



Ja würdest du vermutlich  .. aber wenn du es erstmal mit Arrays probieren möchtest, diese 225 Tipper kannst bequem in einer Schleife, bzw soltlest du dann auch, umsetzen.

```
public class GUI implements ActionListener {

private static final int DIMENSION = 10;

...

private void initGUI() {
    ...
    int numButtons = DIMENSION * DIMENSION;

    for (int i=0; i<numButtons; i++) {
        buttons[i] = new JButton();
        buttons[i].addActionListener(this);
    }

    //verteilen der buttons auf der GUI und sonstiges
}

public void actionPerformed(ActionEvent e) {
    JButton b = (JButton) e.getSource();

    if (spieler1isDran)
        b.setText("X");

    if (spieler2isDran)
        b.setText("O");

    b.setEnabled(false);
}

}//GUI
```

so in etwa würden dann zichtausende buttons entstehen können, oder eben nur einer, deine Wahl 

ob der code da grad so 100% wasserdicht ist weiss ich nicht, is grad einfach nur runtergetippt


----------



## TF135 (18. Mai 2009)

@schandro

klar ist das Vorgehen mit Array schon viel viel besser, also zig Buttons zu Fuß zu generieren, aber ich war mir halt nicht sicher obs vielleicht noch nen viel eleganteren Weg gibt

@digga1984

der Ansatz leuchtet mir ein ... damit kann ich mal probieren, wobei im Moment klemmts schon viel früher, aber der Tag ist ja noch jung


----------



## TF135 (18. Mai 2009)

so da bin ich wieder und schaue recht ratlos, ich habe das programmiert:

int numB = DIM * DIM;				// Anzahl der Buttons errechnen
Button[] buttons = new Button[DIM];	// erzeugen von Buttons mit Anzahl DIM

	for (int i = 0; i < numB; i++) 
	    {
	    	//buttons_ = new Button("");	// Button ohne Inhalt erzeugen
           }

daß ich noch keinen Button sehen kann ist mir klar, ABER sobald ich den Teil in der for-Schleife verwende, verschwinden meine bisherigen Labels auf meinem Fenster, allerdings ist mir ziemlich unklar wieso?_


----------



## Schandro (18. Mai 2009)

> sobald ich den Teil in der for-Schleife verwende, verschwinden meine bisherigen Labels auf meinem Fenster


Das kann nicht sein, da du in der auskommentierten Zeile nur ein paar Instanzen von Button erstellst und sie im Array abspeicherst. Das dürfte absolut keine Auswirkung auf irgendwas anderes haben.

Schreib doch mal ein passendes KSKB.^^


----------



## TF135 (18. Mai 2009)

KSKB, bitte was ?


----------



## diggaa1984 (18. Mai 2009)

Kleines selbst-kompilierbares Beispiel war das glaube ^^

also ne klasse die ohne zu zucken compilierbar ist, ohne Exception ohne nix, welche den Fehler verdeutlicht.

und ich geben Schandro mal recht 

edit2: du musst aber auch soviel Platz im array reservieren wie numB angibt. bei ner Dimension von 10 reservierst du 10 Plätze statt 100, aber ändert nix an Labels oder dergleichen, müsste dir nur ne IndexOutOfBounds-Exception geben, was im blödesten Fall abgefangen wird ohne was zu machen, und du NIX mehr dem Fenster addest was unterhalb der for-schleife geschrieben wurde. Wenn da Labels stehen, dann is klar das die net sichtbar werden ^^


----------



## TF135 (18. Mai 2009)

Schande über mein Haupt - wenn man alle dem genug Speicher reserviert, dann hat ma hinterher au keine Probleme:

-> richtig: Button[] buttons = new Button[numB];

Mal gucken was ich noch so für Mist baue, bis wenigstens alle Felder auf m Schirm sind :rtfm:


----------



## TF135 (19. Mai 2009)

so da bin ich wieder, ich "Spezialist" 

mein Programm sieht bisher so aus:

public class StartFW extends JFrame
{
 	static final long serialVersionUID = 1L;		//

 	public StartFW(String title) 
 	{
 		super(title);					//
 		setSize(500, 675);				// feste Fenstergröße
 		setDefaultCloseOperation(EXIT_ON_CLOSE);	
 		setVisible(true);					// sichtbar

 		add(new TextFW());				// Beschriftungen aufrufen

 		add(new PlayerA());				// Spieler A - Steinwahl		

 		add(new DimFW());                             // Wahl der Dimension
 	}

	public static void main (String args[]) 
	{
		new StartFW ("4 gewinnt - Spieler A vs. Spieler B");	
	}
}

wenn ich das ausführe, sehe ich NUR was in DimFW() passiert - ein Choicefeld, TextFW() und PlayerA() funktionieren, werden aber nur sichtbar, wenn die Aufrufe danach ausmaskiere. Für euch is das wahrscheinlich logisch - öhm für mich nicht. Wie bringe ich es fertig, daß die vorherigen Aufrufe erhalten bleiben und nicht immer "überschrieben" werden?


----------



## Marco13 (19. Mai 2009)

Dort ist die Antwort praktisch die gleiche wie bei http://www.java-forum.org/awt-swing...-wie-mit-koordinaten-aber-wie.html#post518561 - In ein Frame (bzw. Contentpane) "passt" erstmal nur eine Component, außer wenn man genauer sagt, wo die anderen hin sollten. Du solltest dir auf jeden Fall Using Layout Managers (The Java™ Tutorials > Creating a GUI with JFC/Swing > Laying Out Components Within a Container) durchlesen, sonst kommst du auf keinen grünen Zweig...


----------



## L-ectron-X (19. Mai 2009)

Vielleicht hilft dir das weiter: 'Vier Gewinnt' programmieren - Byte-Welt Forum


----------



## TF135 (24. Mai 2009)

Jahre und viele Sorgenfalten später ...

ich habe im default-Fall ein Button-Array (eindimensional) von 100 Elementen, mühsam habe ich es au hinbekommen den entsprechenden Button einzufärben wenn er gedrückt wird. Jetzt wollte wissen welche No der Knopf hat also z.B. Button[12], dazu wollte ich:

int p;
p = (JButton)e.getSource(); // weißt p die No des gedrückten Button zu

so meckert Eclipse (Type mismatch: cannot convert from JButton to int), bestimmt au zurecht ... und irgendwie hab ich hier gelesen, daß das Button-Model das gar ned könnte, suche ich also eine Lösung die es so nicht gibt oder liegt die Lösung zum greifen nahe?


----------



## Marco13 (24. Mai 2009)

Hmjo, vielleicht. Schau mal hier http://www.java-forum.org/java-faq-beitraege/49255-componenten-und-listener.html die 2. Möglichkeit an. Wenns nicht hilft, sag bescheid.


----------



## TF135 (24. Mai 2009)

```
for(int i=0; i < buttons.length; i++)
		{
			if (e.getSource() == buttons[i])
			{
				System.out.println(i);
			}
		}
```

so hab ich das gemacht und es gibt mir die No des richtigen Knopfs aus, damit komm ich weiter ... aber das mit system.out.println geht eigentlich anders oder, Stichwort Formatierung


----------



## Marco13 (25. Mai 2009)

Kannst du die Frage präzisieren?


----------

