Café International Theoriensammlung

@Crian : Das sehe ICH etwas anders. Hier würde ich in einer übergeordneten Klasse eher etwas in der Art “setzeStuhlUndTisch” oder “composeChairToTable” und dort beides aufrufen.

was ich vielleicht zuvor schon erstmals ins Spiel gebracht habe kann auch wirklich gefährlich sein, etwa wenn
Tisch#addStuhl() bereits manuell aufgerufen wurde,
dann kommt Stuhl#addToTisch() mit zweitem Mal Tisch#addStuhl(), doppelten Hinzufügen…

allerdings auch bisschen irrsinnig wie viele hier zu diesem Programm mit überschaubarer Weltbedeutung schreiben :wink:

Bei den Tischen hast du die toString() auch noch nicht überschrieben.
Ansonsten die Ausgabe sollte ganz flott über Arrays.toString(list.toArray()) funktionieren.

[QUOTE=BinaryLogic]Bei den Tischen hast du die toString() auch noch nicht überschrieben.
Ansonsten die Ausgabe sollte ganz flott über Arrays.toString(list.toArray()) funktionieren.[/QUOTE]

Oh ja, okay, danke schön, woran man hier nicht alles denken muss.

	     return land + "";
	}```

Klappt alles knorke.

Edit: Sodele, habe nun auch die Stühle generieren können.
So sieht meine Stuhlklasse aus:
```package spiel;

public class Stuhl {
	   
    private Gastkarte gast;
    private Tisch tisch;
   
    public Stuhl(Gastkarte gast) {
    	this.gast = gast;
    }
    
    public void addToTisch(Tisch tisch){
        this.tisch = tisch;
    }
    
    public String toString(){
	     return gast + "";
	}
   
    public void addGast(Gastkarte gast){
        if(this.gast == null){
            this.gast = gast;
        } else {
            System.err.println("Der Stuhl ist bereits belegt!");
        }
    }
 
}```

Ich hab nun ne Methode spielfeldgenerieren, welche sich dem Fall der Generierung der Tische und Stühle schon mal annimmt:
```public static void spielfeldgenerieren() {
		 for(int n=0;n<12;n++) {
			 tische.add(new Tisch(laenderkarten.get(n)));
		 }
		 for(int n=0;n<24;n++) {
			 stuehle.add(new Stuhl(null));
		 }
		 System.out.println(stuehle);
		 System.out.println(tische);
	 }```
Die Tischliste gibt dann schön die 12 Tischwerte aus, also die Länder, welche darauf liegen.
Und die Stuhlliste sind 24 Nullwerte. Wie gewollt, sitzt ja auch noch nichts drauf. ;)

Aus meiner Sicht wichtig: in der Klasse Tisch ist das Feld Laenderkarte final, dass heist, dass man dort später keine neue Laenderkarte zuweisen kann.

bye
TT

Das liegt wohl daran, dass es hier im Forum zur Zeit sehr wenige Threads zu beantworten gibt. Außerdem ist das Spiel recht interessant.

*** Edit ***
@FranzFerdinand

Ich finde es etwas gewagt, wenn es schon die beiden Klassen Laenderkarte und Land gibt (Laenderkarte scheint mir generell überflüssig zu sein, aber egal), dann später eine Variable vom Typ Laenderkarte land zu nennen.

[QUOTE=FranzFerdinand;106999]

import spiel.Gastkarte.Land;

public class Laenderkarte {
	
	   public final Land land;
	 
	   public Laenderkarte(Land land){
	      this.land = land;
	   }
	 
	   public String toString(){
	     return land + "";
	   }
}

[…]

import java.util.ArrayList;
import java.util.List;

import spiel.Gastkarte.Land;

public class Tisch {
	   
    private List<Stuhl> stuehle = new ArrayList<Stuhl>();
	
    public final Laenderkarte land;
	
	public Tisch(Laenderkarte land){
	      this.land = land;
	}
    

}```[/QUOTE]

*** Edit ***

[QUOTE=FranzFerdinand;107006]
```public String toString(){
	     return land + "";
	}```
[/QUOTE]

Generell ist es etwas hässlich, mit einem `+ ""` den Typ zu verbiegen. Verwende dafür besser `land.toString()`, falls `land` eine sinnvolle Methode `toString()` hat.

Bei Integerzahlen kann man sich etwa mit `Integer.toString(index)` behelfen.

*** Edit ***

[QUOTE=timbeau;106985]@Crian : Das sehe ICH etwas anders. Hier würde ich in einer übergeordneten Klasse eher etwas in der Art "setzeStuhlUndTisch" oder "composeChairToTable" und dort beides aufrufen.[/QUOTE]

Naja, aber 

```    private Tisch tisch;
   
    public void addToTisch(Tisch tisch){
        this.tisch = tisch;
    }

ist einfach nur ein Setter. Dann sollte man das Ding imho auch so nennen:

   
    public void setTisch(Tisch tisch){
        this.tisch = tisch;
    }

[quote=Crian]Naja, aber``` private Tisch tisch;

    public void addToTisch(Tisch tisch){
        this.tisch = tisch;
    }```ist einfach nur ein Setter. Dann sollte man das Ding imho auch so nennen:[/quote]Rein technisch gesehen hast Du recht.

Aber ich denke, dass Setter als solche erstmal schlecht sind und in Fachklassen vermieden werden sollten.

Dieser hier ist aber eine fachliche Notwendigkeit was auch über den Namen transportiert wird. Dieser Name erhöht die Hemmschwelle ein null zu übergeben. Das allein ist für mich schon den anderen Namen wert.

bye
TT

[QUOTE=FranzFerdinand]```package spiel;

public class Stuhl {

private Gastkarte gast;
private Tisch tisch;

...

public void addToTisch(Tisch tisch){
    this.tisch = tisch;
}

}```[/QUOTE]
So kann einem Stuhl nur ein Tisch zugeordnet werden. In dem Spiel kann bei der Anordnung ein Stuhl an bis zu drei Tischen stehen.

[quote=_Michael;107037]So kann einem Stuhl nur ein Tisch zugeordnet werden. In dem Spiel kann bei der Anordnung ein Stuhl an bis zu drei Tischen stehen.[/quote]Deswegen war meine Idee, einem Stuhl “seine” Tische als Varars im Konstruktor zu übergeben. Der Stuhl würde sich dann selbst an die übergebenen Tische “stellen”, womöglich mittels “package private” Methode in der Tisch-Klasse.

bye
TT

Stimmt, das wäre sicherlich eine gute Sache. Mir ging es auch in dem Prototyp nicht darum eine fertige Klasse zu entwickeln sondern die Verbindung von Tisch und Stuhl aufzuzeigen.

Kann ich nachvollziehen. Ich habe die Spiellogik auch mal spaßeshalber durchimplementiert und im ersten Ansatz hatte ich auch eine Klasse „Laenderkarte“, die nur eine einzige Eigenschaft, nämlich „Land“ hatte. Das habe ich dann aber abgeändert, sodass „Land“ direkt benutzt wurde, weil eine überflüssige Abstraktionsebene entfallen konnte.

An der toString()-Variante ist besser, dass der Methodenaufruf explizit gemacht wird. Bei der + ""-Variante wird er auch gemacht, aber implizit zum konvertieren der Variablen in einen String, weil durch das + "" ein String-Kontext erzwungen wird. In der ersten Variante sieht man sofort was passiert, in der zweiten Variante ist der Schritt zur toString()-Methode nicht so offensichtlich.

Wohl nicht direkt ActionListener, da dies ein existierendes Interface ist, das für GUI Kompontenten genutzt wird.
Aber Prinzipiell ist die Nutzung eines Listeners/Observers möglich aber nicht notwendig, wenn der Tisch ohnehin die Stühle kennt, kann auch direkt in der Klasse Stuhl eine Methode angeboten werden, mit der sich der Tisch am Stuhl bekannt macht.

Hallöle,

@cmrudolph
Vielen Dank für die Erklärung. :slight_smile:

[QUOTE=_Michael;107089]Wohl nicht direkt ActionListener, da dies ein existierendes Interface ist, das für GUI Kompontenten genutzt wird.
Aber Prinzipiell ist die Nutzung eines Listeners/Observers möglich aber nicht notwendig, wenn der Tisch ohnehin die Stühle kennt, kann auch direkt in der Klasse Stuhl eine Methode angeboten werden, mit der sich der Tisch am Stuhl bekannt macht.[/QUOTE]
Okay okay. :slight_smile: Ich arbeite leider ein wenig Anti-GUI, ich bin eher der theoretische Mensch, der alles mit println versucht zu regeln, ohne groß was graphisch zu erzeugen.

Wenn ich irgendwann mit dem Zeuchs fertig bin und das Spiel läuft, werde ich mich mal nach einer seriösen Spielebibliothek umsehen und mal schauen, was sich machen lässt mit ner graphischen Oberfläche.

Habe gerade auch nicht viel Zeit dafür. Nachdem ich gestern noch meine Methode Arbeit.putzen(schuhe); aufrufen musste, ist das Wochenende nun auch erst einmal arbeitsam.

Ich schaue mich nächste Woche einmal um, wie ich, nachdem nun die Stühle und Tische generiert habe das ganze zusammenbauen und Relationen dazwischen herstellen kann.
Bzw. wie ich sowas wie addStuhl da jetzt aufrufe.:smiley:

Ich wünsche allen einen Fabulösen Nikolaus und ein fesches Wochenende.

Gruß
Lukas

PS: Ich habe meinen aktuellen Entwicklungsstand, ich nenne ihn gemäß meiner Durchnummerierung einfach 1.6.3 auf GitHub hochgeladen, falls sich jemand den aktuellen Stand ansehen möchte. :slight_smile:

Hallöle Leute,

ich habe mal weiter daran gearbeitet.
Meine Methide spielfeldgenerieren sah bis dato so aus:

		 for(int n=0;n<12;n++) {
			 tische.add(new Tisch(laenderkarten.get(n)));
		 }
		 for(int n=0;n<24;n++) {
			 stuehle.add(new Stuhl(null));
		 }
		 System.out.println(stuehle);
		 System.out.println(tische);
	 }```

Nun möchte ich den Tischen Stühle hinzufügen.
Beispielsweise füge ich Tisch 0 die Stühle 1, 2, 3 und 4 hinzu.
```tische.get(0).addStuhl(new Stuhl(null));```
Ich gette mir den ersten Tisch aus der Liste und führe addStuhl mit einem neuen Stuhl hinzu. Als Attribut steht jetzt einfach mal 0 drin, der Stuhl ist doch auch leer. (Oder sollte ich das anders machen)

Das müsste ich jetzt für alle Tische machen, ein mathematisches Modell, wie man das kürzestmöglich generiert ist mir nicht bekannt, was kürzer ist als 12 Einfügezeilen für jeden Tisch.

Nun würde ich aber gerne einmal von euch wissen, wie ich das automatatisch auch andersherum zuweise.
Habe im letzten Beitrag mein Projekt auf GitHub gepostet.
Aber nochmal, so sieht meine Stuhlklasse aus:
```package spiel;

public class Stuhl {
	   
    private Gastkarte gast;
    public Tisch tisch;
   
    public Stuhl(Gastkarte gast) {
    	this.gast = gast;
    }
    
    public void addToTisch(Tisch tisch){
        this.tisch = tisch;
    }
    
    public String toString(){
	     return gast + "";
	}
   
    public void addGast(Gastkarte gast){
        if(this.gast == null){
            this.gast = gast;
        } else {
            System.err.println("Der Stuhl ist bereits belegt!");
        }
    }
 
}```

Mit `addGast` füge ich später den Gast hinzu. Mich interessiert nun `addToTisch`.
Ich würde das jetzt so machen:
```stuehle.get(3).addToTisch(tische.get(5));```
Einfaches Beispiel, ich nehme mir Stuhl drei und füge ihn an Tisch 5 an. Ist das so korrekt, wie ich das gemacht habe?

Und hat jemand einen Ansatz, wie ich dem Programm letzteres nicht auch automatisch bei addStuhl mitteilen könnte?

Schöne Grüße
Lukas

Hast du dir mal auf Papier aufgezeichnet, welche Tische welche Stühle nachher haben sollen?

Ich würde übrigens nicht jedem Tisch einen neuen Stuhl hinzufügen. Wie willst du dann Stühle mehrfach hinzufügen?

Generiere dir z.B. 2 Listen, mit Tischen und Stühlen. Jetzt kann du z.B. überlegen, dass du Stuhl mit der ID 1 an Tisch mit ID 5 und 6 setzen willst. Oder du gehst die Liste mit den Tischen durch. Aber ich denke ganz simpel wird die Zuordnung nicht werden.

public void combine(Stuhl stuhl1, List tische) {
für jeden Tisch in der Liste
{
stuhl1.addToTisch(…)
tisch.addStuhl(stuhl1)
}

[quote=FranzFerdinand]Einfaches Beispiel, ich nehme mir Stuhl drei und füge ihn an Tisch 5 an. Ist das so korrekt, wie ich das gemacht habe?[/quote]ja.

[quote=FranzFerdinand;107307]Und hat jemand einen Ansatz, wie ich dem Programm letzteres nicht auch automatisch bei addStuhl mitteilen könnte?[/quote]ja.
Gib dem Konstruktor des Stuhles eine VarArg-Parameter:public Stuhl(Tisch... tische){ this.tische=tische;}
Der Parameter GastKarte im Stuhl-Konstruktor sollte verschwinden, weil Du (vermutlich) nie eine Gastkarke hast, wenn Du einen Stuhl erstellst.

Die Anwendung wäre dann so:// nach dem erstellen der Tische: stuehle.add(new Stuhl(tische.get(3)); // Stuhl an nur einem Tisch stuehle.add(new Stuhl(tische.get(3),tische.get(4)); // Stuhl an zwei Tischen stuehle.add(new Stuhl(tische.get(3),tische.get(4),tische.get(5)); // Stuhl an drei Tischen
bye
TT

*** Edit ***

[quote=timbeau;107309]Wie willst du dann Stühle mehrfach hinzufügen?[/quote]Das muss er sogar.

bye
TT

man vergleich lang verklungene Worte

[quote=SlaterB]aktuell wäre ein vermeintlich simpler aber dann doch günstiger Anfang, auf beliebige Weise einfach nur 12 Tische zu erzeugen,
sie ordentlich irgendwo ablegen (falls nicht EINE Enum, dann durchaus irgendwo EINE Liste)
[…]
danach für den Rest aller Zeiten darauf aufpassen, das keine neunmalkluge Stuhl-Klasse oder sonstiger Code auf einmal noch neue Tische erzeugt[/quote]
mit aktuell

     for(int n=0;n<24;n++) {
                 stuehle.add(new Stuhl(null));
     } // 24 Stühle fertig

[..]
    tische.get(0).addStuhl(new Stuhl(null)); // noch mehr Stühle??

gegen die zwölf Aufrufe ist in der Tat nix zu machen, außer sie direkt bei 12 Tisch-Konstruktoren oder Enum-Aufrufen zu schreiben,
aber fast dasselbe,
oder die benötigte Information in einer Liste/ Array abzulegen, im manchen Fällen gar berechnen zu lassen, aber dafür hier zu wenig

verwende doch 12 Aufrufe a la
add(0, 2, 3, 4, -1) // erster Parameter Tisch 0, Rest bis zu 4 Stühle Varargs oder wenn ein Parameter >= 0

allgemeine Methode add(int,int,int,int,int),
die macht daraus
add(0, 2)
add(0, 3)
add(0, 4)
// nix für -1

und noch eine allgemeine Methode add(int,int),
die Tisch 0 aus der Liste holt sowie Tisch 2 und bei beiden Objekten add-Methoden aufruft

ein Stuhl kann auch mehreren Tischen zugeordnet sein, oder?

[edit: die verschiedensten Vorschläge schon wieder im Minutentakt, wobei alles auch schon früher genannt wechselseitig, such dir was aus :wink: ]

Das geht auch ohne explizite Aufzählung der Zuweisungen:

    tische = new ArrayList<>(12);
    for (int i = 0; i < 12; i++) {
        tische.add(new Tisch());
    }

    stuehle = new ArrayList<>(24);
    for (int i = 0; i< 12; i++) {
        Tisch tisch = tische.get(i);
        Tisch naechsterTisch = tische.get((i + 1) % 12);
        Tisch letzterTisch = tische.get((i + 11) % 12);
        if (i % 3 == 0) {
            // aeussere Ecke, Stuhl an nur einem Tisch
            Stuhl stuhl1 = new Stuhl(tisch);
            tisch.addStuhl(stuhl1);
            stuehle.add(stuhl);
            
            // innere Ecke, Stuhl an 3 Tischen
            Stuhl stuhl2 = new Stuhl(tisch, naechsterTisch, letzterTisch);
            tisch.addStuhl(stuhl2);
            naechsterTisch.addStuhl(stuhl2);
            letzterTisch.addStuhl(stuhl2);
            stuehle.add(stuhl2);
        } else {
            // Normaler Stuhl, steht zwischen zwei Tischen
            Stuhl stuhl1 = new Stuhl(tisch, letzterTisch);
            tisch.addStuhl(stuhl1);
            letzterTisch.addStuhl(stuhl1);
            stuehle.add(stuhl1);
            
            // Normaler Stuhl, steht zwischen zwei Tischen
            Stuhl stuhl2 = new Stuhl(tisch, naechsterTisch);
            tisch.addStuhl(stuhl2);
            naechsterTisch.addStuhl(stuhl2);
            stuehle.add(stuhl2);
        }
    }
}```

Falls ich mich jetzt nicht vertippt habe, sollte das so klappen. Dabei werden im Uhrzeigersinn Tische und Stühle aufgestellt. An jeden Tisch werden zwei Stühle gestellt. Die Ecktische bekommen eine Sonderbehandlung, weil dort ein Stuhl mit 3 Tischen und ein Stuhl mit nur einem Tisch ist. Ansonsten wird jeweils ein Stuhl zwischen den nachfolgenden und den vorhergegangenen Tisch gestellt.

Vorsicht beim Kopieren:

[quote=cmrudolph]// Normaler Stuhl, steht zwischen zwei Tischen
Stuhl stuhl2 = new Stuhl(tisch, letzterTisch);
tisch.addStuhl(stuhl2);
naechsterTisch.addStuhl(stuhl2);[/quote]

dieselbe Information an zwei Stellen, selbst direkt hintereinander, abzubilden ist ja auch allgemein unschön,
verkürzte Haupt-Schleife geht evtl. so:

            Tisch tisch = tische.get(i);
            Tisch naechsterTisch = tische.get((i + 1) % 12);
            Tisch letzterTisch = tische.get((i + 11) % 12);
            boolean eck = i % 3 == 0;
            // normal Stuhl zwischen zwei Tischen, bei Eck einzeln außen
            newStuhl(tisch, (eck ? null : letzterTisch), null);
               
            // normal Stuhl, zwischen zwei Tischen, bei Eck innen bei dreien
            newStuhl(tisch, naechsterTisch, (eck ? letzterTisch : null));
        }

mit längerer Sub-Methode:
newStuhl {
  // Stuhl anlegen, in Liste einfügen (nur eine Codestelle!)
  // für jeden Tisch-Parameter != null, idealerweise Schleife über Varargs:
     // beidseitiges hinzufügen
}

[quote=SlaterB]verkürzte Haupt-Schleife geht evtl. so:[/quote]bitte gib mir das if wieder und lass die nulls weg!
bye
TT