Café International Theoriensammlung

Hallöle,

mir geht es heute nicht darum hier irgendwo Code zu erhaschen, sondern einfach einmal darum, ob jemand Ideen und Ansätze hätte, wie man rein logisch folgendes Problem in meiner Projektlogik lösen könnte. Deshalb poste ich mal im Hausaufgaben-Forum.

Also, ich programmiere am Spiel café International am Java. Um sich das besser vorstellen zu können, hier einmal ein Bildschirmfoto der Benutzeroberfläche in der iPad App.

Es gibt 24 Länderkarten, die jeweils ein bestimmtes Land anzeigen. Und 100 Gastkarten mit Gästen, die jeweils ein Geschlecht und eine Nationalität besitzen.

Nun hat jeder Spieler immer 5 Gastkarten auf der Hand und darf pro Runde 2 Karten ins Spielfeld legen.
im Spielfeld existieren 12 Tische, die einem Land angehören, also da liegt eine Länderkarte. An jedem Ländertisch stehen Stühle dran. Da dürfen Gäste sitzen, die dem jeweiligen Land angehören. Wie man sehen kann, gibt es Stühle, die entweder einem Tisch, zwei Tischen oder drei Tischen angehören.
Der Spieler legt nun eine Karte auf einen Stuhl, der zu mindestens einem Tisch gehört, der seinem Land entspricht.
Dabei gelten noch folgende zwei Bedingungen:

  1. Er darf nicht allein sein, also er muss egal wo er sitzt an mindestens einem Tisch einen Unterhaltungspartner haben.
  2. Es darf kein Geschlecht den Tisch regieren. Also es müssen immer eine Frau und ein Mann oder 2 Frauen und 2 Männer dran sitzen. Einer mehr, wie 2 Männer und eine Frau ist noch möglich. Verboten wäre also 3 Frauen, ein Mann oder 2 Männer und sonst nichts. :wink:

Wenn ich einen Gast an einen Tisch setze müssen immer alle Bedingungen für alle Tische an denen der Stuhl steht eingehalten werden, sonst lehnt das Spiel den Spielzug ab.
Wenn ein Tisch voll ist, also 4 Gäste dran sitzen, gehen alle Gäste nach Hause und der Tisch bekommt eine neue Länderkarte aus dem Länderkartenstapel zugeordnet.

Ich hoffe die Logik ist soweit verstanden worden.

Meine Frage gilt nun der logischen Umsetzung, wie man das bewerkstelligen kann.
Also da hängt schon einiges zusammen.

  1. Einerseits muss jeder Tisch immer genau wissen:
    a) Welches Land bin ich?
    b) Wer sitzt eigentlich bei mir dran? Sind wir schon zu viert? Von welchem Geschlecht sind meine Gäste? Kann der Mann da jetzt dazu, ohne eine Männeroberhand zu generieren?
  2. Andererseits muss jeder Stuhl genau wissen, zu welchem Tisch er gehört, sodass bei Belegung eines Stuhls immer sofort alle Tische wissen, aha, da kommt was, lass uns mal überprüfen, ob wir die Karte nehmen würden.
  3. Großes Manko auch noch: Wenn ich einen Tisch durch 4 Gäste leer Räume, dann gehen die Gäste wie gesagt nach Hause. Dann müssen die Nachbartische aber auch mitbekommen, dass Gäste, die auch zu ihrem Tisch gehört haben nicht mehr vorhanden sind.

Das ist jetzt mein großes Logikproblem. Ich würde mich freuen, wenn ihr ein paar Ideen und Ansätze habt, wie man das rein logisch umsetzen könnte. Das muss jetzt kein großer Codeschnipsel sein, ich möchte einfach mal wissen, was ihr so für Ideen hättet.

===============
Voraussetzungen:
Ich habe eine Klasse Gastkarte, in welcher ich in enums die Eigenschaften Geschlecht und Land vereint habe.

	   public static enum Geschlecht {Mann, Frau};
	   public static enum Land {Deutscher, Franzake, Brite, Amerikaner, Tuerke, Inder, Chinese, Russe, Spanier, Kubaner, Afrikaner, Italiener, Joker};
	 
	   public final Land land;
	   public final Geschlecht geschlecht;
	 
	   public Gastkarte(Geschlecht geschlecht, Land land){
	      this.land = land;
	      this.geschlecht= geschlecht;
	   }
	 
	   public String toString(){
	     return land + ":" + geschlecht;
	   }
	}```

Generiert werden Gastkarten dann immer mit:
```gastkarten.add(new Gastkarte(geschlecht, land));```
Es liegt dann also immer eine Karte im Format `deutscher:weiblich` vor.
Bei den Ländertischkarten steht da einfach nur das Land: `deutscher`

Es existieren außerdem diese beiden Listen, die mit diesen Eigenschaften bereits befüllt wurden:
```protected static List<Gastkarte> gastkarten = new ArrayList<Gastkarte>();
  protected static List<Laenderkarte> laenderkarten = new ArrayList<Laenderkarte>();```

Ich würde mich über kleine Ideen und Denkanstöße freuen, wie ich das rein logisch regeln könnte.

Gruß
Lukas

Das ist alles relativ einfach von der “Tisch” Sicht.

Jeder Tisch hat 4 Plätze für Karten/Gäste. Diese Karten bekommt er extern zugewiesen, sprich der Gast setzt sich (bzw. der Spieler legt die Karte)
Der Tisch kann nun verschiedene Vergleiche anstellen.
Ist noch Platz? Einfach eine List mit den Karten die bereits gelegt sind speichern. Länge >= 4 bedeutet, kein Platz
Gast-Nationalität == Tisch
Ist die Differenz zwischen Mann und Frau aktuell = 0?
Andernfalls, ist die Differenz zwischen Mann und Frau nach ablegen der Karte < 2?

usw.

Das Problem des Leerräumens kannst du lösen, indem jede Gastkarte sich die Tische merkt an denen sie sitzt. Wird sie an einem Tisch aufgefordert zu gehen, kann sie die Liste mit den Tischen durchgehen und jeden Tisch informieren, dass sie nun weg ist. Der Tisch bietet also eine Methode an und löscht daraufhin die Karte aus seiner Gästeliste.

Ich würde eine Bidirektionale Beziehung Tisch <> Stuhl herstellen. Eine Nummerierung ist sicherlich sinnvoll, wobei für die Programmlogik nicht zwingend. Aber damit wird vieles einfacher.

Bzgl zähler hast du eine Methode der Klasse Tisch

...```

Der Tisch merkt sich ja eh seine Karten. Er kann also z.B. alle seine Karten durchgehen und gucken.

Mögliche Kombinationen:
m  w
0  1
0  0
1  0
2  1
2  2
1  2

Da kann man z.B. 2 counter nehmen oder man speichert die Anzahl an m und w eben.

Start: m= 0 und w = 0. 

Abfrage: if(|m-w| = 0) bedeutet es sind gleichviele am Tisch. 
Lege Karte ab und inkrementiere das passende Geschlecht (z.B. m)

Meine Lösung (ohne GUI) hat 309 Zeile Code in 7 Klassen. (2xEnum, 1x ListenerInterface, 4 FachKlassen: Tisch, Gast, Stuhl und Spiel)

Die Tische halten ihr Land und eine Map mit zwei Gäste-Listen, je Geschlecht eine.
Außerdem halten sie eine Liste von Listenern, die benachrichtigt werden, wenn der Tisch voll ist und die Gästeliste geleert wird.
Der Tisch kann gefragt werden, ob er zu einem Land gehört und ob er noch Platz für ein Geschlecht hat.

Die Stühle halten ihren Gast und eine Liste aller Tische an denen sie stehen. Bei den Tischen sind sie als TischVollListener registriert, damit sie wissen, wann der Gast geht. Ich gebe die Stühle nicht direkt an die Tische weiter, weil ich die Registrieung im Konstruktor der Stühle mache und man soll ja aus dem Konstruktor heraus this nicht weitergeben…
Man kann einen Gast auf einen Stuhl setzen. Der Stuhl prüft, ob er schon besetzt ist. Wenn nicht fragt er “seine” Tische, ob sie Platz für das Geschlecht des Gastes haben und einer dem Land des Gastes angehört. Wenn die Bedingungen erfüllt sind merkt er sich seinen Gast und gibt auch den Tischen den neuen Gast weiter.
Der Stuhl meldet zurück, ob er Gast sich setzten durfte oder nicht.

Die Gäste sind nur DTOs und haben lediglich eine toString() Methode und Getter für Land und Geschlecht.

Die Spiel-Klasse erzeugt Tische, Stühle und Gäste und stellt die Stühle an die Tische. Die Zuordnung der Stühle zu den Tischen hinzubekommen, ohne das für jeden einzelnen Stuhl hinzuschreiben, war eigentlich das Schwierigste. Hat leider nicht ganz geklappt, aber wenigstens konnte ich diesen Teil auf ein viertel schrumpfen.
Dann arbeitet das Spiel die (gemischte) Liste der Gäste ab und versucht jeden Gast der Reihe nach auf einen Stuhl zu setzen.
Wenn das geklappt hat wird der Gast aus der Liste der Gäste entfernt. Das Spiel ist auch als TischVollListener an allen Tischen registriert (super Beispiel für Wiederverwendung von Code…).
Ist die Liste der Gäste leer oder wurde ein mal durchlaufen ohne das es zu einem TischVollEvent kam ist das Spiel beendet.

Wenn unser junger Freund seine einge Lösung hat kann ich meine ja mal posten…

bye
TT

Hallöle ihr Alle und Danke für eure Antworten!
@timbeau : Meinst Du damit, dass jeder Tisch einen Zähler für Männlich und einen für weiblich hat und überprüft, ob die Differenz zwischen beidem kleiner als 2 ist? Und um zu überprüfen, ob das ganze vier erreicht hat, reicht ja eine einfache Addition der beiden.

Wenn das so ist, wie Du das meinst, dann entspricht das so ziemlich dem, was ich auch so vor hatte. :wink:
Deine Liste ist auch soweit korrekt

[QUOTE=timbeau]Mögliche Kombinationen:
m w
0 1
0 0
1 0
2 1
2 2
1 2[/QUOTE]

Was das hier angeht:
if(|m-w| == 0)
Gibt es in Java Betragsstriche? Damit hätte ich jetzt ehrlich nicht gerechnet, praktisch, danke für diese Nebeninfo. :wink:

@Thimothy_Truckle: Oh, 309 Zeilen Code in 7 Klassen. Dass man sich hier so viel Mühe macht. Ich sagte doch, ich bin nur auf Ideen und Ansätze aus, ganzen Code möchte ich gar nicht, ihr braucht euch doch nicht so viel Aufwand zu machen. :wink:
Wenn ich in gegebener Zeit irgendwann damit fertig bin, würde mich Deine Idee interessieren, aber jetzt erstmal irrelevant. Ich hab ja auch nur das nötigste meines Codes gepostet, ich glaube die sind ja auch nicht groß kompatibel. :wink:

Wie dem auch sei:

  1. Ich verstehe das mit der Map noch nicht so ganz. Heißt das, das sind irgendwie 2 Listen wo die 50 Männer und die 50 Frauen drin sind

  2. Listener sind ein interessanter Ansatz. Habe mich außer den ActionEvents beim klicken von jButtons nie damit befasst und bin mir dem bewusst, sie in diesem Zwecke endlich mal zu benötigen. Da muss ich mich erstmal belesen zu. Ich hab ja noch bis Oktober Zeit und mehr Wissen zu Java schadet ja nicht.

  3. Du sagtest ohne GUI. Darf ich mal kurz nachfragen? Hast Du da jetzt nur die Logik programmiert oder auch die Ereignisse, wo der User die Karten dann direkt über irgendetwas GUIähnliches verschieben kann?
    Die GUI ist aktuell mein größtes Problem. Ich bin was sowas angeht überhaupt nicht kreativ, das sieht dann immer wild zusammengemixt aus. Aktuell programmiere ich das gesamte Projekt mit einem Eingabefeld (jTextfield) und Ausgabe via System.out.println(); Alles ohne große Grafik, so richtig DOSmäßig gibt der User alles ein.
    gastkarte:4:tisch3 schiebt zum Beispiel eine Gastkarte, um genau zu sein die 4. von den 5, die der User auf der Hand hat auf Tisch 3.
    Wenn ich diese Logik endlich fertig habe, wollte ich mich um ne GUI kümmern. Das primitivstmögliche ist ein Canvas, aber das kommt mir ziemlich albern vor. Vielleicht schau ich mich noch nach einer Spielebibliothek um. Aber das soll nun nicht Thema des Topics hier sein.

Die Stühle halten ihren Gast und eine Liste aller Tische an denen sie stehen.

So hatte ich das auch gedacht. Jeder dieser 24 Stühle weiß, wer drauf sitzt und muss wissen, wo er dran sitzt.
Aber wie Du bereits sagtest, das hat ja keine richtige Regelmäßigkeit mit der Stuhl-Tisch-Zuordnung. Ich müsste das eigentlich für jeden Stuhl einzeln machen. Wundert mich, wie Du das „auf ein Viertel reduziert“ hast. Aber ich weiß auch nicht, wie viel bei Dir 100% waren.
4.1) In welchem Typ würdest Du empfehlen abzuspeichern, zu welchen Tischen der Stuhl gehört?
Soll dann jeder Stuhl ne List haben mit {4,7,12} oder sowas?
Oder soll ich ein komplettes Dictionary (Schlüssel, Wert) erstellen, wo dann Stuhl:Tisch drinsteht? {2:1;3:1;4:2;7:2} (beispielsweise) Ach, es gibt so viele Möglichkeiten und ich möchte das einfach nicht unnötig kompliziert machen.

Die Gäste sind nur DTOs und haben lediglich eine toString() Methode und Getter für Land und Geschlecht.

Ähm, dazu hab ich mal eine kurze Frage. Ich hab das mit den Karten etwas obskur gemacht. Ich habe wie erwähnt eine Liste mit den 100 Gastkarten namens gastkarten. Die habe ich von Anfang an geshufflet und die bleibt bis zum Ende in der Reihenfolge. Ich habe einen Zähler dabei, bei der wievielten Gastkarte ich bin. Wenn int gastkarte bei 37 steht, dann zieht er sich aus der Liste das 37. Element raus und verarbeitet es. Wie bei nem Romée-Spiel, wo der Zieh-Stapel von Anfang bis Ende des Spiels eine feste Reihenfolge gemischt herumsteht.
Und nun die Frage dazu: Wenn ich jetzt diese feste Reihenfolge habe. Ich hab dann immer, wenn ich die Karte brauche den gesamten String deutscher:männlich kopiert. Wäre es an der Stelle nicht klüger, nur die Listennummer zu übernehmen, damit ich bei Bedarf die Liste fragen kann, was denn bei Element 37 so ist? Was meint ihr dazu.

  1. Zum Spielende: Das Spielende hab ich sogar schon programmiert. Banalerweise hab ich den Anfang und das Ende des Spiels fertig, nur die Logik innen drin fehlt eben.
    Das Spiel endet nach einer von drei Bedingungen:
    A) Alle 100 Gastkarten sind aufgebraucht
    B) Alle 24 Tischkarten sind aufgebraucht.
    C) Alle 21 Barplätze sind belegt. Auf dem Bild vom Anfang sieht man oben Links 21 Plätze. Wenn ein Spieler nämlich keine Karte legen kann, muss er Gäste an die Bar „abschieben“. Wenn die 21 Barplätze voll sind, endet das auch.
    Die Bar ist aber nicht weiter relevant für das Spiel, weil die da einfach hingeschoben werden und dann nie wieder von Belang sind. Ist, als wären sie nach Hause gefangen. Nur eben der Zähler int barkarten muss weiter Hochzählen.

Sodele, das war’s eigentlich erstmal. Bin nicht zuhause und schreibe nur vom Tablet. Ich sammle erst einmal Ideen, danke an alle die bisher mitgemacht haben. Wenn ich wieder am Rechner bin, bemühe ich mich um erste Codeideen.

Schöne Grüße
Lukas

Ich weiß das ist alles recht neu für Dich, aber wenn Du mit dem Projekt vernünftig vorankommen willst, ist es langsam an der Zeit sich mit Objekten zu beschäftigen.
Zu 4.1) und 5)
Versuche solche Indizes zu meiden, die halten Dich davon ab mit Objekten zu arbeiten. Man kann das komplette Spiel programmieren ohne sowas wie „int gastkarte“ zum Speichern der Listenposition oder int tisch, stuhl usw. zu verwenden. Die Liste mit Gästen kannst Du am Anfang mischen und dann ziehst Du bzw.die Spieler immer den ersten Gast der Liste, der dabei aus der Liste entfernt wird - wie beim echten Ziehen von Karten aus einem Stapel oder der Kärtchen aus dem Beutel. Ein Gast/ eine Gastkarte, die gezogen ist erfüllt in der Liste keinen Zweck mehr.
Die einzige Stelle wo ich so einen Zählindex evtl. nutzen würde ist bei der Bar, um mir z.B. zu merken welches der nächste freie Platz ist.

[quote=FranzFerdinand]In welchem Typ würdest Du empfehlen abzuspeichern, zu welchen Tischen der Stuhl gehört?
Soll dann jeder Stuhl ne List haben mit {4,7,12} oder sowas?[/quote]
Ja eine Liste, aber nicht mit Indizes sondern mit Referenzen auf Objekte vom Typ Tisch ==> OOP

Beides ist Schmarrn. Denke objektorientiert, übergebe eine Referenz auf die Karte, dann müsst Du keinen String kopieren (um daraus womöglich wieder eine Karte zu erstellen) oder einen Index, um dann jedesmal auf eine Liste zurückzugreifen, wenn Informationen der Karte benötigt.
Definiere für jedes relevante Objekt im Spiel eine eigene Klasse: Gast(karte), Stuhl, Tisch, Cafe. Wie Timothy_Truckle bereits erwähnt. Die Klasse Gast(karte) mit den Attributen Nationalität und Geschlecht hast Du ja bereits.
Ein Stuhl sollte seinen „Besetzer“ kennen und die Tische an denen er steht, dazu noch ein paar Methoden anbieten z.B. damit ein Gast gesetzt werden kann usw.

    Gastkarte gast; //null, wenn leer, sonst Referenz auf den Gast, der auf dem Stuhl sitzt
    List<Tisch> tische = new ArrayList<Tisch>(); // Liste mit den Tischen an denen der Stuhl steht.
    ...
    public boolean einGastWillSichSetzen(Gastkarte gast) { //liefert true, wenn sich ein Gast setzen konnte, false wenn sich ein Gast nicht setzen darf
        if (frageAlleTischeObGastSichSetzenDarf()) {
            this.gast = gast;
            return true;
        }
        return false;
    }
    ...    
}```
Ein Tisch sollte seine Nationalität kennen (daher würde es Sinn machen das Enum Land ausserhalb der Gastkarte zu deklarieren) und er könnte die Stühle kennen, die an ihm stehen und dazu noch ein paar Methoden anbieten, über die z.B. ein Stuhl anfragen kann, ob sich ein bestimmter Gast setzen darf oder die Punkte berechnet, die ein Spieler erhält, wenn er einen Gast an den Tisch setzt usw.
```public class Tisch {
    Land nationalitaet; // Nationalität des Tisches
    List<Stuhl> stuehle; //Liste der Stühle die an dem Tisch stehen
    // Alternativ kennt der Tisch die Stühle nur indirekt als Listener und dafür direkt die Gäste die an ihm sitzen (vgl. Lösungsentwurf von TT)
    ...
}```
usw.

[quote=FranzFerdinand]Dass man sich hier so viel Mühe macht. Ich sagte doch, ich bin nur auf Ideen und Ansätze aus[/quote]Das Problem hat mich eben interessiert und da hab ich’s mal schnell runterprogrammiert. Aber ich habe 15 Jahre Übung im Programmieren, deshalb sollte das für Dich Ansporn, aber nicht Maßstab sein.

[quote=FranzFerdinand;106780]1) Ich verstehe das mit der Map noch nicht so ganz. Heißt das, das sind irgendwie 2 Listen wo die 50 Männer und die 50 Frauen drin sind[/quote]Nein.
Jeder Tisch hat 2 Listen. Eine in der bis zu 2 Männer und eine in der bis zu 2 Frauen drin sind, so wie @timbeau das vor schlug.
Um ein if zu sparen (ich denke, Du hast hier im Forum schon meine Abneigung dagegen mitbekommen) habe ich die beide Listen des Tisches in eine Map gepackt:Map<Geschlecht,List<Gast>> gaeste;
Wenn der Tisch jetzt prüfen soll, ob für ein Geschlecht jetzt noch ein Platz frei ist muss er gar nicht wissen um welches Geschlecht es sich handelt, denn egal welches Geschlecht sich setzten will, die Liste des selben Geschlechts darf nicht voller sein, als die des Anderen:istAkzeptiert = gaeste.get(geschlecht).size() <= gaeste.get(geschlecht.getAnderes()).size()Dann muss nur noch die (statische) Methode getAnderes() im enum Geschlecht passen implementiert sein.

[quote=FranzFerdinand;106780]2) Listener sind ein interessanter Ansatz. Habe mich außer den ActionEvents beim klicken von jButtons nie damit befasst und bin mir dem bewusst, sie in diesem Zwecke endlich mal zu benötigen. Da muss ich mich erstmal belesen zu. Ich hab ja noch bis Oktober Zeit und mehr Wissen zu Java schadet ja nicht.[/quote]Da ist nichts kompliziertes dabei. Man übergibt dem Verursacher der Ereignisse ein (sehr kleines) Objekt mit sehr wenigen Methoden (üblicher Weise eine einzige) und der Verursacher ruft diese Methode auf, wenn ein Ereignis eintritt.
Da das übergebene Objekt im Kontext des Ererignisverbrauchers erzeugt wird hat es Zugriff auf dessen interne Methoden und Variablen.
Der Witz ist nun, das es dem Erzeuger vollkommen egal ist wer ihm so ein Listener-Objekt übergibt oder was der Listener mit dem Ereignis macht, der Erzeuger ruft ja nur die in einem Interface deklarierte Methode auf…

[quote=FranzFerdinand;106780]3) Du sagtest ohne GUI. Darf ich mal kurz nachfragen? Hast Du da jetzt nur die Logik programmiert oder auch die Ereignisse, wo der User die Karten dann direkt über irgendetwas GUIähnliches verschieben kann?[/quote]Ich habe die Spielelogik und einen primitiven Computerspieler implementiert. Den Spielverlauf kann man auf der Kommandozeile verfolgen, aber nicht eingreifen. Also man sieht, wie das Spiel versucht jeden Gast der Reihe nach auf verschiedene Stühle zu setzen bis ein passender gefunden ist auf den der Gast das gesetzt wird oder alle Stühle durchprobiert sind. Wenn dann ein Tisch voll ist gibt es auch eine entsprechende Ausgabe.
stark gekürzt
[spoiler]

prüfe Gast DEUTSCHER, WEIBLICH auf Stuhl 12
	 [tische=[
		Tisch 7, land=FRANZOSE, gaeste={MAENNLICH=[], WEIBLICH=[]}], 
		Tisch 8, land=NORWEGER, gaeste={MAENNLICH=[], WEIBLICH=[]}]]]
prüfe Gast DEUTSCHER, WEIBLICH auf Stuhl 8
	 [tische=[
		Tisch 4, land=RUSSE, gaeste={MAENNLICH=[], WEIBLICH=[]}], 
		Tisch 5, land=BELGIER, gaeste={MAENNLICH=[], WEIBLICH=[]}], 
		Tisch 6, land=BELGIER, gaeste={MAENNLICH=[], WEIBLICH=[]}]]]
prüfe Gast DEUTSCHER, WEIBLICH auf Stuhl 3
	 [tische=[
		Tisch 2, land=DEUTSCHER, gaeste={MAENNLICH=[], WEIBLICH=[]}], 
		Tisch 3, land=GRIECHE, gaeste={MAENNLICH=[], WEIBLICH=[]}]]]
Gast DEUTSCHER, WEIBLICH 
	neu auf Stuhl 3
	 [tische=[
		Tisch 2, land=DEUTSCHER, gaeste={MAENNLICH=[], WEIBLICH=[]}], 
		Tisch 3, land=GRIECHE, gaeste={MAENNLICH=[], WEIBLICH=[]}]]]
prüfe Gast DEUTSCHER, MAENNLICH auf Stuhl 12
	 [tische=[
		Tisch 7, land=FRANZOSE, gaeste={MAENNLICH=[], WEIBLICH=[]}], 
		Tisch 8, land=NORWEGER, gaeste={MAENNLICH=[], WEIBLICH=[]}]]]
prüfe Gast DEUTSCHER, MAENNLICH auf Stuhl 10
	 [tische=[
		Tisch 6, land=BELGIER, gaeste={MAENNLICH=[], WEIBLICH=[]}], 
		Tisch 7, land=FRANZOSE, gaeste={MAENNLICH=[], WEIBLICH=[]}]]]
prüfe Gast DEUTSCHER, MAENNLICH auf Stuhl 3
         besetzt von Gast DEUTSCHER, WEIBLICH
prüfe Gast DEUTSCHER, MAENNLICH auf Stuhl 2
	 [tische=[
		Tisch 1, land=POLE, gaeste={MAENNLICH=[], WEIBLICH=[]}], 
		Tisch 2, land=DEUTSCHER, gaeste={MAENNLICH=[], WEIBLICH=[Gast DEUTSCHER, WEIBLICH]}], 
		Tisch 3, land=GRIECHE, gaeste={MAENNLICH=[], WEIBLICH=[Gast DEUTSCHER, WEIBLICH]}]]]
Gast DEUTSCHER, MAENNLICH 
	neu auf Stuhl 2
	 [tische=[
		Tisch 1, land=POLE, gaeste={MAENNLICH=[], WEIBLICH=[]}], 
		Tisch 2, land=DEUTSCHER, gaeste={MAENNLICH=[], WEIBLICH=[Gast DEUTSCHER, WEIBLICH]}], 
		Tisch 3, land=GRIECHE, gaeste={MAENNLICH=[], WEIBLICH=[Gast DEUTSCHER, WEIBLICH]}]]]
prüfe Gast TUERKE, MAENNLICH auf Stuhl 12
	 [tische=[
		Tisch 7, land=FRANZOSE, gaeste={MAENNLICH=[], WEIBLICH=[]}], 
		Tisch 8, land=NORWEGER, gaeste={MAENNLICH=[], WEIBLICH=[]}]]]
[...]
prüfe Gast TUERKE, MAENNLICH auf Stuhl 24
	 [tische=[
		Tisch 1, land=POLE, gaeste={MAENNLICH=[Gast DEUTSCHER, MAENNLICH], WEIBLICH=[]}], 
		Tisch 2, land=DEUTSCHER, gaeste={MAENNLICH=[Gast DEUTSCHER, MAENNLICH], WEIBLICH=[Gast DEUTSCHER, WEIBLICH]}]]]
 nicht platziert
prüfe Gast NORWEGER, MAENNLICH auf Stuhl 12
	 [tische=[
		Tisch 7, land=FRANZOSE, gaeste={MAENNLICH=[], WEIBLICH=[]}], 
		Tisch 8, land=NORWEGER, gaeste={MAENNLICH=[], WEIBLICH=[]}]]]
[...]
prüfe Gast GRIECHE, WEIBLICH auf Stuhl 5
	 [tische=[
		Tisch 3, land=GRIECHE, gaeste={MAENNLICH=[Gast DEUTSCHER, MAENNLICH, Gast GRIECHE, MAENNLICH], WEIBLICH=[Gast DEUTSCHER, WEIBLICH]}], 
		Tisch 4, land=RUSSE, gaeste={MAENNLICH=[Gast GRIECHE, MAENNLICH], WEIBLICH=[Gast RUSSE, WEIBLICH]}]]]
Gast GRIECHE, WEIBLICH 
	neu auf Stuhl 5
	 [tische=[
		Tisch 3, land=GRIECHE, gaeste={MAENNLICH=[Gast DEUTSCHER, MAENNLICH, Gast GRIECHE, MAENNLICH], WEIBLICH=[Gast DEUTSCHER, WEIBLICH]}], 
		Tisch 4, land=RUSSE, gaeste={MAENNLICH=[Gast GRIECHE, MAENNLICH], WEIBLICH=[Gast RUSSE, WEIBLICH]}]]]
ist Voll: Tisch 3, land=GRIECHE, gaeste={MAENNLICH=[Gast DEUTSCHER, MAENNLICH, Gast GRIECHE, MAENNLICH], WEIBLICH=[Gast DEUTSCHER, WEIBLICH, Gast GRIECHE, WEIBLICH]}]
  Tisch 3 neues Land: SPANIER
prüfe Gast BELGIER, WEIBLICH auf Stuhl 4
	 [tische=[
		Tisch 3, land=BELGIER, gaeste={MAENNLICH=[], WEIBLICH=[]}], 
		Tisch 4, land=RUSSE, gaeste={MAENNLICH=[Gast GRIECHE, MAENNLICH], WEIBLICH=[Gast RUSSE, WEIBLICH, Gast GRIECHE, WEIBLICH]}]]]
prüfe Gast ITALIENER, WEIBLICH auf Stuhl 24
	 [tische=[
		Tisch 1, land=POLE, gaeste={MAENNLICH=[Gast DEUTSCHER, MAENNLICH, Gast UNGAR, MAENNLICH], WEIBLICH=[Gast UNGAR, WEIBLICH]}], 
		Tisch 2, land=DEUTSCHER, gaeste={MAENNLICH=[Gast DEUTSCHER, MAENNLICH], WEIBLICH=[Gast DEUTSCHER, WEIBLICH]}]]]
 nicht platziert
8 Gäste nicht platziert

[/spoiler]

[quote=FranzFerdinand;106780]Die GUI ist aktuell mein größtes Problem.[/quote]meins auch, außerdem frisst GUI immer 'ne menge Zeit. Mit war die Spielelogik wichtig.

[quote=FranzFerdinand;106780]4) […] Wundert mich, wie Du das “auf ein Viertel reduziert” hast. [/quote] Das ist eben die Kunst beim Programmieren: Finde raus, wo sich Programmteile ähnlich verhalten und finde geeignete Parameter, die die Unterschiede bewirken.
Wenn man sich den Spielplan an sieht fällt dem geübten Auge auf, dass die Tische im Quadrat aufgestellt sind. Und da erinnere ich mich an meinen alten Mathelehrer: Was ist das Besondere an einem Quadrat?

[quote=FranzFerdinand;106780]Aber ich weiß auch nicht, wie viel bei Dir 100% waren.[/quote]Natürlich die 24 Stühle.

[quote=FranzFerdinand;106780]4.1) In welchem Typ würdest Du empfehlen abzuspeichern, zu welchen Tischen der Stuhl gehört?
Soll dann jeder Stuhl ne List haben mit {4,7,12} oder sowas?[/quote]genau dass, aber eben nicht die IDs sondern die Tisch-Objekte selbst.

[quote=FranzFerdinand;106780]Ach, es gibt so viele Möglichkeiten und ich möchte das einfach nicht unnötig kompliziert machen.[/quote]Auch dass zeichnet den guten Programmierer aus, dass er die verschiedenen Lösungewege kennt und mit Blick auf das Ziel bewerten kann. Hier sein nur so viel gesagt: in einer OO-Sprache sollte man in der Geschäftslogik nicht mit ID’s rumhantieren (Schnittstellen oder IO ist was anderes…), Die ID’s brauche ich in meinem Beispiel nur für die “Visualisierung” auf der Kommandozeile.

[quote=FranzFerdinand;106780]5) Wäre es an der Stelle nicht klüger, nur die Listennummer zu übernehmen, damit ich bei Bedarf die Liste fragen kann, was denn bei Element 37 so ist?[/quote]Es wäre an dieser Stelle klüger, das Objekt weiterzugeben (nicht zu kopieren), dann brauchst Du niemanden “fragen”.
Dass ist überhaupt ein Stichwort: Eines der Prinzipien der OOP ist “tell, don’t ask”. Also statt in der SpielKlasse zu schreibenList<Gast> frauen= tisch.getWeiblich(); List<Gast> maenner= tisch.getMaennlich(); if(Geschlecht.MAENNLICH=gast.geschlecht){ if(maenner.size() <= frauen.size()) //... else{ //... }sollte es so sein:if(tisch.istFreiFuer(gast.getGeschlecht())) Und die Logik wird vom Tisch ausgeführt, ohne dass seine Interna, also wie er sich die Anzahl Frauen und Männer merkt, nach außen gegeben wird.

[quote=FranzFerdinand;106780]6) […]C) Alle 21 Barplätze sind belegt[/quote]Die BarPlätze habe ich bersehen, scheint mir aber auch nicht ganz so wichtig.

bye
TT

Wunderschönen Guten Tag,

hm, ich sollte endlich mal Ordnung in meinem GitHub Ordner machen, dann kann ich mal nen Link posten, wo man den aktuellen Inhalt sieht. Sonst muss ich hier immer alle Klassen posten, der Code hat in letzter Zeit ganz schön zugenommen.
Habe vorhin erstmal alles mögliche herausgestrichen, was ich nicht brauche oder unnützer Quatsch ist. Ein seriöser Programmierer würde wahrscheinlich noch 90% des Rests rausstreichen, aber okay…

Also:

Die Liste mit Gästen kannst Du am Anfang mischen und dann ziehst Du bzw.die Spieler immer den ersten Gast der Liste, der dabei aus der Liste entfernt wird - wie beim echten Ziehen von Karten aus einem Stapel oder der Kärtchen aus dem Beutel. Ein Gast/ eine Gastkarte, die gezogen ist erfüllt in der Liste keinen Zweck mehr.
Die einzige Stelle wo ich so einen Zählindex evtl. nutzen würde ist bei der Bar, um mir z.B. zu merken welches der nächste freie Platz ist.

Peinlich… Ich programmiere nicht nur mit Java, sondern beschäftige mich mit ein paar anderen Sprachen noch dazu. In irgendeiner war das so, wenn ich Element 0 lösche, dann rückt das alles nicht nach, sondern dann ist da einfach NULL, also ein leerer Wert drin. Das hatte ich jetzt auf Java übertragen und mich bewusst dagegen entschieden und das mit diesem Zähler gemacht.
Vielen vielen Dank für den Hinweis, das nimmt mir Unmengen unnötige Denkarbeit ab. Ich hab nun immer beim Ziehen einer Karte diesen Nachziehvorgang drin mit anschließendem:
gastkarten.remove(0);

Ansonsten möchte ich jetzt einmal bitte bitte etwas erklärt bekommen.

Ich habe mir jetzt zwei neue Klassen Stuhl und Tisch angelegt.


import java.io.IOException;

public class Tisch extends CafeRoot{
	
	private static final long serialVersionUID = 5316004918115601947L;
	
	public Tisch(String title) throws IOException {
		super(title);
	}

}

import java.io.IOException;

public class Stuhl extends CafeRoot{
	
	private static final long serialVersionUID = -6498029724200529910L;

	public Stuhl(String title) throws IOException {
		super(title);
	}

}

Ich hab da jetzt noch nichts groß reingefüllt, weil ich das nicht so ganz verstehe. Wenn ich das jetzt so machen würde, wie immer und den Umstandsmenschen spielen würde, würde ich da jetzt schreiben:

String tisch1 = laenderkarten.get(1);
String tisch2 = laenderkarten.get(2);
String tisch3 = laenderkarten.get(3);
String tisch4 = laenderkarten.get(4);
String tisch5 = laenderkarten.get(5);
String tisch6 = laenderkarten.get(6);
String tisch7 = laenderkarten.get(7);
String tisch8 = laenderkarten.get(8);
String tisch9 = laenderkarten.get(9);
String tisch10 = laenderkarten.get(10);
String tisch11 = laenderkarten.get(11);
List stuhl1 = {0;3;7};
List stuhl2 = {5;10;11};
List stuhl3 = {2;4;9};
//usw.```

Ich bin mir der Tatsache bewusst, dass der Code so wie er dasteht nicht geht, ich wollte nur schnell und knapp darstellen, nach welchem Schema ich da jetzt fahrlässig arbeiten würde.
Ich verstehe da jetzt ehrlich gesagt nicht, wie ihr das meint, das Pauschal so zu erstellen, dass Java begreift, was Stuhl und was Tisch ist und wo es sich seine Inhalte herklaubt.
Ich möchte auch keine großen Codebeispiele, ich will hier nicht immer den Spielen, der sich Quellcode von anderen erhascht, ich möchte lieber lernen und verstehen, wie das funktioniert.


Am Ende kurze und knappe Frage mal so generell zu ActionListenern:
Gibt es einen ActionListener, der mitbekommt, dass eine Variable ihren Wert verändert hat? Bei mir hängt vieles an diversen Integern und ständig, wenn die sich ändern klatsche ich da so nen Codeblock dran, was der daraus machen soll. Das ist extrem umständlich, wie ich finde.

Hat Java soetwas wie nen ActionListener_intchanged(), der beispielsweise mitkriegt, dass sich `int test` verändert hat?

Schönen Sonntag!
Lukas

Die erste Frage die sich mir stellt: Was ist die Klasse KaffeRootund warum erben Tischund Stuhlvon dieser?
Vererbung drückt immer eine “ist ein” Beziehung aus. “ist ein” Stuhlein (besonderes) CaffeRoot?

[quote=FranzFerdinand]dass Java begreift, was Stuhl und was Tisch ist[/quote]Du hast doch entsprechende Klassen erstellt. Die müssen jetzt eben Methoden bekommen, die für einen Stuhl oder Tisch sinnvoll sind. Wichtig: diese Methoden beziehen sich immer auf einen Stuhl/Tisch. Die Klasse Stuhl/Tisch selbst muss nicht wissen, dass es mehrere Objekte davon geben wird.

[quote=FranzFerdinand;106808]Gibt es einen ActionListener, der mitbekommt, dass eine Variable ihren Wert verändert hat? Bei mir hängt vieles an diversen Integern und ständig, wenn die sich ändern klatsche ich da so nen Codeblock dran, was der daraus machen soll. Das ist extrem umständlich, wie ich finde.[/quote]Das umständliche ist, dass Du mit den ID’s arbeitest. Die primitiven Klassen kennen solche Listener nicht, weil sie immutable sind, also ihren Wert nicht ändern können. Die Klasse, in der Du die ID’s (oder besser gleich die Objekte) hälts können aber zusätzlich eine Liste von Objekte haben, die sich für die Änderungen interessieren.

[quote=FranzFerdinand;106808]Hat Java soetwas wie nen ActionListener_intchanged(), der beispielsweise mitkriegt, dass sich int testverändert hat?[/quote]Nicht direkt. Aber Java hat die Klasse [JAPI]Observable[/JAPI], von der die Klasse erbt, in der die Änderung statt findet (in der dein int test steht) und das Interface [JAPI]Observer[/JAPI], das in der Klasse, die über die Änderung informiert werden will meist als anonyme Klasse implementiert wird.
Ich persönlich finde [JAPI]Observable[/JAPI] nicht praktisch genug und implementiere das bischen, was [JAPI]Observable[/JAPI] an Funktionalität bietet lieber selbst. Der Vorteil, den ich davon habe ist, dass ich ein eigenes Listener Interface habe, und nicht das unspezifische [JAPI]Observer[/JAPI].

bye
TT

[QUOTE=Timothy_Truckle;106809]Die erste Frage die sich mir stellt: Was ist die Klasse KaffeRoot und warum erben Tisch und Stuhl von dieser?
Vererbung drückt immer eine „ist ein“ Beziehung aus. „ist ein“ Stuhl ein (besonderes) CaffeRoot?
[/QUOTE]

Oh, entschuldige, dass hatte ich vergessen zu erwähnen. CafeRoot ist meine Hauptklasse, von welcher aller Ursprung des Bösen ausgeht. Das Extends fügt Eclipse automatisch ein, weil ich in 99,9% der Fälle irgendetwas an Inhalt daraus übernehme und damit daraus Dinge erben möchte.
Mit dem aktuellen Leerinhalt der Klasse noch nicht, also kann das in der Theorie vorerst weg.

Gruß
Lukas

Edit: Ich hab mal alle Inhalte, die bisher existent sind bei GitHub hochgeladen. Aktualisiert sich bei jeder Änderung meinerseits selbst. :wink:

[quote=FranzFerdinand]weil ich in 99,9% der Fälle irgendetwas an Inhalt daraus übernehme[/quote]ok.

[quote=FranzFerdinand;106810]und damit daraus Dinge erben möchte.[/quote]Ääähhm, nein…
Was Du möchtest ist Elemente verschieben: Alt+Umschalt+V

bye
TT

[quote=FranzFerdinand]public class Stuhl {
public final Land land;
public final Geschlecht geschlecht;[/quote]Wieso muss der Stuhl dies Informationen haben? reicht es nicht, dass er weis, dass ein Gast auf ihm sitzt oder nicht?

[quote=FranzFerdinand;106813]Mit new Tisch(land); bzw. new Stuhl(land); kann ich auf jeden Fall neue Elemente generieren.[/quote]Ja.
Aber: im Konstruktor werden dem Objekt vor allem die Abhängigkeiten übergeben, die das Objekt von Anfang an haben muss und die sich (im Normalfall) während der Laufzeit nicht mehr änderen. Beim Tisch ist es also OK, das Land im Konstruktor zu übergeben, weil er immer eins haben muss, auch wenn er später ein anderes bekommt.
Der (leere) Stuhl hat dagegen kein Land.
Dagegen ist die Information, an welchem Tisch der Stuhl steht ist aber so eine, die sich während des Spiels nicht mehr ändert, und die im Konstruktor übergeben werden sollte:new Stuhl(Arrays.asList(tische.get(0))); // äußerer Stuhl an Ecktisch new Stuhl(Arrays.asList(tische.get(0),tische.get(1),tische.get(11))); // innerer Stuhl an Ecktisch und dem jeweils ersten beider der Seiten

hübscher ist es mit eigenen Varargs:
[spoiler]new Stuhl(tische.get(0)); // äußerer Stuhl an Ecktisch new Stuhl(tische.get(0),tische.get(1),tische.get(11)); // innerer Stuhl an Ecktisch und dem jeweils ersten beider der Seiten[/spoiler]

bye
TT

Hallöle und nochmals danke, dass Du Dich dem Problem annahmst,

Ich dachte jetzt eigentlich daran, dass der Stuhl schon weiß, welches Land und welches Geschlecht gerade auf ihm Platz nehmen. Wenn ich da nur sage, ob da was drauf ist, muss ich doch früher oder später noch nen weiteres Element hinzufügen, was dann, wenn gastvorhanden = True; auch noch weiß, was da vorhanden ist.
Oder mache ich das zu umständlich?
Also das ist erstmal der Grund, wieso ich das so gemacht habe. Ich lasse mich immer eines besseren belehren.

Aber: im Konstruktor werden dem Objekt vor allem die Abhängigkeiten übergeben, die das Objekt von Anfang an haben muss und die sich (im Normalfall) während der Laufzeit nicht mehr änderen. Beim Tisch ist es also OK, das Land im Konstruktor zu übergeben, weil er immer eins haben muss, auch wenn er später ein anderes bekommt.
Der (leere) Stuhl hat dagegen kein Land.
Dagegen ist die Information, an welchem Tisch der Stuhl steht ist aber so eine, die sich während des Spiels nicht mehr ändert, und die im Konstruktor übergeben werden sollte:

Damit hast Du absolut link. Der Tisch ist mir jetzt nicht so schwer gefallen, aber bei mir hacken die Hirnsynapsen immer noch auf diesem Stuhl herum, wie ich das Quellcodemäßig umsetzen soll. Siehe das Problem da oben. Aber ja, Land und Geschlecht ändern sich ständig. Und die Tische, wo er dran sitzt sind endgültig. Die müsste ich dann, wie Du erkannt hast auf Ewig so definieren.

new Stuhl(tische.get(0),tische.get(1),tische.get(11)); // innerer Stuhl an Ecktisch und dem jeweils ersten beider der Seiten```
Vielen Dank für den Vorschlag. Ich schaue das morgen einmal genauer an.
Das fügt den jetzt zu den Tischen 0, 1 und 11 hinzu? Dazu muss ich aber erstmal noch meine Stuhl-Klasse umschreiben, dass er den Quellcode so nimmt. Ich nehme an, bei Dir ist die Klasse in Deiner Schattenlösung schon dementsprechend umprogrammiert.

Das schaue ich mir mal morgen an.

Eine Sache muss ich aber noch generell machen. Mein Benutzername FranzFerdinand war nicht immer selbiger. Hab mich früher oft "DieMathematik" genannt. Ich muss diesem Namen gerecht werden und mir endlich eine mathematische Lösung überlegen, wie ich die Stuhl- und Tischnummern seriös verteile, um den optimalstmöglichen Quelltext zusammenzumixen. Fest steht für mich erst einmal nur, dass die Tische einfach in einem Ring 0 bis 11 sind. Deinem Quelltext zu Folge sind die Beiden Stühle der eine Einzelstuhl oben und der dem gegenüberstehende, wenn man ganz oben mit 0 anfängt zu zählen, gelle?


Schönen Sonntag!

Gruß
Lukas

[quote=FranzFerdinand]Wenn ich da nur sage, ob da was drauf ist, muss ich doch früher oder später noch nen weiteres Element hinzufügen, was dann, wenn gastvorhanden = True; auch noch weiß, was da vorhanden ist.[/quote]Ja, aber nicht zusätzlich, sondern statt dessen. Dem Stuhl ist es vollkommen egal, was da auf ihm sitzt. Nur beim Versuch sich hinzusetzten muss er das wissen, damit er seine Tische entsprechend befragen kann.

[quote=FranzFerdinand;106817]Fest steht für mich erst einmal nur, dass die Tische einfach in einem Ring 0 bis 11 sind.[/quote] Die Frage ist: muss man den Ring wirklich programmieren (da hat Java noch keine fertige Klasse) oder kann man die Tische einfach in einer normalen Liste halten und rein virtuell als Ring betrachten? Genauer: ist die Abbildung als geschlossener Ring für die Implementierung des Algorythmus notwending oder ehr hinderlich? Was wären die Vor- und Nachteile bezogen auf unser Ziel?

genau.

kleiner Trick am Rande: wenn unsere Liste ein (virtueller) Ring ist, kann man das ja auch mit einem Kreis vergleichen. Und was ist das Kennzeichen eines Kreises? Er ist **überall **rund, auch an den Ecken.
Wer sagt also, dass unsere Liste mit einem Ecktisch beginnen muss?
Und welchen Vorteil bringt es für unser Codeschnipsel, wenn statt dessen der zweite Tisch in der Liste (Tisch 1) der Ecktisch ist, vor allem wenn man daran denkt, dass man diese Zuordnung verallgemeinern will? Jemand, der „DieMathematik“ als Nick hat sollte das ja schnell raus bekommen…

bye
TT

Najanaja, um die Zeit denke ich auch nicht mehr groß Mathematisch.
Tatsache ist jedoch, dass mir die Kreissache eigentlich wumpe ist, sind eben 12 Tische in einem Kreis, die alle 4 Stühle um sich herum haben.
Wenn ich da jetzt einen riesigen Mathematischen Algorithmus drum herum baue, macht das keinen Sinn, ich ordne jeden Stuhl einzeln zu. :smiley:

Gruß
Lukas

[quote=FranzFerdinand]Wenn ich da jetzt einen riesigen Mathematischen Algorithmus drum herum baue, macht das keinen Sinn, ich ordne jeden Stuhl einzeln zu.[/quote]395% Tipperei, aber bitte, sind ja Deine Hausaufgaben… ;o)

bye
TT

Da gibts nichts regelmäßig, was den Quellcode essentiell kürzen könnte.
Mich würde erstmal generell interessieren, wie ich das mache,
Das probiere ich morgen mal aus.
Ansonsten kann ich mich auch noch später mit dem mathematischen Problem auseinandersetzen. :wink:

Wie wäre es in der Stuhl-Klasse einfach ein Gast-Feld zu erstellen. Diese wird von außen befüllt und prüft ob der ankommende Gast sich überhaupt setzen darf. D.h. der Stuhl kann die Informationen des Gastes an den Tisch weiterreichen. Der Tisch sagt anhand seiner Informationen “ja” oder “nein”.

Ein interessanter Ansatz, danke, aber ich verstehe das immer noch nicht so recht, wie das gemeint ist, dieses Gastfeld.
Ist das jetzt wie schon mal vorgeschlagen nur ein Feld, was sagt Gast vorhanden Ja oder Nein, also ob da schon jemand sitzt oder sollen da jetzt die vollen Infos mit Land und Geschlecht abgespeichert werden?

Gruß
Lukas

Damit ist gemeint, dass die Klasse Stuhl eine Instanzvariable besitzt, die auf einen Gast referenziert bzw. referenzieren kann.
z.B. wie von mir gepostet:

[quote=_Michael;106790]public class Stuhl { Gastkarte gast; //null, wenn leer, sonst Referenz auf den Gast, der auf dem Stuhl sitzt ...
[/quote]