# Labyrinth über MazeGameServer visualisieren



## jono (17. Aug 2020)

Es wird empfohlen mit der Komponente GameStatusModel zu beginnen. Die Aufgabe der Klassen der Komponente GameStatusModel ist es, den vollständigen Spielstatus(Maze, baits, score, players) zu enthalten und andere Komponenten wie die MazeClientUI über Änderungen zu benachrichtigen. Wie gehe ich da jetzt vor, kann mir da jemand Hilfe beim Ansatz geben, wie ich anfangen kann. 
Zuerst möchte ich jetzt ein UML für die Klassen der GameStatusModel-Komponente erstellen. Ich weiß, dass mehrere Klassen notwendig sind, aber warum ist das nicht mit einer Klasse zu händeln?
Attribute wären ja schonmal coffee,gem,...(In der exam-task.pdf). Aber wie weiter...? Wäre sehr dankbar für ein paar gute Hilfen !


----------



## LimDul (17. Aug 2020)

Warum nicht mit einer Klasse? Kannst du dann in einem Satz die Klasse vollständig beschreiben was ihre Verantwortung ist? Schau dir in der exam-task mal das Kapitel 6 an, was es alles an Informationen gibt. Diese kannst du nicht einer Klasse abbilden. Der Spieler z.B. wird irgendwo eine Position haben. Die Baits müssen gespeichert werden. Wie soll deine Klasse dann aussehen? Zig Listen zu den unterschiedlichen Daten mit einfachen Datentypen? Das ist nicht sinnvoll. Es ist meist sinnvoller lieber mehr als weniger Klassen zu haben. Du hast es schon selber geschrieben " (Maze, baits, score, players)". Da hast du schon einige Dinge identifiziert. Das werden mit Sicherheit alles eigene Klassen werden (außer vielleicht Score, was ggf. eine Eigenschaft des Spielers ist).


----------



## MoxxiManagarm (17. Aug 2020)

jono hat gesagt.:


> und andere Komponenten wie die MazeClientUI über Änderungen zu benachrichtigen. Wie gehe ich da jetzt vor, kann mir da jemand Hilfe beim Ansatz geben, wie ich anfangen kann.











						The Observer Pattern in Java | Baeldung
					

Learn a few ways to implement the Observer design pattern in Java




					www.baeldung.com
				






jono hat gesagt.:


> Ich weiß, dass mehrere Klassen notwendig sind, aber warum ist das nicht mit einer Klasse zu händeln?


Du kannst viel in einer Klasse machen, aber bedenke, dass du den Überblick behalten willst, sowie andere, die deinen Code anschauen wollen. Daher sind sprechende Strukturen ein notwendiges Mittel.


----------



## jono (17. Aug 2020)

@MoxxiManagarm 
Also zu mir meinte der Dozent:
"Das Observer-Pattern brauchen Sie nicht selbst implementieren, denn in JavaFX gibt es dafür schon ObservableValues."

Ja, okay, das wäre natürlich sinnvoll, ich werde jetzt mal das UML weiter erstellen und ich werde es dann mal hochladen.


----------



## jono (17. Aug 2020)

@LimDul 
Okay, danke versuche das sinnvoll einzubringen.


----------



## MoxxiManagarm (17. Aug 2020)

jono hat gesagt.:


> "Das Observer-Pattern brauchen Sie nicht selbst implementieren, denn in JavaFX gibt es dafür schon ObservableValues."


Das ist richtig, aber das ist mir schon eine neue Information, das hast du bisher nicht gesagt, dass es ein JavaFX Projekt ist


----------



## jono (17. Aug 2020)

Okay sorry dann geht das natürlich von mir aus.


----------



## jono (17. Aug 2020)

Ich habe jetzt mal etwas erstellt und ich gehe fast davon aus, dass das nicht vollständig ist. Nur fällt mir einfach nicht mehr ein. Was könnte noch hinzugefügt werden?


----------



## LimDul (17. Aug 2020)

- Grundsätzlich - operation1 bis 6 sind keine sinnvollen Bezeichnungen.
- Gleiches gilt für attribute8
- Wo speicherst du die Position der baits? 
- Warum hat ein Bait (also eine Instanz der Klasse Baits) vier Attribute? Ein Bait besteht für dich also aus "Gem UND Coffee UND Food UND Trap)"? Ist das was du da modelliert hast, nicht eher der BaitType mit einem Score Wert (Typ: Java-Enum).


----------



## LimDul (17. Aug 2020)

Vielleicht als Tipp: Lös dich mal von UML und Attributen und Methoden.

Beschreibe erst mal in Natürlicher Sprache, was hast du für Objekte

Ein Spieler befindet sich an einer Position im Labyrinth und hat einen Punktewert.
Ein Labyrinth besteht aus Wegen und Mauern......


----------



## jono (17. Aug 2020)

Die Bezeichnungen "-operation1 bis 6 usw." sind vorgegeben von Astah , werden noch umbenannt oder gelöscht jenachdem ob sie benötigt werden.
Wie speichere ich denn eine Postition...?(evtl. muss dann pro bait ein zweidimensionales Array angelegt werden?) 
Ja, das stimmt es ist schon eher der BaitType, aber wieso kann ich es denn nicht einfach so anlegen und brauche ein ENUM? In der BaitType-Klasses sind Attribute doch eigentlich auch nur eine Aufzählung...?

Guter Tipp mit der natürlichen Sprache, habe ich ehrlicherweise nicht dran gedacht.


----------



## jono (17. Aug 2020)

Wie kann man denn Wege und Mauern modellieren?


----------



## jono (17. Aug 2020)

Ist ja in der Protokollsyntax festgelegt in exam-task.pdf , soll ich das dann einfach übernehmen? String ... = "-" für ein unbekanntes nicht zugängliches Feld.


----------



## jono (18. Aug 2020)

@LimDul Bekomme ich keine Antwort mehr ^^


----------



## mrBrown (18. Aug 2020)

jono hat gesagt.:


> Guter Tipp mit der natürlichen Sprache, habe ich ehrlicherweise nicht dran gedacht.


Dann mach genau das doch erstmal 

Einfach mal beschreiben, was es so gibt.


----------



## VfL_Freak (18. Aug 2020)

Moin,


jono hat gesagt.:


> Bekomme ich keine Antwort mehr ^^


mal so nebenbei:
Du musst bedenken, dass wir, die Dir helfen, das zumeist neben der Arbeit, Schule etc. machen! 
Zudem völlig unentgeltlich! Und die wenigsten sind 24 h pro Tag online, haben aber auch ein Privatleben 😮

Also bitte ggf. etwas mehr Geduld in bezug auf Antworten!

VG Klaus


----------



## jono (18. Aug 2020)

@mrBrown
zur Klasse Player:
Jeder Spieler befindet sich an einer Position und schaut in eine der 4 vorhanden Himmelsrichtungen. Jeder Spieler hat eine individuelle Punktzahl und am Anfang beträgt sie 0. Jeder hat eine eigene ID und eine nickname und eine bestimme Koordinate im Maze. Der Spieler muss die Baits einsammeln können (collect()) und dazu muss er sich bewegen können (move()). Außerdem muss ein Spieler sich mit dem Server verbinden können, das Spiel spielen und es auch wieder verlassen können.

Maze:
Ein Labyrinth hat eine Höhe und eine Breite. Es besitzt außerdem unbekannte, nicht zugängliche Felder, dann Wände und noch freie Wege.
Die verschiedenen Items befinden sich mit ihren Scores ebenfalls im Labyrinth.

@VfL_Freak
Ja, ich weiß, habe auch absolut Verständnis und Geduld, dachte vielleicht hat er nicht mehr daran gedacht oder so...


Das habe ich jetzt erstmal vorläufig dazu erstellt.


----------



## mrBrown (18. Aug 2020)

Position kann man noch sinnvoller darstellen


----------



## jono (18. Aug 2020)

1. Auch mit width und height?
Was fehlt ansonsten noch? Müsste ich nicht noch eine Methode zum Verlassen des Spiels hinzufügen in der Klasse Player?


----------



## mrBrown (18. Aug 2020)

jono hat gesagt.:


> 1. Auch mit width und height?


Wieso sollte eine Position Breite und Höhe haben?  

Beschreib doch mal umgangssprachlich "Position".



jono hat gesagt.:


> Müsste ich nicht noch eine Methode zum Verlassen des Spiels hinzufügen in der Klasse Player?


Würde für mich nicht da rein gehören


----------



## jono (18. Aug 2020)

Eine Position ist eine Koordinate im Sinne des Labyrinths, ich kenne nur x und y Koordinaten im herkömmlichen Sinne. Ich denke, dass sich das eignet ein Tipp von dir wäre echt sehr nett und hilfreich.


----------



## jono (19. Aug 2020)

@mrBrown


----------



## mrBrown (19. Aug 2020)

und was sind die „x und y Koordinaten“ und wie könnte man die modellieren?


----------



## jono (19. Aug 2020)

Die sind ein Punkt zusammen


----------



## jono (19. Aug 2020)

Ich habe keine Ahnung, wie ich in einem Maze-Array eine Position anders ausdrücken sollte.


----------



## mrBrown (19. Aug 2020)

Wenn mehrere Dinge zusammen gehören, macht man daraus eine ______?


----------



## jono (19. Aug 2020)

Liste? @mrBrown


----------



## mrBrown (19. Aug 2020)

Wenn du eine Person modellieren müsstest, würdest du dann eine Liste aus [Name, Vorname, Alter] erstellen?


----------



## jono (19. Aug 2020)

Ne eine Zeile  @mrBrown


----------



## mrBrown (19. Aug 2020)

jono hat gesagt.:


> Ne eine Zeile  @mrBrown


Und was bitte soll eine Zeile in Java sein?


----------



## jono (19. Aug 2020)

@mrBrown Ich weiß nun wirklich nicht worauf du hinaus willst, wäre es nicht durchaus sinnvoll mir etwas mehr auf die Sprünge zu helfen?


----------



## jono (20. Aug 2020)

@mrBrown


----------



## kneitzel (20. Aug 2020)

In einer Objektorientierten Sprache werden Objekte gebildet, die gewisse Eigenschaften / Zustände haben und mit denen man gewisse Dinge machen kann.

In Java wird das über Klassen gemacht, von denen dann Instanzen erstellt werden können.



mrBrown hat gesagt.:


> Wenn du eine Person modellieren müsstest, würdest du dann eine Liste aus [Name, Vorname, Alter] erstellen?


Das wäre dann also z.B. eine Klasse Person, welche Instanzvariablen name, vorname und alter haben könnte.

Und wenn Du also eine Position aus x und y Koordinate hast, dann macht es durchaus Sinn, dies auch entsprechend zu modellieren...

Das dürfte das sein, worauf @mrBrown hinaus wollte...


----------



## jono (20. Aug 2020)

Ja, eine Klasse für Koordinate x und Koordinate y ?
Aber die Position des Spielers soll ja dynamisch sein, heißt x und y sind variabel, wie modelliere ich das denn entsprechend?
@JustNobody


----------



## mrBrown (20. Aug 2020)

jono hat gesagt.:


> Ja, eine Klasse für Koordinate x und Koordinate y ?


Nein, eine Klasse für die Position, und eine Position enthält x und y.



jono hat gesagt.:


> Aber die Position des Spielers soll ja dynamisch sein, heißt x und y sind variabel, wie modelliere ich das denn entsprechend?


Das ist es doch quasi automatisch, wenn du es als Klasse umsetzt? Wo siehst du da ein Problem?


----------



## jono (20. Aug 2020)

Ja, gut erstmal sehe ich da kein Problem, ist ja variabel da ja keine Werte zugewiesen worden sind.

Wäre das dann so korrekt?
Wie genau stelle ich jetzt die Wände, unzugänglichen Felder und zugängliche Felder dar?
Das hat man ja schonmal als Information:
" Description: The server informs about the structure of the maze. First, it sends the Width and Height of the rectangular game field. The following lines with game field data contain one character for each field of the maze. The fields are encoded as follows: 
• - (Minus): Unknown, non-accessible field (may also occur inside the maze) 
• # (Hash): Stone field; an impenetrable wall 
• . (Period): Free accessible field
Müssen die Zeichen einfach der Klasse Maze als String Attribute hinzugefügt werden?
Und wie sage ich der Klasse dass es nicht zugänglich ist usw...?


----------



## mrBrown (20. Aug 2020)

Warum hat Player denn noch pos, x & y?


----------



## jono (20. Aug 2020)

Versehentlich nicht entfernt.😬 int x und int y müssen ja dann auch noch weg


----------



## thecain (20. Aug 2020)

Die Multiplizitäten bei den Enums stimmen mMn nicht... aber ich bin auch kein UML Experte, aber ich hätte ein Feld gemacht und eine Abhängigkeitsbeziehung


----------



## jono (20. Aug 2020)

Ja, hast recht. Müssten Kompositionen sein und andere Multiplizitäten ändere ich doch gerade mal ab.
@thecain Könntest du mir bei den Fragen unter dem UML in #36behilflich sein ?


----------



## mrBrown (20. Aug 2020)

jono hat gesagt.:


> Wie genau stelle ich jetzt die Wände, unzugänglichen Felder und zugängliche Felder dar?


Die eine Frage hat er schon beantwortet: Führ ein "Feld" ein, und nutz dort den Feld-Typen 

Die anderen Fragen sollte das auch klären


----------



## jono (20. Aug 2020)

Was heißt denn "ich hätte ein Feld gemacht" <--- Zitat von @thecain , @mrBrown und was meinst du mit "Für ein "Feld" ein"??? Was ist denn ein Feld Typ???


----------



## mrBrown (20. Aug 2020)

Ein Feld ist einfach nur ein Feld innerhalb des Labyrints, der Feld-Typ ist dann die „Art“ des Felds, zb „Wand“


----------



## jono (20. Aug 2020)

Gut, aber wie ich jetzt die Wände usw. erstelle ist mir immer noch nicht ersichtlich aus den Hilfen.
Die Antwort von @thecain ein Feld zu machen ist nicht wirklich hilfreich, denn das ist ja das was ich gerade frage, wie mache ich ein Feld(siehe #36 durch Hinzufügen der Zeichen als String Attribute der Maze-Klasse)?


----------



## mrBrown (20. Aug 2020)

Die Antwort ist nahezu immer, dass du eine Klasse erstellen solltest.


----------



## jono (20. Aug 2020)

Also das enum löschen und eine Klasse Feld erstellen oder wie ???


----------



## jono (20. Aug 2020)

Und mir hat keiner gesagt, dass ich dafür eine Klasse erstellen soll?!


----------



## mrBrown (20. Aug 2020)

Ist im wesentlichen deine Beschreibung des ganzen, etwas ergänz (in _kursiv_). Darin einfach jedes Nomen markieren (in *Fett*), und wenn irgendein Nomen etwas anderes "besitzt" wird das ganze unterstrichen:

"zur Klasse Player:
Jeder *Spieler* befindet sich an einer *Position*, _diese besteht aus __x- und y-Koordinate_, und schaut in eine der 4 vorhanden *Himmelsrichtungen*. Jeder *Spieler* hat eine individuelle *Punktzahl* und am Anfang beträgt sie 0. Jeder hat eine eigene *ID* und eine *nickname* und eine bestimme *Koordinate* im *Maze*. Der Spieler muss die *Baits* einsammeln können (collect()) und dazu muss er sich bewegen können (move()). Außerdem muss ein *Spieler* sich mit dem Server verbinden können, das Spiel spielen und es auch wieder verlassen können.

Maze:
Ein *Labyrinth* hat eine *Höhe* und eine *Breite*. Es besitzt außerdem unbekannte, nicht *zugängliche Felder*, dann *Wände* und noch freie *Wege*.
Die verschiedenen *Items* befinden sich mit ihren *Scores* ebenfalls _auf *Feldern*_ im *Labyrinth*."


Jedes Nomen ist jetzt ein Typ (=Klasse oder primitiver Typ wie Enum/Zahl/String/boolean), jedes Unterstrichene ist ein Feld in einem der Typen.

Das kannst du jetzt einfach in einem Diagramm darstellen (jedes Nomen ein Kasten, jedes "besitzen" ein Pfeil). Wenn etwas keine ausgehenden Pfeile hat, ist es meist in primitiver Typ, welche musst du dann entscheiden (zB ist "Nickname" wahrscheinlich ein String), wenn dem so ist, kannst du es als eigener Typ in dem Diagramm entfernen und direkt als "Attribut" in den besitzenden Typen eintragen.

Wahrscheinlich muss man dann noch ein bisschen verfeinern, am Ende kommt dann ein meist relativ sinnvolles Domänenmodell dabei raus, welches du so 1-zu-1 in Code übersetzen kannst.


----------



## jono (20. Aug 2020)

Also erstmal danke, dass du mir hilfst. Aber was willst du mir denn jetzt damit sagen, dass jedes Nomen ein Kasten darstellt? Wofür steht denn ein Kasten in deinem Sinne? Und wozu dient der Pfeil? 
2. Was meinst du mit "...wenn dem so ist, kannst du es als eigener Typ in dem Diagramm entfernen und direkt als ...". Wenn du ja sagst, dass jedes Nomen ein Typ ist und sagst, dass der nickname als Stringtyp als eigener Typ in dem Diagramm entfernt werden kann und direkt als Attribut in den besitzenden Typ eingetragen werden soll ? Der Nickname ist doch als Attribut dem besitzenden Typen(Player) beigefügt???
Ein bisschen bessere Differenzierung von deinen Ausführungen wären da echt mega.


----------



## jono (20. Aug 2020)

Finde, dass du es echt etwas schwieriger machst, als es sein müsste


----------



## mrBrown (20. Aug 2020)

jono hat gesagt.:


> Aber was willst du mir denn jetzt damit sagen, dass jedes Nomen ein Kasten darstellt? Wofür steht denn ein Kasten in deinem Sinne? Und wozu dient der Pfeil?


Beides benutzt du in deinem Diagramm schon – benutzt du das, ohne zu wissen, was es darstellt? 

Abgesehen davon steht es sogar in meinem Beitrag in der Zeile darüber: "Jedes Nomen ist jetzt ein Typ (=Klasse, Enum oder primitiver Typ wie Zahl/String/boolean), jedes Unterstrichene ist ein Feld in einem der Typen." Also, "Kasten"=Typ, "Pfeil"="besitzen" (=Relation).



jono hat gesagt.:


> 2. Was meinst du mit "...wenn dem so ist, kannst du es als eigener Typ in dem Diagramm entfernen und direkt als ...". Wenn du ja sagst, dass jedes Nomen ein Typ ist und sagst, dass der nickname als Stringtyp als eigener Typ in dem Diagramm entfernt werden kann und direkt als Attribut in den besitzenden Typ eingetragen werden soll ? Der Nickname ist doch als Attribut dem besitzenden Typen(Player) beigefügt???


Am Anfang: Ein Kasten "Spieler", ein Kasten "Nickname", dazwischen ein Pfeil (von Spieler auf Nickname zeigend).

Nickname hat keinen ausgehenden Pfeil (und keine Attribute, die du in dem Schritt erstellst) => daran erkennst du, das es ein primitiver Typ ist, und als primitiver Typ kommt da String in Frage =>  "Kasten Nickname" entfernen und Nickname direkt dem Typen Spieler hinzufügen.




jono hat gesagt.:


> Finde, dass du es echt etwas schwieriger machst, als es sein müsste


Es ist halt ein Weg, wie man selbstständig auf die Lösung kommt, ohne das man irgendwo vorgesagt bekommt, dass etwas eine Klasse sein soll


----------



## jono (20. Aug 2020)

Ich hatte aber keinen Kasten namens Nickname ?


----------



## jono (20. Aug 2020)

Ist aber nur zur Demonstration, um das auf meine spezifische Frage bezüglich der Wände und Wege konkretisieren zu können stimmt's?


----------



## jono (20. Aug 2020)

Deinen Aussagen zufolge würde das heißen in Klasse Maze:
String wall = "."
String unknown = "-" ?


----------



## mrBrown (20. Aug 2020)

jono hat gesagt.:


> Ich hatte aber keinen Kasten namens Nickname ?


Ne, weil du den Schritt übersprungen hast 

Kann man auch Problemlos machen – wenn man aber nicht weiß was man tut klappt es nicht.



jono hat gesagt.:


> Ist aber nur zur Demonstration, um das auf meine spezifische Frage bezüglich der Wände und Wege konkretisieren zu können stimmt's?


Nicht nur, wäre schon bei Position/Koordinate sinnvoll gewesen, und soll weniger Demonstration als mehr Hilfe zur Selbsthilfe sein 

Um aber noch näher auf Das Problem der Felder einzugehen:


jono hat gesagt.:


> Ein Labyrinth hat eine Höhe und eine Breite. Es besitzt außerdem unbekannte, nicht zugängliche Felder, dann Wände und noch freie Wege.
> Die verschiedenen Items befinden sich mit ihren Scores ebenfalls im Labyrinth.


Es gibt "Felder", die sind einfach da, man kann sie nicht betreten und man weiß nicht was es ist?
Dann Wände, da kann man vermutlich nicht durchgehen?
Und Wege, die sind dann wohl das einzige zum drüber laufen?

Und Baits liegen jetzt wo? Einfach so im Labyrinth oder auf Wegen oder auf nicht zugänglichen Feldern?


----------



## mrBrown (20. Aug 2020)

jono hat gesagt.:


> Deinen Aussagen zufolge würde das heißen in Klasse Maze:
> String wall = "."
> String unknown = "-" ?


Wie sieht der Weg von Text ("Ein Labyrinth hat eine Höhe und eine Breite. Es besitzt außerdem unbekannte, nicht zugängliche Felder, dann Wände und noch freie Wege.
Die verschiedenen Items befinden sich mit ihren Scores ebenfalls im Labyrinth.") bis dahin aus?


----------



## jono (20. Aug 2020)

Sieht sinngemäß aus!


----------



## jono (20. Aug 2020)

Ein Enum ist nicht unbedingt sinnvoll mit PATH, UNKNOWN


----------



## jono (20. Aug 2020)

Baits liegen auf zugänglichen Feldern. 
Nur weiß ich nicht wie ich das umsetzen kann, ist das erste Projekt, was ich mache mit großerem Kontext deshalb bitte ich da auch um etwas Verständnis


----------



## jono (20. Aug 2020)

Und welchen Schritt habe ich übersprüngen, seit wann soll man aus einem Attribut einen Kasten(stellvertretend für eine Klasse) verwenden, wäre ggf. echt gut wenn du flüssig antworten würdest, wenn du schon helfen möchtest. Die Art und Weise, wie du argumentierst und dann mittendrin wieder nichts schreibst ist doch nicht zielführend wenn man schon ein Helferkomplex hat. Ich weiß nicht warum du dich so komisch verhältst. Ich bin in der Lage zu abstrahieren, was du mir mit deinen Antworten sagen möchtest, aber du gibst mir Antworten, die sich nicht explizit auf das beziehen was, ich zuerst erfragen wollte: Wie setze ich die Wände usw. um??? Da bringt es mir nichts zu wissen was Typen sind(unterstrichene Nomen). Ich bin wohl selbst in der Lage einfache Attribute den Klassen zuzuordnen, deshalb verstehe ich die Gewichtung des Textes nicht, wäre echt gut wenn du mal auf mich versuchst einzugehen, anstatt nur von dem überzeugt zu sein, was du mir sagst.


----------



## jono (20. Aug 2020)

Was du meinst geht bestimmt in diese Richtung (vorheriges Maze, dort sind noch ein paar Dinge fehlend, die in dem anderen dabei sind), aber hier geht um das Status Model, welches ich meine.

@mrBrown


----------



## mrBrown (20. Aug 2020)

Wenn du auf bestimmte Dinge antwortest, solltest du diese auch zitieren. Ich hab keine Ahnung, welche deiner Antworten sich jetzt worauf bezieht.



jono hat gesagt.:


> wäre ggf. echt gut wenn du flüssig antworten würdest, wenn du schon helfen möchtest. Die Art und Weise, wie du argumentierst und dann mittendrin wieder nichts schreibst ist doch nicht zielführend wenn man schon ein Helferkomplex hat



Ich antworte, wenn ich Zeit und vor allem *Lust* dazu hab. Solche Antworten fördern letzteres nicht grad


----------



## kneitzel (20. Aug 2020)

Du kannst das doch ganz frei aufbauen, zumindest habe ich beim überfliegen diesbezüglich nichts in den pdfs gefunden (Aber ich muss zugeben, dass ich die wirklich nur ganz ganz schnell überflogen habe ...)

Stell Dir das doch einfach bildlich vor. Du hast also sowas wie Objekte. Du hast also ein Spielfeld mit x mal y Feldern. Ein Feld hat ein bestimmten Typ. Und den modellierst Du richtig! Keine "Abkürzungen" mit Zeichen oder so! Also wenn es eine feste Menge an FeldTypen gibt, dann modellierst Du das auch so (Also lass das Enum! Aber das ist kein Feld sondern ein FeldTyp. Korrekte Benennung beachten! Und so ein feldTyp kann dann auch durchaus wissen, wie man sich als Zeichen oder String darstellt. Das könnte man bei der Definition des Enum mit vorgeben und man könnte eine statische Methode haben, um aus einem Zeichen / einer Zeichenkette das Enum zu bekommen.)

Also hast Du x mal y etwas vom Typ Feld. Wie kannst Du das abbilden? Kennst Du eine Datenstruktur, die dies erlaubt?

Und dann hast Du Felder. Ein Feld ist gekennzeichnet durch einen Typ. Und dann kann da etwas auf dem Feld sein. Da wäre dann eine Frage: Wie viele Elemente?
- 0..1? (Also kein Element oder max 1 Element?)
- 1?(Also immer genau ein Element?)
- 0..n? (also beliebig viele Elemente?)
Das kann man dann entsprechend modellieren. Das 0..1 und 1 ist fast gleich.  Das wäre eine Referent die eben null sein kann oder nicht.... Und für den letzten Fall wäre die Frage: Kennst Du irgend ein Konstrukt, in das Du 0, 1 oder beliebig mehr Elemente packen könntest?



jono hat gesagt.:


> Und welchen Schritt habe ich übersprüngen, seit wann soll man aus einem Attribut einen Kasten(stellvertretend für eine Klasse) verwenden, wäre ggf. echt gut wenn du flüssig antworten würdest, wenn du schon helfen möchtest. Die Art und Weise, wie du argumentierst und dann mittendrin wieder nichts schreibst ist doch nicht zielführend wenn man schon ein Helferkomplex hat



Das große Problem ist, dass wir Dir keine Lösung vorgeben wollen. Damit würdest du nichts lernen. Also haben wir das Problem, dass wir erst einmal erkennen müssen, an welcher Stelle es bei Dir hakt. Um dann da gezielt zu helfen. Und zwar so zu helfen, dass Du auf die Lösung kommst.

Im Augenblick denke ich, das Du Probleme hast, Dir das vorzustellen um es dann Sinnvoll zu unterteilen. Mir hat damals "Object Thinking" von Microfot Press als Buch gut gefallen. Das hat das relativ gut erläutert ...


----------



## mrBrown (20. Aug 2020)

jono hat gesagt.:


> das Status Model



Markier in dieser Beschreibung mal bitte "Status Model": 


jono hat gesagt.:


> zur Klasse Player:
> Jeder Spieler befindet sich an einer Position und schaut in eine der 4 vorhanden Himmelsrichtungen. Jeder Spieler hat eine individuelle Punktzahl und am Anfang beträgt sie 0. Jeder hat eine eigene ID und eine nickname und eine bestimme Koordinate im Maze. Der Spieler muss die Baits einsammeln können (collect()) und dazu muss er sich bewegen können (move()). Außerdem muss ein Spieler sich mit dem Server verbinden können, das Spiel spielen und es auch wieder verlassen können.
> 
> Maze:
> ...


----------



## jono (20. Aug 2020)

Ja, wenn du nicht auch mal etwas einstecken kannst, bist du wohl fehl am Platz oder bist du hier um dich überlegen zu fühlen??
Naja, auf das niveau wollen wir nicht zusteuern. Aber wenn jemand helfen möchte, dann doch bitte möglichst so, sodass man das nicht allzu lange warten lässt (zumal das ja im Interesse desjenigen sein sollte, der ja helfen möchte, damit jemand weiterkommen kann).


----------



## jono (20. Aug 2020)

Das ist StatusModel


----------



## jono (20. Aug 2020)

@JustNobody 
Zu #63:
Das mit der statischen Methode verstehe ich nicht, um daraus das Enum zu bekommen.
Um das x mal y vom Typ Feld abbilden zu können kann man ein 2D-Array verwenden.
Zur letzten Frage, ein Konstrukt in das ich 0,1 oder mehrere Elemente packen könnte. Da wäre eine List denkbar oder evtl auch ein normales Array.


----------



## mrBrown (20. Aug 2020)

*Bitte zitiere Beiträge, auf die du Antwortest.*



jono hat gesagt.:


> Das ist StatusModel


Da steht "Es besitzt außerdem unbekannte, nicht zugängliche Felder, dann Wände und noch freie Wege.
Die verschiedenen Items befinden sich mit ihren Scores ebenfalls im Labyrinth", da kommt weder "Status" noch "Model" noch "StatusModel" vor.

(Oder um es deutlicher zu sagen: StatusModel ist Unsinn.)



jono hat gesagt.:


> Aber wenn jemand helfen möchte, dann doch bitte möglichst so, sodass man das nicht allzu lange warten lässt


In dem Fall: Nachhilfe geb ich ab 20€/h


----------



## kneitzel (20. Aug 2020)

Ok, das hat sich etwas überschnitten. Was mir bei Dir auffällt ist: Du hast Felder - das wäre dann aber Field und nicht FieldType.

Und die Baits hast Du statt in einem Feld direkt im maze gespeichert. Das geht natürlich auch. Das kann man sich generell so überlegen, wie man möchte.



jono hat gesagt.:


> Ja, wenn du nicht auch mal etwas einstecken kannst, bist du wohl fehl am Platz oder bist du hier um dich überlegen zu fühlen??
> Naja, auf das niveau wollen wir nicht zusteuern. Aber wenn jemand helfen möchte, dann doch bitte möglichst so, sodass man das nicht allzu lange warten lässt (zumal das ja im Interesse desjenigen sein sollte, der ja helfen möchte, damit jemand weiterkommen kann).



So kommen wir wohl nicht auf einen Nenner fürchte ich. Generell bist Du es, der etwas will. Du kannst Deine Probleme darstellen und wir können darauf antworten. Und das machen wir generell so, wie wir es für richtig halten. Und bei gewissen Erlebnissen überlege ich mir inzwischen durchaus, manche Threads einfach zu ignorieren. Ich muss niemandem helfen um mich überlegen oder besser zu fühlen. Und ich bin extrem sicher, dass es fast allen, die hier aktiv sind, ebenso geht (ohne @mrBrown, @mihe7 und den vielen Anderen, die hier sehr aktiv sind im Forum zu nahe treten zu wollen: Ich unterstelle dies ihnen und stecke sie damit einfach so in diese "Schublade"  ...)

Ein Auto besitzt Kolben. Damit das wahr ist: Dürfen die Kolben im Motorblock sein oder müssen diese dann direkt im Auto sein? Wie man das abbildet ist erst einmal egal. Aber spätestens, wenn man zur Funktionalität kommt, dann wird es relativ schwer. Wenn alles direkt im Auto ist, dann wird das Auto sehr komplex. Daher packt man Funktionalität da hin, wo sie hin gehört. Und dann gibt es Einheiten, die geschlossen funktionieren. Also ein Motor hat schon direkt die Funktionalität eines Motors. Das Auto muss die genaue Funktionalität nicht kennen.

Etwas übertragen wäre dies: Für mich würde ein Feld wissen, was es da für Funktionalität gibt. Ein Feld weiss z.B., ob ein Spieler auf das Feld gehen kann. Das ist eine Logik, die das Maze nicht kennen muss. Das Maze muss nur wissen, wie der Spieler sich bewegen möchte, prüft dann das Zielfeld und wenn er es nicht betreten kann, dann führt es die Bewegung nicht aus.

Das reduziert dann die Funktionalität des Maze, strukturiert den Code, macht ihn lesbar. Und vor allem hast Du keine "Masterklasse", in der alles steckt und alles andere sind nur reine Datenhaltung (Was bei C Strukturen waren). Das ist halt etwas, das man in der Softwareentwicklung vermeiden möchte ... 



jono hat gesagt.:


> @JustNobody
> Zu #63:
> Das mit der statischen Methode verstehe ich nicht, um daraus das Enum zu bekommen.
> Um das x mal y vom Typ Feld abbilden zu können kann man ein 2D-Array verwenden.
> Zur letzten Frage, ein Konstrukt in das ich 0,1 oder mehrere Elemente packen könnte. Da wäre eine List denkbar oder evtl auch ein normales Array.



In java ist ein Enum eine spezielle Klasse die eigentlich fast alles kann, was auch eine Klasse kann mit wenigen Ausnahmen. So kann man zur Laufzeit keine Instanzen mehr erzeugen. Aber Du kannst Instanzvariablen haben, Klassenmethoden, Konstruktor, ...

Also z.B. sowas:

```
public enum TestEnumWithIntValue {
  ONE(1),
  TWO(2),
  THREE(3);
 
  private int intValue;
  public int getIntValue() { return intValue; }
 
  TestEnumWithIntValue(final int intValue) { this.intValue= intValue; }
 
  public static TestEnumWithIntValue fromIntValue(final int intValue) {
    for (TestEnumWithIntValue enumValue: TestEnumWithIntValue.values()) {
      if (enumValue.getIntValue() == intValue) return enumValue;
    }
    throw new InvalidArgumentException("Value " + intValue + " is not a valid value of TestEnumWithIntValue");
  }
}
```

Das ist jetzt hier im Editor geschrieben worden. Tippfehler bitte ich zu entschuldigen. Ohne IDE kann schon mal etwas schief gehen. Aber das Prinzip wird schnell deutlich. Und die statische Methode der enum gibt halt den passenden Enum Wert zurück.

Ansonsten ist es richtig. 2D Array für die Felder hätte ich auch im Sinn gehabt. Es gibt auch andere Lösungsideen speziell wenn man recht große Felder haben will, aber das würde ich tatsächlich erst einmal so machen. (Eine andere Option wäre mit Koordinaten in einer Map wie Du es bei den Baits gemacht hast. Aber das 2d Array ist ok, so Du nicht z.B. sehr viele "UNKNOWN" Felder hast, die Du gerne weglassen möchtest....

Und das mit der Liste ist auch korrekt. Das würde ich in das Feld mit einbauen. Ggf. mit einer null Möglichkeit falls es nur sehr begrenzt diese Baits gibt. Die List brauchst Du aber nur, wenn Du auf einem Feld mehrere Baits haben kannst. Ist das nicht der Fall, dann reicht eine einfache Referenz.


----------



## kneitzel (20. Aug 2020)

mrBrown hat gesagt.:


> In dem Fall: Nachhilfe geb ich ab 20€/h



Auch in "Ruhe bewahren"? Dann hätte ich ggf. Interesse  Aber evtl. wäre es einfacher, im lokalen DNS Server die Domain java-forum.org zu blocken/umzuleiten bzw ein lokaler Yoga- / Meditation Lehrer verlangt ggf. weniger  Oder bau mir eine Seite, die einfach nur ein Meerblick mit Meeresrauschen als Video abspielt ... und auf die leite ich um ... so als Kombination aus beidem 

*SCNR*


----------



## thecain (20. Aug 2020)

Unglaublich... Ich hab zum Glück keinen Helferkomplex und verzichte auf weitere Hilfestellungen.


----------



## mrBrown (20. Aug 2020)

JustNobody hat gesagt.:


> Auch in "Ruhe bewahren"? Dann hätte ich ggf. Interesse  Aber evtl. wäre es einfacher, im lokalen DNS Server die Domain java-forum.org zu blocken/umzuleiten bzw ein lokaler Yoga- / Meditation Lehrer verlangt ggf. weniger  Oder bau mir eine Seite, die einfach nur ein Meerblick mit Meeresrauschen als Video abspielt ... und auf die leite ich um ... so als Kombination aus beidem
> 
> *SCNR*


Für 20€/h spiele ich dir gerne über Zoom Meditationsvideos vor


----------



## jono (20. Aug 2020)

@JustNobody
Ich versuche mal das bis morgen umzusetzen zumal ich jetzt eh afk gehen muss. Ich danke für die Hilfe und komme morgen nochmal darauf zurück.


JustNobody hat gesagt.:


> Und das machen wir generell so, wie wir es für richtig halten.


Das ist ja in Ordnung, ich will auch etwas, das stimmt, aber es bringt dann ja auch nichts mich bei der Hälfte des Weges stehen zu lassen, wobei ich auch das Empfinden hatte, dass @mrBrown und ich teilweise aneinander vorbei geredet haben bzw. ich vlt. an ihm.


thecain hat gesagt.:


> Unglaublich... Ich hab zum Glück keinen Helferkomplex und verzichte auf weitere Hilfestellungen.


@thecain Ein Helferkomplex ist übertrieben formuliert, aber man gibt Hilfestellungen doch hoffentlich auch , um anderen zu helfen und nicht nur, um weiter dazu zu lernen.


----------



## kneitzel (20. Aug 2020)

Deine Aussagen kamen evtl. etwas falsch rüber. Ich kann verstehen, dass da etwas Frust entsteht, wenn man hier so hin und her schreibt aber ich hoffe, dass ich auch etwas erläutern konnte, wieso wir so vorgehen und keine Lösungen hin knallen.

Und wenn es um Worte und deren Bedeutung geht, dann kann es durchaus leicht dazu kommen, dass man etwas aneinander vorbei redet. Da wäre mein Tipp, die Worte genau zu überdenken. Denn gerade @mrBrown ist da nach meiner Erfahrung jemand, der hier sehr exakt ist und dem man da durchaus gut zuhören sollte. Das aber einfach nur als meine grobe Einschätzung... wünsche allen ein schönen Abend...


----------



## jono (20. Aug 2020)

Okay, werde ich mir zu Herzen nehmen, wünsche ich ebenfalls...


----------



## jono (21. Aug 2020)

mrBrown hat gesagt.:


> Jeder *Spieler* befindet sich an einer *Position*, _diese besteht aus __x- und y-Koordinate_, und schaut in eine der 4 vorhanden *Himmelsrichtungen*. Jeder *Spieler* hat eine individuelle *Punktzahl* und am Anfang beträgt sie 0. Jeder hat eine eigene *ID* und eine *nickname* und eine bestimme *Koordinate* im *Maze*. Der Spieler muss die *Baits* einsammeln können (collect()) und dazu muss er sich bewegen können (move()). Außerdem muss ein *Spieler* sich mit dem Server verbinden können, das Spiel spielen und es auch wieder verlassen können.
> 
> Maze:
> Ein *Labyrinth* hat eine *Höhe* und eine *Breite*. Es besitzt außerdem unbekannte, nicht *zugängliche Felder*, dann *Wände* und noch freie *Wege*.
> ...




Ich habe mich mal an die "Konventionen" von @mrBrown gehalten.



JustNobody hat gesagt.:


> Und so ein feldTyp kann dann auch durchaus wissen, wie man sich als Zeichen oder String darstellt. Das könnte man bei der Definition des Enum mit vorgeben und man könnte eine statische Methode haben, um aus einem Zeichen / einer Zeichenkette das Enum zu bekommen.)
> 
> Also hast Du x mal y etwas vom Typ Feld. Wie kannst Du das abbilden? Kennst Du eine Datenstruktur, die dies erlaubt?
> 
> ...


Du meintest in dem Beitrag:


JustNobody hat gesagt.:


> Also wenn es eine feste Menge an FeldTypen gibt, dann modellierst Du das auch so (Also lass das Enum!


aber sagst hier wieder


JustNobody hat gesagt.:


> Das könnte man bei der Definition des Enum mit vorgeben


das verstehe ich nicht, erst soll ich eins verwenden und dann nicht ? Des Weiteren verstehe ich nicht, die Feldtypen gehören einem Feld an (das könnte doch auch einfach das Maze sein (2D-Array?) ? Und zu der Frage wie ich ich die Elemente in das Feld packe, hatte sich ja herauskristallisiert, dass ein normale Array dies erfüllen würde, dementsprechend müsste ich eine Klasse mit den Baits(gem, coffee, trap...) erstellen, diesen ihren Wert zuweisen, wodurch sie ein integer wären. Dann müsste ich ja im nächsten Schritt eine Instanz von der Klasse "Baits" bilden in der "Feld(Maze???)"-Klasse damit das Feld verschiedene Elemente der Baits aufnehmen kann ?


----------



## jono (21. Aug 2020)

@JustNobody
Sorry, mir fällt gerade auf,


JustNobody hat gesagt.:


> Ein Auto besitzt Kolben. Damit das wahr ist: Dürfen die Kolben im Motorblock sein oder müssen diese dann direkt im Auto sein? Wie man das abbildet ist erst einmal egal. Aber spätestens, wenn man zur Funktionalität kommt, dann wird es relativ schwer. Wenn alles direkt im Auto ist, dann wird das Auto sehr komplex. Daher packt man Funktionalität da hin, wo sie hin gehört. Und dann gibt es Einheiten, die geschlossen funktionieren. Also ein Motor hat schon direkt die Funktionalität eines Motors. Das Auto muss die genaue Funktionalität nicht kennen.
> 
> Etwas übertragen wäre dies: Für mich würde ein Feld wissen, was es da für Funktionalität gibt. Ein Feld weiss z.B., ob ein Spieler auf das Feld gehen kann. Das ist eine Logik, die das Maze nicht kennen muss. Das Maze muss nur wissen, wie der Spieler sich bewegen möchte, prüft dann das Zielfeld und wenn er es nicht betreten kann, dann führt es die Bewegung nicht aus.


dass das hier gilt, weshalb es eine eigene Feldklasse geben muss. Dementsprechend würden dort die Baits durch ein 1D-Array vom Typ Baits modelliert werden und die Feldtypen würde man dann als welchen Datentyp in Form eines Attributs angeben? (Die Frage habe ich ja schon im Screen gestellt).


----------



## mrBrown (21. Aug 2020)

jono hat gesagt.:


> Anhang anzeigen 13938



Position hat deshalb keine ausgehenden Pfeile, da du x und y direkt als Attribut geschrieben hast 
Erster Schritt:

Dann für alle "Blätter" (ohne ausgehende Kanten) den Wertebereich festlegen (hab ich oben nicht extra geschrieben, das explizit noch mal zu machen ist hier aber sinnvoll):

Score: 0 - N
ID: irgendeine ganze Zahl
Nickname: Irgendein Text
Himmelsrichtung: N, O, S oder W
X: irgendeine ganze Zahl
Y: irgendeine ganze Zahl



Spoiler



Wertebereich ist nahezu immer entweder Text, Zahl, Wahr/Falsch oder eine feste Menge an Werten.
Für jedes einzelne davon kann man das meist noch weiter einschränken: Zahl kann zb "Ganze Zahl zwischen 5 und 9" oder "Kommazahl kleiner als 5" sein, Text kann sowas sein wie "Text mit mindestens 5 Zeichen" oder "nur Alphanumerisch".
Das ganze möglichst genau aufschreiben ist in jedem Fall sinnvoll, irgendwann ist jede Einschränkung relevant (auch wenn man sie leider oftmals unter den Tisch fallen lässt...).

Man kann dabei auch feststellen, dass es keinen sinnvollen, begrenzten Wertebereich gibt, in dem Fall lässt man es einfach wie es ist. Sieht man potentiell später noch mal.



Aus dem Wertebereich den Typ ableiten:

Score: int
ID: int
Nickname: String
Himmelsrichtung: Enum mit N, O, S oder W
X: int
Y: int



Spoiler



Theoretisch kann man auch Score, ID, Nickname etc als eigene Klasse behalten.

Ein Score ist eben nicht einfach nur ein int, zB kann der Score ja nicht negativ sein (nehm ich einfach mal an). Daher kann es Sinn haben, eine eigene Klasse Score zu haben, die genau das sicherstellt, die dann zB Methoden wie _erhöhe_ oder _verringere_ hat. In der Klasse kann das dann ein int sein – nach außen sieht man aber nur "Score".

Gleiches für den Nickname, nicht jeder String ist auch ein gültiger Nickname, zB muss ein Nickname immer aus mindestens einem Zeichen bestehen und der Anfang und das Ende müssen sichtbare Zeichen sein, Zeilenumbrüche will man vermutlich auch verhindern und es sollte vermutlich eine maximale Länge geben – also eigene Klasse, die genau das sicherstellt, die dann intern wieder einen String benutzt.

Wird aber von vielen auch als schlechtes Design angesehen.



Und dann das Diagramm entsprechend ändern:


Bis dahin käme man ohne jegliche Java-Kenntnisse, mit minimalen Java-Kenntnissen tippt man das jetzt im Nu runter 



jono hat gesagt.:


>


Da zeigen sich jetzt die Mängel in der Natürlichsprachlichen Beschreibung 

"Feld" wird offensichtlich für mehrere verschiedene Dinge benutzt; einmal ist es das ganze Labyrinth, dann ist es etwas "nicht zugänliches", und zusätzlich liegen auch noch die Baits drauf.

Man könnte das ganze zB etwas anders beschreiben:
Ein Labyrinth hat eine feste Größe, diese setzt sich aus Breite und Höhe zusammen. Ein Labyrinth besteht wie ein Schachfeld aus einzelnen Feldern. Jedes Feld ist dabei entweder ein Weg, eine Wand, oder ein "unbekanntes, nicht zugängliches" Feld. Auf einem Feld kann außerdem ein Bait liegen. Ein Bait hat dabei eine (negative oder positive) Punktzahl.


----------



## jono (21. Aug 2020)

mrBrown hat gesagt.:


> Und dann das Diagramm entsprechend ändern:


@mrBrown
Wie war das nochmal mit der Instanzbildung von enums? Denn um das enum "viewDir" mit der Klasse Player zu verbinden, muss
ich ja in der Klasse Player eine Instanzvariable erzeugen von "viewDir".


----------



## fhoffmann (21. Aug 2020)

Neben allen Diskussionen über das Klassendesign, ist es doch aus interessant, wie das Labyrint überhaupt gespeichert werden soll.
Oder anders gefragt: Was ist die "Position" einer Mauer und was ist die "Position" eines Spielers?
Auf einem karierten Blatt Papier würde ich die Mauern auf die Linien zeichnen und die Spieler in die Kästchen. Damit habe ich aber doch zwei unterschiedliche Arten von "Positionen".

Ein Kompromiss könnte sein, dass ich die "Linien" und "Kästchen" gemeinsam durchnummeriere - wie auf folgendem Bild:


```
0 1 2 3 4 5 6
0   -   -   -
1 |   |   |   |
2   -   -   -
3 |   |   |   |
4   -   -   -
5 |   |   |   |
6   -   -   -
```

Dann sind aber für bestimmte "Teile" nur bestimmte Positionen erlaubt:

waagerechte Mauern: (gerade x ungerade)
senkrechte Mauern: (ungerade x gerade)
Spieler-Position: (ungerade x ungerade)
nicht benutzt: (gerade x gerade)

Und dies sollte wiederum im Klassenmodell berücksichtigt werden!


----------



## jono (21. Aug 2020)

@JustNobody 

```
public enum Field {
    WALL,
    PATH,
    UNKNOWN;
    
    BaitType [] bait;
    int field[][];
    
}
```



JustNobody hat gesagt.:


> Also hast Du x mal y etwas vom Typ Feld. Wie kannst Du das abbilden? Kennst Du eine Datenstruktur, die dies erlaubt?
> 
> Und dann hast Du Felder. Ein Feld ist gekennzeichnet durch einen Typ. Und dann kann da etwas auf dem Feld sein. Da wäre dann eine Frage: Wie viele Elemente?
> - 0..1? (Also kein Element oder max 1 Element?)
> ...


1. Es hat sich ja herausgestellt, dass man x mal y etwas vom Typ Feld durch ein 2D-Array darstellen kann. Aber das Array, was ich dort habe erfüllt glaube ich noch nicht diese Anforderung, aber wenn ja warum?
2. Um dem Typ Feld auch baits zuzuordnen, sollte ein eindimensionales Array den Zweck erfüllen. Ist das korrekt so, wie im Code?


----------



## jono (21. Aug 2020)

@fhoffmann 
Okay, mal angenommen ich übernehme deine Konventionen so, wie auf deinem Bild. Wie sage ich denn jetzt der Klasse Maze spezifisch das waagerechte Mauern (gerade x ungerade ist) und senkrechte Mauern (ungerade x gerade) ? Außerdem haben wir für den Player jetzt eine Instanzvariable des Typs Position erstellt. Da fällt es mir schwer zu verstehen, wie ich das unten Zitierte jetzt implementieren kann, weiß das nicht einzuordnen. 


fhoffmann hat gesagt.:


> Spieler-Position: (ungerade x ungerade)


----------



## fhoffmann (21. Aug 2020)

jono hat gesagt.:


> Da fällt es mir schwer zu verstehen, wie ich das unten Zitierte jetzt implementieren kann


Du hast dafür verschiedene Möglichkeiten:
Die Klasse Position könnte eine Methode haben wie `boolean isValidForPlayer()`
Oder die Klasse Player könnte dies abfangen in der Methode `void setPosition(Position position) throws IllegalArgumentException`
Oder die Klasse Maze regelt das...


----------



## jono (21. Aug 2020)

Okay, mal angenommen ich mache das jetzt mit deiner 2. vorgeschlagenen Möglichkeit. Konkret:
Zuerst muss ich eine doppelte (z.B. if-Schleife) implementieren, in der ersten sage ich (wenn x (=Spalte)) gerade ist (mithilfe vom Modulo), dann werfe Exception und wenn y gerade ist ebenfalls dasselbe oder ? @fhoffmann


----------



## jono (21. Aug 2020)

Das Prinzip müsste ich dann ziemlich so auch für Wände und Wege implementieren.


----------



## fhoffmann (21. Aug 2020)

jono hat gesagt.:


> doppelte (z.B. if-Schleife)


"if-Schleifen" gibt es nicht und die If-Bedingung muss auch nicht doppelt sein:

```
if(x % 2 == 1 && y % 2 == 1) {
  // ok
} else {
  // Exception
}
```


----------



## fhoffmann (21. Aug 2020)

jono hat gesagt.:


> Das Prinzip müsste ich dann ziemlich so auch für Wände und Wege implementieren.


Für Wände musst du es analog implementieren.
Ob du überhaupt "Wege" benötigst, möchte ich bezweifeln. Ein Player kann nach Norden gehen, wenn sich nördlich von ihm keine Wand befindet. Wozu dann noch "Wege" einführen?


----------



## jono (21. Aug 2020)

Ja, stimmt da schließt das eine das andere aus.


----------



## jono (21. Aug 2020)

x und y Kennt die Klasse Player nicht, einfach neue Variablen anlegen oder x und y als int-Parameter in die Methode?


fhoffmann hat gesagt.:


> if(x % 2 == 1 && y % 2 == 1) { // ok } else { // Exception }


@fhoffmann


----------



## mrBrown (21. Aug 2020)

fhoffmann hat gesagt.:


> Neben allen Diskussionen über das Klassendesign, ist es doch aus interessant, wie das Labyrint überhaupt gespeichert werden soll.
> Oder anders gefragt: Was ist die "Position" einer Mauer und was ist die "Position" eines Spielers?
> Auf einem karierten Blatt Papier würde ich die Mauern auf die Linien zeichnen und die Spieler in die Kästchen. Damit habe ich aber doch zwei unterschiedliche Arten von "Positionen".


Es ist ein Beispiel gegeben:


```
MAZE;20;10 
-------------------- 
-##################- 
-#................#- 
-#.###.#.###.##.#.#- 
-#...###..#..#..#.#- 
-#.#.........#..#.#- 
-#.#########.#.##.#- 
-#................#- 
-##################- 
--------------------
```


----------



## mrBrown (21. Aug 2020)

jono hat gesagt.:


> @mrBrown
> Wie war das nochmal mit der Instanzbildung von enums? Denn um das enum "viewDir" mit der Klasse Player zu verbinden, muss
> ich ja in der Klasse Player eine Instanzvariable erzeugen von "viewDir".


Die Instanzen sind "einfach da", kannst über KlassenName.WERT darauf zugreifen.


----------



## jono (21. Aug 2020)

Was verändert das jetzt an dem vorherig Besprochenem mit @fhoffmann


mrBrown hat gesagt.:


> Es ist ein Beispiel gegeben:


Okay, ist das denn überhaupt erforderlich auf die Werte zuzugreifen?


mrBrown hat gesagt.:


> Die Instanzen sind "einfach da", kannst über KlassenName.WERT darauf zugreifen.


@mrBrown


----------



## mrBrown (21. Aug 2020)

jono hat gesagt.:


> Was verändert das jetzt an dem vorherig Besprochenem mit @fhoffmann



Das ist eine andere und deutlich einfachere Darstellung, als die von @fhoffmann vorgeschlagene. Alles, was sich auf diese Darstellung bezogen hat, brauchst du nicht.



jono hat gesagt.:


> Okay, ist das denn überhaupt erforderlich auf die Werte zuzugreifen?


Keine Ahnung was du meinst. Wenn du auf einen Wert nicht zugreifen bräuchtest, bräuchtest du den Wert nicht – also ja, irgendwie ist es schon erforderlich, auf irgendwelche Werte zuzugreifen.


----------



## kneitzel (21. Aug 2020)

Nur noch kurz zurück zu der Idee, die ich aufgebracht hatte:
Die Enumeration wäre FieldType oder so. Generell ist bei einer Enumeration aus meiner Sicht darauf zu achten, dass man halt konstante Instanzen hat. Also ich vermeide immer, da irgendwas einzubauen, das veränderlich ist.
Dann gibt es eine Klasse Field. Diese Klasse hat dann z.B. eine Instanzvariable FieldType, die angibt, was für ein Feld es sein soll sowie die Baits (Also als List<Bait> oder so).

Das wäre dann der grobe Aufbau.

Dann kann man sich noch überlegen, wo welche Informationen noch hinzu kommen. FieldType könnte z.B. ein boolean enthalten, der angibt, ob ein Spieler auf so ein Feld kann. Denn das ist eine Information die aus meiner Sicht eher da hin gehören würde.

Aber das waren halt nur ein paar Ideen von meiner Seite, die jetzt ggf. schon überholt sind, da Du einen anderen Weg eingeschlagen hast oder so ...


----------



## jono (21. Aug 2020)

mrBrown hat gesagt.:


> Das ist eine andere und deutlich einfachere Darstellung, als die von @fhoffmann vorgeschlagene. Alles, was sich auf diese Darstellung bezogen hat, brauchst du nicht.


1. Okay, aber wie sage ich jetzt wo Wände sind ? Das müsste ich dann trotzdem wissen. Wie würde sich das Labyrinth bei 30;10 z.B. verändern?
2. Wie sage ich jetzt einem Feld, welche Felder der Player betreten darf? @JustNobody



JustNobody hat gesagt.:


> Nur noch kurz zurück zu der Idee, die ich aufgebracht hatte:
> Die Enumeration wäre FieldType oder so. Generell ist bei einer Enumeration aus meiner Sicht darauf zu achten, dass man halt konstante Instanzen hat. Also ich vermeide immer, da irgendwas einzubauen, das veränderlich ist.
> Dann gibt es eine Klasse Field. Diese Klasse hat dann z.B. eine Instanzvariable FieldType, die angibt, was für ein Feld es sein soll sowie die Baits (Also als List<Bait> oder so).


@JustNobody Okay, also eine Enumeration <<FieldType>> und eine Klasse "Field" würden benötigt, um das so darzustellen. Ich merke schon, da steckt sehr objektorientiertes Denken drin. Ne, ich habe noch keinen anderen Weg eingeschlagen.
Ja gut, boolean PATH = true; wäre schonmal nicht richtig. Vielleicht ein Tipp noch dazu?



JustNobody hat gesagt.:


> Dann gibt es eine Klasse Field. Diese Klasse hat dann z.B. eine Instanzvariable FieldType, die angibt, was für ein Feld es sein soll sowie die Baits (Also als List<Bait> oder so).


Nochmal hierzu: Ja, aber wie mache ich das dann, sodass die Liste dem FieldType zugeordnet werden kann, sodass das z.B. FieldType "PATH" weiß, dass nur dort Baits liegen dürfen.


----------



## kneitzel (21. Aug 2020)

Also du kannst etwas bauen wie:


```
public enum FieldType {
  UNKNOWN(false),
  WALL(false),
  WAY(true);
 
  private boolean playerAllowed;
  public boolean isPlayerAllowed() { return playerAllowed; }
 
  FieldType(final boolean playerAllowed) { this.playerAllowed = playerAllowed; }
}
```

Die Werte UNKNOWN, WAY, WALL stammen jetzt von mir - ich habe nicht nachgesehen, wie es richtig heißen soll. Und da kann an natürlich noch die String Representation hinzu fügen wenn man möchte ...

Und wenn Field ein FieldType hat, dann kann man da jederzeit prüfen, ob ein Spieler auf das Feld kann über das isPlayerAllowed der Enumeration.

Das wäre so eine Idee von meiner Seite aus.


----------



## jono (24. Aug 2020)

JustNobody hat gesagt.:


> Dann gibt es eine Klasse Field. Diese Klasse hat dann z.B. eine Instanzvariable FieldType, die angibt, was für ein Feld es sein soll sowie die Baits (Also als List<Bait> oder so).


@JustNobody

```
public class Field {
   
    FieldType PATH;
   
}
```
WIe verknüpfe ich denn jetzt die Instanzvariable FieldType mit der List, sodass die List weiß, dass alle in ihr enthaltenen Baits dem FieldType PATH angehören?


----------



## mrBrown (24. Aug 2020)

jono hat gesagt.:


> WIe verknüpfe ich denn jetzt die Instanzvariable FieldType mit der List, sodass die List weiß, dass alle in ihr enthaltenen Baits dem FieldType PATH angehören?


:


JustNobody hat gesagt.:


> Dann gibt es eine Klasse Field. Diese Klasse hat dann z.B. eine Instanzvariable FieldType, die angibt, was für ein Feld es sein soll sowie die Baits (Also als List<Bait> oder so).


----------



## jono (24. Aug 2020)

Ja, ich habe eine Instanzvariable FieldType angelegt und diese weiß jetzt, dass sie als PATH definiert ist.
Doch wenn ich jetzt eine Liste anlege wie z.B. List<BaitType>, weil in der Enumeration BaitType die verschiedenen Baits aufgezählt sind, weiß die Instanzvariable FieldType PATH noch nicht, dass die in der Liste vorhandenen Baits dieser zuzuschreiben sind... 
@mrBrown


----------



## mrBrown (24. Aug 2020)

Leg doch einfach mal die Liste an und zeig dann den Code.


----------



## jono (24. Aug 2020)

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

public class Field {
   
    FieldType PATH;
    List<BaitType> baittypes = new ArrayList<BaitType>();
}
```
@mrBrown


----------



## mrBrown (24. Aug 2020)

Was denkst du macht `FieldType PATH;`?


----------



## jono (24. Aug 2020)

Dem Field sagen, dass es einen FieldType PATH hat, der ja true ist, nun will ich dem PATH sagen, dass sich nur auf diesem die Baits befinden können...


----------



## mrBrown (24. Aug 2020)

Damit sagst du nur, das Field eine Variable vom FieldType hat, die du "PATH" nennst, die aber bisher keinen Wert hat, effektiv steht da `FieldType PATH = null;`. Nur weil die Variable PATH heißt, hat die noch nichts mit dem Enum icode]FieldType.PATH[/icode] zu tun.


----------



## jono (24. Aug 2020)

Kannst du mir evtl. einen Hinweis geben, um das Problem beheben zu können?


----------



## mrBrown (24. Aug 2020)

Erstmal die Frage, warum sollte der FieldType wissen, welche Baits wo sind, und warum sollte irgendein Bait einen FieldType kennen?


----------



## jono (24. Aug 2020)

Der FieldType PATH sollte meiner Meinung keinen BaitType kennen aber, sollte wissen, dass sich auf dem FieldType PATH nur Baits verbergen können. Ich meine irgendwie muss man den Feldern ja sagen dass sie entweder Baits enthalten dürfen/oder eben auch nicht. Ansonsten könnten diese ja überall verteilt sein.


----------



## mrBrown (24. Aug 2020)

jono hat gesagt.:


> Der FieldType PATH sollte meiner Meinung keinen BaitType kennen aber, sollte wissen, dass sich auf dem FieldType PATH nur Baits verbergen können. Ich meine irgendwie muss man den Feldern ja sagen dass sie entweder Baits enthalten dürfen/oder eben auch nicht. Ansonsten könnten diese ja überall verteilt sein.


Ein Feld darf also nur Baits enthalten, wenn der FieldType PATH ist?


Wie fügst du denn aktuell überhaupt Baits zu einem Feld hinzu?


----------



## jono (24. Aug 2020)

mrBrown hat gesagt.:


> Ein Feld darf also nur Baits enthalten, wenn der FieldType PATH ist?


Ja, dass ein Spieler darf auch nur den FieldType PATH betreten bzw. macht es auch nur so Sinn, da das ja der Labyrinthweg ist. 


mrBrown hat gesagt.:


> Wie fügst du denn aktuell überhaupt Baits zu einem Feld hinzu?


Das ist ja das Problem, was ich gerade versuche zu lösen durch die List. Eine List enthält BaitTypes. Wie füge ich diese aber dem FieldType hinzu?


----------



## mrBrown (24. Aug 2020)

mrBrown hat gesagt.:


> Wie fügst du denn aktuell überhaupt Baits zu einem Feld hinzu?





jono hat gesagt.:


> Wie füge ich [BaitTypes] aber dem FieldType hinzu?



Siehst du den Unterschied zwischen deiner und meiner Frage?


----------



## jono (24. Aug 2020)

Ja, aber gemeint ist dasselbe von mir.
Natürlich sind alle BaitTypes zusammengefasst die Baits, welche aber nur einem FieldType zugeordnet werden sollen darum geht es mir. 
Es hieß ja ich solle am besten eine Klasse Field erstellen, das habe ich ja auch getan.


----------



## mrBrown (24. Aug 2020)

jono hat gesagt.:


> Ja, aber gemeint ist dasselbe von mir.


Zwischen Feld/Field und FieldType ist ein sehr großer Unterschied!



Um noch mal einen Schritt zurückzugehen:
Das Maze ist aufgebaut wie ein Schachbrett, es besteht aus mehreren einzelnen Feldern (=Field).
Wie bei einem Schachbrett hat jedes Feld einen Typen (=FieldType) – beim Schach zB Schwarz oder Weiß, bei dir Weg, Wand und unbekannt.
Auf einem Feld, wenn es den Typ Weg hat, können mehrere Baits (=BaitType) liegen. Oder andersausgedrückt: Wenn ein Feld den FeldTyp Weg hat, kann man Bait hinzufügen.
Wenn man ein Bait einem Feld mit dem Typ Wand hinzufügt, passiert entweder nichts oder es wird eine Fehler geworfen.


Das kann man im wesentlichen so runter programmieren.



Spoiler: Tipp 1



Der Typ kann sich für ein Feld nicht ändern, der wird direkt zu Beginn festgelegt - was eignet sich für sowas am besten





Spoiler: Tipp 2



Für die Baits eines Feldes sollte es *keinen* einfachen Getter geben


 


Spoiler: Tipp 3



Das Feld kann zB eine Methode _baitPlatzieren_ haben


----------



## kneitzel (24. Aug 2020)

Du hast aber doch viele Felder, die alle über eine Instanz vom Typ Field abgebildet werden sollen. Und diese Felder können FieldType.PATH sein oder eben auch von anderen Typen (Also z.B. FieldType.UNKNOWN oder was es da sonst so gibt).

Also hat ein Feld erst einmal keinen PATH.
Ein Feld hat einen FeldTypen und dieser kann PATH sein.


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

public class Field {
  
    FieldType fieldType;
    List<BaitType> baits = new ArrayList<BaitType>();
}
```

(Ich habe diese baittypes mal in baits umbenannt. Baits als solches gibt es eigentlich nicht, denn Du hast nur diese Types meine ich. Eine weitere Klasse gibt es nicht. Könnte man also auch entsprechend umbenennen.)

Nun könntest Du also eine Methode addBait(BaitType bait) machen. Diese sollte man aber nur auf einem Feld vom typ PATH ablegen können. Und den Erfolg könnte man über einen Return-Wert zurück geben ... Das könnte man prüfen. Falls Du den FieldType mit gewisser Logik implementiert hast, dann weiß ein Typ, ob ein Spieler ein Feld von dem typ betreten könnte. Das könnte man dann als Logik ebenfalls nutzen statt dem starren beharren auf PATH. Falls es später weitere Typen gibt, die ein Spieler ggf. auch betreten kann, dann hast Du sonst das Problem, da die Logik Stellen alle zu finden, die Du anpassen müsstest ....)


```
public boolean addBait(final BaitType bait) {
  // Prüfe, ob der Typ passt. Ggf. false zurück geben!
  // Füge bait dem feld hinzu
  // true zurück geben
}
```

Also in den Kommentaren habe ich die Funktionalität geschrieben. Würdest Du dies so hin bekommen?


----------



## jono (24. Aug 2020)

Nein, weiß ich nicht direkt. Im Prinzip kann man ja in natürlicher Sprache sagen, dass wenn die Position des Baits der Position des FieldTypes PATH entspricht, dass bait der Position des PATH hinzugefügt werden kann und true returnt.


JustNobody hat gesagt.:


> Falls Du den FieldType mit gewisser Logik implementiert hast, dann weiß ein Typ, ob ein Spieler ein Feld von dem typ betreten könnte. Das könnte man dann als Logik ebenfalls nutzen statt dem starren beharren auf PATH.


In der Methode "isplayerAllowed" in der enumeration die du mir auf Seite 5 genannt hast, könnte man dies machen oder? Könnte doch aber auch in der Klasse Field festlegen, ob ein Spieler ein feldtyp betreteten darf oder nicht?


----------



## jono (24. Aug 2020)

JustNobody hat gesagt.:


> public boolean addBait(final BaitType bait) { // Prüfe, ob der Typ passt. Ggf. false zurück geben! // Füge bait dem feld hinzu // true zurück geben }


Wie prüfe ich, ob die position des baits der position des PATH entspricht.


----------



## mrBrown (24. Aug 2020)

Du denkst viel zu Kompliziert. Weder ein PATH noch ein Bait hat eine Position.

Es gibt Felder.
Wenn ein Feld den Typ PATH hat, kann man einen Bait hinzufügen.

Dafür brauchst du eine einzelne Methode, die Signatur wurde dir schon genannt, und in der Methode nur ein if und darin einen Methodenaufruf.


----------



## jono (24. Aug 2020)

Ich komme einfach nur nicht klar gerade mit dem genauen Codieren.
Warum brauche ich noch einen Methodenaufruf in der Methode?
Wie kann man denn einfach mal überprüfen, ob das Feld den Typ PATH hat.Das ist das erste "große" Projekt, was applikationsspezifisch erstellt werden muss(was jede Aufgabe prinzipiell muss) aber in diesem Rahmen ist es noch schwieriger und erfordert genau und gesetzten Code, um die Aufgabe als solche korrekt zu bearbeiten
Ich bitte da echt um Verständnis. Ich verstehe ja, was ich machen soll, nur teilweise fehlen mir die genauen Sprachbefehle. If-Anweisung ist ja klar...


----------



## mrBrown (25. Aug 2020)

jono hat gesagt.:


> Wie kann man denn einfach mal überprüfen, ob das Feld den Typ PATH hat.


Wenn wir jetzt einfach mal von dem Code von @JustNobody ausgehen:

Der Typ des Feldes steht in der Variable `fieldType`. Um zu prüfen, ob diese PATH ist: `this.fieldType == FieldType.PATH`.



jono hat gesagt.:


> Das ist das erste "große" Projekt, was applikationsspezifisch erstellt werden muss(was jede Aufgabe prinzipiell muss) aber in diesem Rahmen ist es noch schwieriger und erfordert genau und gesetzten Code, um die Aufgabe als solche korrekt zu bearbeiten



Große Projekte muss man einfach nur in kleine Teile aufteilen - an diesem Problem jetzt sind zB grad mal drei verschiedene Klassen beteiligt, und zwei davon sind schlichte Enums


----------



## jono (25. Aug 2020)

mrBrown hat gesagt.:


> Der Typ des Feldes steht in der Variable `fieldType`.


Ouhman, habe die Instanzvariable von FieldType gar nicht mehr in Betracht gezogen. Danke 



mrBrown hat gesagt.:


> Große Projekte muss man einfach nur in kleine Teile aufteilen. An diesem Problem jetzt grad sind grad mal drei verschiedene Klassen beteiligt, und zwei davon sind schlichte Enums


Ja deshalb hatte ich meinen Beitrag #117 nochmal bearbeitet, weil das mit den vielen Klassen nicht stimmte 


```
public class Field {

    FieldType fieldType;
    List<BaitType> baittypes = new ArrayList<BaitType>();

    public boolean addBait(final BaitType bait) {
        if (this.fieldType == FieldType.PATH) {
            baittypes.add(bait);
        } else {
            return false;
        }
        return true;
    }
}
```
Das wäre der Code bis jetzt, jedoch:
baittypes.add(bait) erfüllt ja nicht genau das was @JustNobody sagte:


JustNobody hat gesagt.:


> // Füge bait dem feld hinzu


Bei mir wird es ja nur der Liste inzugefügt, wie spezifiziere ich das jetzt?


----------



## mrBrown (25. Aug 2020)

jono hat gesagt.:


> baittypes.add(bait) erfüllt ja nicht genau das was @JustNobody sagte:
> 
> 
> JustNobody hat gesagt.:
> ...


Die Liste *ist Teil des Feldes*.


----------



## jono (25. Aug 2020)

Deshalb habe ich gerade nochmal den PC hochgefahren, weil mir das auch eingefallen ist vor dem Einschlafen^^


jono hat gesagt.:


> List<BaitType> baittypes = new ArrayList<BaitType>();


Dementsprechend müsste man dies in:

```
List<FieldType> fieldTypes = new ArrayList<FieldType>();
```
umändern, oder habe ich das  jetzt selbstsicher falsch umgeändert?


----------



## jono (25. Aug 2020)

Aber dann würde die add Funktion nicht mehr so funktionieren wie sie hier steht:

```
List<FieldType> fieldTypes = new ArrayList<FieldType>();

    public boolean addBait(final BaitType bait) {
        if (this.fieldType == FieldType.PATH) {
            fieldTypes.add(bait);
        } else {
            return false;
        }
        return true;
```


----------



## mrBrown (25. Aug 2020)

jono hat gesagt.:


> Dementsprechend müsste man dies in:
> 
> ```
> List<FieldType> fieldTypes = new ArrayList<FieldType>();
> ...


Das ist Unsinn..

Ein Feld hat *einen Feld-Typen* und *mehrere Baits* -> FieldType als eine Variable und eine Liste von Baits als eine andere Variable.



Wie kommst du denn darauf, dass ein Feld eine Liste von Typen hat? Soll ein Feld gleichzeitig Weg und Wand sein?


----------



## jono (25. Aug 2020)

Ja stimmt  Jetzt weiß ich echt nicht weiter...


----------



## mrBrown (25. Aug 2020)

jono hat gesagt.:


> Ja stimmt  Jetzt weiß ich echt nicht weiter...



Dann geh mal einen Schritt zurück und überleg was du schon hast und was du als nächstes brauchst.


----------



## jono (25. Aug 2020)

jono hat gesagt.:


> ```
> public class Field {
> FieldType fieldType;
> List<BaitType> baittypes = new ArrayList<BaitType>();
> ...


Dann muss das ja korrekt sein ??

Weil es ja hieß:


mrBrown hat gesagt.:


> Ein Feld hat *einen Feld-Typen* und *mehrere Baits* -> FieldType als eine Variable und eine Liste von Baits als eine andere Variable.


Es heißt ja dass ein feld einen Feld-Typen hat und mehrere Baits.
Einen Feld-Typen hat es ja durch die Variable "FieldType" und durch die BaitType Liste wird dem Feld ja ein bzw. mehrere Baits hinzugefügt.


----------



## mrBrown (25. Aug 2020)

jono hat gesagt.:


> Dann muss das ja korrekt sein ??


Das hinzufügen der Baits ist korrekt.


Allerdings ist fieldType aktuell immer null, das solltest du ändern (und auch die Variablen private machen).


----------



## jono (25. Aug 2020)

mrBrown hat gesagt.:


> Allerdings ist fieldType aktuell immer null


Ich versuche das mal zu ändern


----------



## Plauzi92 (25. Aug 2020)

Als jemand der die gleiche Aufgabe lösen muss, hätte ich hier einen Tipp:



> Der FieldType PATH sollte meiner Meinung keinen BaitType kennen aber, sollte wissen, dass sich auf dem FieldType PATH nur Baits verbergen können. Ich meine irgendwie muss man den Feldern ja sagen dass sie entweder Baits enthalten dürfen/oder eben auch nicht. Ansonsten könnten diese ja überall verteilt sein.



Alle Positionen werden dir vom Server übermittelt. Lass dir mal die Ausgaben vom Server in die Konsole schreiben, dann sollte es klar sein. Der Server wird dir kein Bait in eine Mauer legen. Du musst das alles nur in JavaFX darstellen. Lediglich die Spielerbewegung führt zu einer Überprüfung.
Auch wenn der Prof sagte, dass man mit dem StatusModel anfangen sollte, kann es nicht schaden sich vorher mal über das Gesamtkonzept Gedanken zu machen.


----------



## jono (25. Aug 2020)

Stimmt so nicht, was du sagst. Trotzdem muss man es überprüfen.


----------



## Plauzi92 (25. Aug 2020)

> Stimmt so nicht, was du sagst. Trotzdem muss man es überprüfen.


Dann sag mir bitte mal wozu du die Position der Baits auf eine Mauer überprüfen musst.


----------



## jono (25. Aug 2020)

Plauzi92 hat gesagt.:


> Dann sag mir bitte mal wozu du die Position der Baits auf eine Mauer überprüfen musst.


Es kann passieren dass man im Client etwas falsch programmiert oder irgendetwas was dafür sorgt dass ein Bait in einer Wand landet.


----------



## jono (25. Aug 2020)

Von vornerein kann man das dann damit verhindern in GameStatusModel


----------



## Plauzi92 (25. Aug 2020)

Also willst du die Informationen die vom Server kommen überprüfen, falls du sie im Client falsch interpretierst? Finde ich jetzt nicht wirklich sinnvoll. Wenn du die Koordinaten der Baits einfach vom Server übernimmst, werden sie nicht in einer Wand landen.


----------



## jono (25. Aug 2020)

Ja, gut aber ist jetzt kein Code der Punkte abzieht, kann da ja jeder machen wie er möchte


----------



## mrBrown (25. Aug 2020)

Plauzi92 hat gesagt.:


> Dann sag mir bitte mal wozu du die Position der Baits auf eine Mauer überprüfen musst.


Defensive Programmierung und kenntlich machen von Constraints wären zwei Punkte dafür


----------



## Plauzi92 (25. Aug 2020)

> Defensive Programmierung und kenntlich machen von Constraints wären zwei Punkte dafür



Indem ein Bait über die zugehörige Klasse erstellt wird, ist dessen Position doch klar definiert. Wenn der Server ein Bait in einer Mauer erstellt, ist es eigentlich ziemlich egal was im Client passiert, da es keine Möglichkeit gibt dem Server mitzuteilen, dass das Bait an einer falschen Position ist.
Es wird durch die Überprüfung lediglich verhindert, dass das Bait gezeichnet wird. Tatsächlich liegt es aber dennoch in der Mauer. Deswegen finde ich die Überprüfung irrelevant. Aber wie Jono schon sagte:



> Ja, gut aber ist jetzt kein Code der Punkte abzieht, kann da ja jeder machen wie er möchte


----------



## jono (25. Aug 2020)

```
private FieldType fieldType = FieldType.PATH;
```
@mrBrown Wie weise ich jetzt noch die anderen 2 Feldtypen UNKNOWN und WALL der Variable zu, sodass diese nicht mehr null ist?

```
fieldType = FieldType.WALL;
fieldType = FieldType.UNKNOWN;
```
das ist ja schonmal falsch.


----------



## kneitzel (25. Aug 2020)

Um Augenblick verstehe ich nicht, was Dein Problem ist.

Ein Feld hat genau einen FieldType. Den FieldType kannst du im Konstruktor setzen oder über einen Setter.

Wenn du das Maze aufbaust, dann wirst du vermutlich viele Felder erstellen. Und das abhängig von dem Zeichen, das für das jeweilige Feld vorgesehen ist ....


----------



## jono (25. Aug 2020)

JustNobody hat gesagt.:


> Um Augenblick verstehe ich nicht, was Dein Problem ist.
> 
> Ein Feld hat genau einen FieldType. Den FieldType kannst du im Konstruktor setzen oder über einen Setter.
> 
> Wenn du das Maze aufbaust, dann wirst du vermutlich viele Felder erstellen. Und das abhängig von dem Zeichen, das für das jeweilige Feld vorgesehen ist ....





mrBrown hat gesagt.:


> Ein Feld hat *einen Feld-Typen* und *mehrere Baits* -> FieldType als eine Variable und eine Liste von Baits als eine andere Variable.


1. Es ging doch jetzt darum in der Klasse Field eine Instanzvariable zu erstellen, da diese ja FieldTypes hat? Diese Variable sollte nicht null sein?
2. Um diese Variable nicht null sein zu lassen habe ich sie so instanziiert.
Wie ist das jetzt genau gemeint, den FieldType im Konstruktor zu setzen, welchen Zweck erfüllt das denn?


----------



## kneitzel (25. Aug 2020)

Du kannst einem Konstruktor Parameter mitgeben um dann die neue Instanz entsprechend zu initialisieren.

Wenn du Field einen Konstruktor gibst, der ein FieldType entgegen nimmt, dann könntest du die Instanzvariable entsprechend setzen.

Oder du übergibst den String, den der Server für das Feld vorgibt, um dann in Abhängigkeit vom String den Typ zu setzen.

Und dann hatte ich, so ich mich recht erinnere, auch schon geschrieben, wie man diese Auswahl Logik sogar in den FieldType verlegen kann (so man das möchte).


----------



## jono (25. Aug 2020)

JustNobody hat gesagt.:


> Wenn du Field einen Konstruktor gibst, der ein FieldType entgegen nimmt, dann könntest du die Instanzvariable entsprechend setzen.





JustNobody hat gesagt.:


> Oder du übergibst den String, den der Server für das Feld vorgibt, um dann in Abhängigkeit vom String den Typ zu setzen.


Also kann ich es jetzt so oder so machen?



JustNobody hat gesagt.:


> Wenn du Field einen Konstruktor gibst, der ein FieldType entgegen nimmt, dann könntest du die Instanzvariable entsprechend setzen.


Kann man in einer Klasse einen Konstruktor erstellen, der Werte von dem enum entgegen nimmt, wusste ich auch noch nicht.
Wie genau soll das dann aber jetzt aussehen, was meinst du mit:


JustNobody hat gesagt.:


> dann könntest du die Instanzvariable entsprechend setzen.


Die Instanzvariable kann man doch auch ohne Konstruktor setzen/erstellen ? ^^



JustNobody hat gesagt.:


> Und dann hatte ich, so ich mich recht erinnere, auch schon geschrieben, wie man diese Auswahl Logik sogar in den FieldType verlegen kann (so man das möchte).


In Beitrag #113, stimmt's?


----------



## jono (25. Aug 2020)

Verstehe jetzt nicht, warum ich da den Konstruktor jetzt einbauen soll usw.


----------



## mrBrown (25. Aug 2020)

Plauzi92 hat gesagt.:


> Indem ein Bait über die zugehörige Klasse erstellt wird, ist dessen Position doch klar definiert. Wenn der Server ein Bait in einer Mauer erstellt, ist es eigentlich ziemlich egal was im Client passiert, da es keine Möglichkeit gibt dem Server mitzuteilen, dass das Bait an einer falschen Position ist.
> Es wird durch die Überprüfung lediglich verhindert, dass das Bait gezeichnet wird. Tatsächlich liegt es aber dennoch in der Mauer. Deswegen finde ich die Überprüfung irrelevant. Aber wie Jono schon sagte:


Das ist weder gegen das explizite im Code erwähnen der Constrainst ein Argument, noch gegen defensive Programmierung 

Natürlich kann man es auch ohne die Überprüfung lösen, aber damit hat man halt einmal explizit auch im Client stehen, wo Baits liegen können, und zusätzlich sichert man sich gegen eigene Fehler und gegen Fehler des Servers ab.
Es ist eben eine zusätzliche Sicherheit - auch wenn man dann zur Laufzeit nur durch eine Fehlermeldung darauf reagieren kann.

Man könnte auch genausogut sagen, das Client ist "dumm", zum bestehen reicht das sicherlich auch aus, aber man macht sowas ja nicht nur zum Bestehen


----------



## mrBrown (25. Aug 2020)

jono hat gesagt.:


> Verstehe jetzt nicht, warum ich da den Konstruktor jetzt einbauen soll usw.


Kann ein Feld ohne Typ existieren? => Nein, also muss es bereits im Konstruktor gesetzt werden.
Kann sich der Feld-Typ zur Laufzeit ändern? => Nein, also muss es im Konstruktor auf den passenden Wert gesetzt werden.


----------



## kneitzel (25. Aug 2020)

Du hast doch ein Maze, welches aus n reihen mit jeweils m Feldern bestehen soll.
Diese ganzen Felder musst Du ja erzeugen und mit entsprechenden Werten versehen. Wenn also das Feld an Position 2,3 ein PATH Feld sein soll, dann könntest Du
a) Das Feld erzeugen und direkt initialisieren. Also ein Aufruf wie new Field(FieldType.PATH) oder new Field(".") denkbar, um eine entsprechende Field Instanz zu erzeugen.
b) Wenn Du es nicht über den Konstruktor setzen willst, dann ginge es über ein Setter. Dann hättest Du etwas wie:
Field field = new Field();
field.setType(FieldType.PATH);

Dem Field ein Setter für den Type mitzugeben würde aber nur Sinn machen, wenn sich der Type eines Fields auch ändern kann / soll. Aber das Maze ist ja konstant. Aus einem PATH wird kein WALL und kein UNKNOWN. Daher macht das mit dem Setter keinen Sinn in meinen Augen. Desweiteren sind es zwei Zeilen, wo eine direkte Zuweisung ausreichen würde (Also z.B. field[x][y] = new Field(encodedFieldChar); wobei encodedFieldChar ein Zeichen des Maze sein könnte ... ).

Aber technisch gehen natürlich beide Lösungen.


----------



## jono (25. Aug 2020)

JustNobody hat gesagt.:


> Desweiteren sind es zwei Zeilen, wo eine direkte Zuweisung ausreichen würde (Also z.B. field[x][y] = new Field(encodedFieldChar); wobei encodedFieldChar ein Zeichen des Maze sein könnte ... ).


Wie du das jetzt meintest, habe ich nicht verstanden. Wirkt irgendwie zusammenhangslos, deshalb konnte ich es jetzt nicht in dem Kontext verstehen wo das hin soll und was es erfüllt?


```
private Field(FieldType fieldType, List<BaitType> baittypes) {
        this.fieldType = fieldType;
        this.baittypes = baittypes;
    }
```
Wäre der Konstruktor so richtig gesetzt?


----------



## Plauzi92 (25. Aug 2020)

@mrBrown 
Es klang für mich in den vorherigen Posts so, als denke der TE, dass die Baits ( bzw. deren Positionen) vom Client festgelegt werden und deswegen eine Überprüfung stattfinden muss. Natürlich kann man das noch zusätzlich überprüfen um eine Fehlermeldung auszugeben. Für die Funktionsweise an sich, ist es aber erstmal nicht nötig. Daher auch die Frage wofür denn die Überprüfung stattfinden soll


----------



## kneitzel (25. Aug 2020)

jono hat gesagt.:


> Wie du das jetzt meintest, habe ich nicht verstanden. Wirkt irgendwie zusammenhangslos, deshalb konnte ich es jetzt nicht in dem Kontext verstehen wo das hin soll und was es erfüllt?



Du solltest versuchen, auch die Nutzung von Field im Blick zu behalten. Das was du entwickelst, ist doch kein Selbstzweck! Das soll doch irgendwie verwendet werden!

Das, was Du an Funktionalität benötigst musst Du implementieren. Nicht mehr aber auch nicht weniger!

Wenn Dir da also der Überblick fehlt, dann solltest Du Dir diesen als erstes erarbeiten. Ansonsten macht es gar keinen Sinn, sich über z.B. Field zu unterhalten. 



jono hat gesagt.:


> ```
> private Field(FieldType fieldType, List<BaitType> baittypes) {
> this.fieldType = fieldType;
> this.baittypes = baittypes;
> ...


Das wäre korrekt, wenn Du bei Erstellung von Fields auch schon eine Liste von baittypes zur Hand hättest.  Ist das die Verwendung, die du brauchst? Überleg doch, wie Du Field nutzen willst: Wo werden die wie gespeichert? Wie werden die wann erzeugt?


----------



## jono (25. Aug 2020)

JustNobody hat gesagt.:


> Das wäre korrekt, wenn Du bei Erstellung von Fields auch schon eine Liste von baittypes zur Hand hättest. Ist das die Verwendung, die du brauchst? Überleg doch, wie Du Field nutzen willst: Wo werden die wie gespeichert? Wie werden die wann erzeugt?


Fields werden in der Klasse Maze gespeichert in dem Instanzen von dieser Klasse erzeugt.


----------



## jono (25. Aug 2020)

JustNobody hat gesagt.:


> Das wäre korrekt, wenn Du bei Erstellung von Fields auch schon eine Liste von baittypes zur Hand hättest.


Eine Liste zur Hand hättest, wie erstellt man denn dMn eine Liste von baittypes die man zur Hand hat?


----------



## kneitzel (25. Aug 2020)

jono hat gesagt.:


> Eine Liste zur Hand hättest, wie erstellt man denn dMn eine Liste von baittypes die man zur Hand hat?


Das ist einfache Umgangssprache.

Wenn du das Field erzeugt, dann musst du bei dem von dir vorgeschlagenen Konstruktor auch eine Liste mit übergeben.

Nun schau dir die Anforderungen  an:
Wie bekommst du welche Informationen vom Server? Was bekommst du, wenn du nach dem Maze fragst? Was kannst du mit diesen Informationen machen?


----------



## jono (25. Aug 2020)

JustNobody hat gesagt.:


> Wenn du das Field erzeugt, dann musst du bei dem von dir vorgeschlagenen Konstruktor auch eine Liste mit übergeben.


Ich habe dem Konstruktor von mir doch die Liste übergeben?



JustNobody hat gesagt.:


> Nun schau dir die Anforderungen an:
> Wie bekommst du welche Informationen vom Server? Was bekommst du, wenn du nach dem Maze fragst? Was kannst du mit diesen Informationen machen?


Informationen vom Server bekomme ich, in dem ich Nachrichten an diesen sende. Wenn ich nach dem Maze frage, bekomme ich eine gesamte Spielfeldbeschreibung. Der Server sendet außerdem Informationen über die sichtbaren Objekte, über die Spieler, ihre Positions und Scores. Und der Server überträgt die Position eines Objekts. Diese Informationen kann ich in meinen Klassen aufnehmen??


----------



## jono (25. Aug 2020)

Ich weiß nicht worauf du hinaus willst, was soll ich mit diesen Informationen machen können. Ich bekomme sie geschickt, sie müssen natürlich in das UI übertragen werden den CommandHandler einem Befehl geben welcher dann GameStatusModel aktualisiert.


----------



## Plauzi92 (25. Aug 2020)

> Nun schau dir die Anforderungen an:
> Wie bekommst du welche Informationen vom Server? Was bekommst du, wenn du nach dem Maze fragst? Was kannst du mit diesen Informationen machen?





> Ich weiß nicht worauf du hinaus willst, was soll ich mit diesen Informationen machen können. Ich bekomme sie geschickt, sie müssen natürlich in das UI übertragen werden den CommandHandler einem Befehl geben welcher dann GameStatusModel aktualisiert.




Schau mal in den Exam-Task Seite 16. Unter "Example" kommt die Serverantwort nach dem du "MAZ?" gesendet hast.
Dieses Rechteck aus Hashtags und Punkten ist das Labyrinth. Unter dem Punkt "Description" steht welches Symbol was darstellen soll. Dementsprechend setzt du für Hashtags eine Mauer und für Punkte eben nicht.
Wenn ich deinen Code richtig verstehe willst du für alle Felder ein neues "Field" erzeugen. Dann setzt du beim erzeugen deinen FieldType entsprechend entweder auf PATH oder auf WALL.
Ich persönlich würde einfach Instanzen vom Typ Wall (oder wie auch immer du es nennen willst) erzeugen die die entsprechende Position erhalten. Dann kannst du beim setzen der Baits trotzdem noch testen ob sich da eine Wand befindet oder nicht. 
Ich hab nicht so ganz verstanden was du mit FieldTyp erreichen willst. Das einzige was den Typ WALL von PATH unterscheidet ist, ob da ein Spieler/Bait 
sein kann oder nicht. Das heißt du überprüfst beim Setzen entweder _"Ist das eine Mauer? -> Nicht setzen"_ oder _"Ist das ein Weg? -> Setzen"_. (Oder die Negationen hiervon) 
Je nachdem auf welchen Typ du prüfst, ist der andere in meinen Augen unnötig.


----------



## mrBrown (25. Aug 2020)

Plauzi92 hat gesagt.:


> Ich hab nicht so ganz verstanden was du mit FieldTyp erreichen willst. Das einzige was den Typ WALL von PATH unterscheidet ist, ob da ein Spieler/Bait
> sein kann oder nicht. Das heißt du überprüfst beim Setzen entweder _"Ist das eine Mauer? -> Nicht setzen"_ oder _"Ist das ein Weg? -> Setzen"_. (Oder die Negationen hiervon)
> Je nachdem auf welchen Typ du prüfst, ist der andere in meinen Augen unnötig.



Der FieldTyp dient doch genau dazu, damit sind die Abfragen "Ist das eine Mauer" und "Ist das ein Weg?" möglich.


----------



## jono (25. Aug 2020)

Ich bin sehr verwirrt bei den vielen Threads jetzt. Wäre evtl. besser wenn @JustNobody Mir die Antwort gibt, ich will verstehe deinen Thread nicht @Plauzi92


----------



## jono (25. Aug 2020)

Plauzi92 hat gesagt.:


> Dann setzt du beim erzeugen deinen FieldType entsprechend entweder auf PATH oder auf WALL.
> Ich persönlich würde einfach Instanzen vom Typ Wall (oder wie auch immer du es nennen willst) erzeugen die die entsprechende Position erhalten. Dann kannst du beim setzen der Baits trotzdem noch testen ob sich da eine Wand befindet oder nicht.


Habe doch schon eine Instanz vom FieldType PATH erzeugt. Die Frage war eben ,wie ich die anderen 2 noch erzeuge. 
Ich brauche doch gar nicht zu prüfen, ob da eine Wand ist, denn Donald ein weg da ist, wird das bait doch gesetzt???
Wäre echt sehr dankbar wenn mich winter aufklärt,Weil ich grade echt nicht mehr weiß, wie ich writer vorgehen soll bzw. warum ich jetzt aufeinmal ein Konstruktor erzeugen soll


----------



## Plauzi92 (25. Aug 2020)

mrBrown hat gesagt.:


> Der FieldTyp dient doch genau dazu, damit sind die Abfragen "Ist das eine Mauer" und "Ist das ein Weg?" möglich.


Ist an der Position (X/Y) ein Objekt Field mit dem Typ "WALL"? -> Ja? -> Nicht setzen
Ist an der Position (X/Y) ein Objekt Wall? ->Ja? -> Nicht setzen

Macht doch absolut keinen Unterschied, nur dass man sich bei letzterer Variante den FieldType spart. 




jono hat gesagt.:


> Wäre echt sehr dankbar wenn mich winter aufklärt,Weil ich grade echt nicht mehr weiß, wie ich writer vorgehen soll bzw. warum ich jetzt aufeinmal ein Konstruktor erzeugen soll



Den Konstruktor bräuchtest du doch auch ohne FieldType damit du der Instanz vom Typ Field die Position direkt mitgeben kannst.


----------



## jono (25. Aug 2020)

Plauzi92 hat gesagt.:


> Den Konstruktor bräuchtest du doch auch ohne FieldType damit du der Instanz vom Typ Field die Position direkt mitgeben kannst.


Was willst du Mir damit sagen, warum brauche ich eine Instanz vom see Klasse Field oder was meinst du mit "Typ Field"? Und wie Gebe ich jetzt genau einem Feld die Position mit?
Wäre echt nett wenn mich Mal einer richtig aufklärt , ich verstehe das hier Gerade nicht was ich zu tun habe


----------



## Plauzi92 (25. Aug 2020)

jono hat gesagt.:


> Was willst du Mir damit sagen, warum brauche ich eine Instanz vom see Klasse Field oder was meinst du Mir "Typ Field"? Und wie Gebe ich jetzt genau einem Feld die Position not?


Du hast doch eine Klasse Field oder nicht? Aus dieser werden die Instanzen (also im Prinzip deine einzelnen Mauern und Wege) erstellt. Jede dieser Mauern/Wege hat einen X Wert und einen Y Wert woraus sich die genau Position in dem Labyrinth ergibt. Position (0|0) wäre demnach oben links in der Ecke.
Außerdem hast du den FieldType. Das kann ein String, oder ein Integer ( 0 für Weg, 1 für Mauer) oder auch irgendwas anderes sein, dass dir gefällt und Sinn macht.

Wenn du also ein neues Field erstellst, kannst du durch den Konstruktor direkt die Parameter mitgeben.

Die Klasse Field sähe dann so aus:


```
public class Field {
private int PositionX, PositionY;
private String Type;

public Field(int PositionX, int PositionY, String Type) {    // <- Das ist der Konstruktor
        this.PositionX = PositionX;
        this.PositionY = PositionY;
        this.Type = Type;
    }
}
```

Und beim erstellen eines neuen Fields an der Position (20|20) vom Typ WALL gibst du das direkt mit:


```
Field neuesField = new Field(20,20,"WALL");
```


----------



## kneitzel (25. Aug 2020)

Also ein paar Punkte:

a) Ich denke, dass es schon wichtig ist, dass sich mehrere Personen beteiligen, denn ein Einzelner kann immer mal keine Zeit haben zum antworten.

b) Plauzi92 hat einfach eine Art Optimierung gemacht. So der Server richtig funktioniert, werden alle Wege durch Mauern abgegrenzt sein. Diese "Unknown" Felder dürften den Client also nicht interessieren. Daher optimiert er so, dass er einfach nur die Mauern speichert. Kann man so machen, aber die Frage ist, ob man damit die Erwartungshaltung bezüglich der Aufgabe erfüllt. In einem realen Projekt sollte die Analyse so sein, dass man klar festlegt, was gebraucht wird. Wenn da 3 Typen von Feld definiert sind, dann würde ich diese auch so umsetzen. Hintergrund ist, dass bei agilen Arbeiten das halt erst ein Punkt ist und es kommen noch weitere Entwicklungsschritte hinterher.
Oder anders gesagt: Dann hätte ich diese Optimierung auch schon direkt beim Server erwartet....

c) Generell führen viele Wege zum Ziel. Du kannst den Konstruktor durchaus so schreiben, wie Du ihn zuletzt geschrieben hast. Worauf ich hinaus wollte, war:
Du wirst beim Client das Labyrinth abfragen und es zurück bekommen. Die Rückmeldung vom Server verwendest Du, um z.B. ein 2d Array von Field zu füllen. Zum Füllen rufst Du also für jede Position des 2d Arrays ein Konstruktor auf. Jeder Aufruf wird also eine neue leere Liste für die Baits übergeben.
Aber das funktioniert natürlich:
felder[x][y] = new Field(getFieldType(scannedType), new ArrayList<BaitType>());

Das wäre dann die Nutzung Deines Konstruktors. Aber dann stellst Du fest:
1) getFieldType(scannedType) kann von der Funktionalität in Field einfließen oder in FieldType. Das nennt sich dann Refactoring. Kann man machen, aber zur Not ist so Code erst einmal an anderer Stelle ... alles prinzipiell ok. Das Thema kann man nach Erstellung einer Lösung angehen.
2) Du rufst den Konstruktor immer mit new ArrayList<BaitType>() auf. Dann kannst Du auf diesen Parameter verzichten und im Konstruktor statt dessen diesen Code schreiben. Dann hättest Du etwas wie:

```
private Field(FieldType fieldType) {
        this.fieldType = fieldType;
        this.baittypes = new ArrayList<BaitType>();
    }
```

Aber auch hier gilt: Kann man machen, aber das wäre auch ein Punkt, den man nach einer ersten Lösung machen kann (so man so gewisse Dinge nicht sieht).

Um so Refactorings ggf. zu vermeiden kann man Funktionalität sozusagen "Top - Down" entwickeln. Das ist generell üblich. In der Regel findet dies aber schon bei der Auflistung der Tasks statt: Was wird wofür gebraucht? Daraus entstehen dann die klaren Aufgaben, was z.B. für "Field" gebraucht wird. Oder man macht es einfach Top/Down bei der Entwicklung. Was brauchst Du denn von Field? Du startest oben bei der Implementierung nachdem Du einen groben Plan hast. Wie der Konstruktor genau aussieht, ist Dir erst einmal egal. Lass ihn zur Not erst einmal weg.
Wenn Du dann die ersten Field Instanzen erzeugen musst, dann siehst Du, was Du hast: Das kann dann also ein String sein mit der Darstellung des Feldes. Und dann gibt es halt einen Konstruktor, der einfach nur so einen String entgegen nimmt.... So vermeidest Du, unnötig Zeit zu verschwenden.
Aber ganz wichtig: Der grobe Aufbau und wo welche Daten gespeichert werden: Das musst Du von Anfang an festlegen. Ohne so ein Design kommst Du nicht weit. Aber das hast Du und da würde ich jetzt nicht zu viel Zeit rein stecken und das ggf. "on the fly" erweitern in den Details.

Ach ja: Der neue Punkt "Position des Feldes":
Nimm das Beispiel Bücherregal: Ein Buch steht im Bücherregal. Wie in der Bücherei: Platz B46 ist von diesem Buch. 
Jetzt kann man das natürlich auch im Buch vermerken. Aber muss man das? Das wäre wichtig, wenn man die Position ständig benötigen würde: Du hast das Buch heraus genommen und nun muss man es zurück stellen. Dann braucht man das.
Aber wenn Du nun Bücher in ein regal stellst: Dann hast Du natürlich auch die Bücher an speziellen Positionen. Über die Position kannst Du auf die Bücher zugreifen. Im Buch muss die Position nicht stehen.

Wenn Du Blätter auf den Schreibtisch legst: Du notierst ja nicht die Position auf den Blättern. Aber wenn Du die Blätter brauchst: Kein Thema: Die Blätter liegen da und da auf dem Schreibtisch. -> zugriff klappt auch ohne dass der Ort vermerkt wird.

So sehe ich das hier auch. Wenn Du z.B. ein 2d Array mit Feldern hast, dann greifst Du darüber auf das jeweilige Feld zu. Aber den Feldern ist es egal, an welcher Position sie sind. Es sind einfach Feld-Instanzen und der Ort ist durch die Referenzierung im 2d Array festgelegt.


----------



## kneitzel (25. Aug 2020)

Plauzi92 hat gesagt.:


> Du hast doch eine Klasse Field oder nicht? Aus dieser werden die Instanzen (also im Prinzip deine einzelnen Mauern und Wege) erstellt. Jede dieser Mauern/Wege hat einen X Wert und einen Y Wert woraus sich die genau Position in dem Labyrinth ergibt. Position (0|0) wäre demnach oben links in der Ecke.
> Außerdem hast du den FieldType. Das kann ein String, oder ein Integer ( 0 für Weg, 1 für Mauer) oder auch irgendwas anderes sein, dass dir gefällt und Sinn macht.
> 
> Wenn du also ein neues Field erstellst, kannst du durch den Konstruktor direkt die Parameter mitgeben.
> ...



Sorry, von dem Aufbau halte ich so erst einmal nichts. Du hast doch ein klaren 2d Aufbau fester Größe. Desweiteren sollte man bei einem Objektorientierten Ansatz bleiben und sich von den Native Types lösen wo es nur geht. Und dieses Lösen könnte man über mehrere Wege machen:

Ein erster Schritt ist erst einmal, die Literale in Konstanten umzuwandeln. Dann hast Du statt "WALL" halt irgend eine Konstante a.la. Field.TYPE_WALL oder so.
Dannkommt aber sofort der zweite Refactoring-Schrittu hast mehrere Konstanten, die zusammen gehören und Du hast eine Variable, die nur bestimmte Werte annehmen kann: Also kommt direkt das Enum.

Dann muss Code an die richtige Stelle. Der Typ eines Feldes sollte also gewisse Dinge wissen wie
- kann ein Spieler auf das Feld? (So es nur vom Typ abhängt)
- wie wird es vom Server dargestellt?

Dann ist klar, wo genau dieser Code steht. Er ist an einer klar definierten Stelle und man hat Verantwortung nicht künstlich in anderen Klassen abgelegt.

Das ist aber nur meine Sicht. Deine Lösung wird auch funktionieren. Aber wie gesagt: Mir sagt die so nicht zu und sobald man es weiter ausbaut wird es schnell unnötig komplex und damit unwartbar.


----------



## mrBrown (25. Aug 2020)

Plauzi92 hat gesagt.:


> Ist an der Position (X/Y) ein Objekt Field mit dem Typ "WALL"? -> Ja? -> Nicht setzen
> Ist an der Position (X/Y) ein Objekt Wall? ->Ja? -> Nicht setzen
> 
> Macht doch absolut keinen Unterschied, nur dass man sich bei letzterer Variante den FieldType spart.



Natürlich macht das einen Unterscheid, das sind völlig unterschiedliche Designs:

 

Möglich sind X verschiedene Varianten, aber Unterschiede macht das in jedem Fall.




Plauzi92 hat gesagt.:


> Den Konstruktor bräuchtest du doch auch ohne FieldType damit du der Instanz vom Typ Field die Position direkt mitgeben kannst.


Allerdings muss ein Feld eigentlich nie seine Position wissen. Wenn es die weiß, hat man die Information doppelt gespeichert, was zu Problemen führen kann und oft auch führt.


----------



## Plauzi92 (25. Aug 2020)

mrBrown hat gesagt.:


> Allerdings muss ein Feld eigentlich nie seine Position wissen. Wenn es die weiß, hat man die Information doppelt gespeichert, was zu Problemen führen kann und oft auch führt.


Stimme ich zu. Habe die Positionen zwar da rein geschrieben aber im Endeffekt nie genutzt. Tatsächlich reicht das 2D-Array


----------



## jono (26. Aug 2020)

JustNobody hat gesagt.:


> Wenn Du dann die ersten Field Instanzen erzeugen musst, dann siehst Du, was Du hast: Das kann dann also ein String sein mit der Darstellung des Feldes. Und dann gibt es halt einen Konstruktor, der einfach nur so einen String entgegen nimmt....


1.
Ein String zur Darstellung des Feldes? Ein Feld wird doch durch eine array position lokalisiert und hat einen FieldType vom Typ Enumeration, verstehe ich jetzt nicht ganz.
2.
Wie erzeuge ich den Field Instanzen, bzw. wo sollen die erzeugt werden? Was ich auch nicht verstehe, was konkret an einem Beispiel von mir aus, heißt es, dass ein Konstruktor entgegen nimmt?
3.
Essentiell noch mal für mich wäre zu klären, welche Aufgabe der Konstruktor jetzt konkret erfüllen soll? Ein Konstruktor dient ja eigentlich nichts anderem als der Erzeugung von Objekten. Wäre super wenn mir das jemand evtl. an einem Fallbeispiel erklären kann. Also die Informationen, die der Server dem Client übergibt bei der Anforderung des MAZE, sind ja im Endeffekt Objekte, aber wie bringe ich das jetzt in Einklang mit dem Konstruktor, weil wenn ich mich richtig entsinne, dann war der Konstruktor doch mit dem Erhalt der Informationen in Zusammenhang gebracht worden?


----------



## jono (26. Aug 2020)

JustNobody hat gesagt.:


> Ach ja: Der neue Punkt "Position des Feldes":
> Nimm das Beispiel Bücherregal: Ein Buch steht im Bücherregal. Wie in der Bücherei: Platz B46 ist von diesem Buch.
> Jetzt kann man das natürlich auch im Buch vermerken. Aber muss man das? Das wäre wichtig, wenn man die Position ständig benötigen würde: Du hast das Buch heraus genommen und nun muss man es zurück stellen. Dann braucht man das.
> Aber wenn Du nun Bücher in ein regal stellst: Dann hast Du natürlich auch die Bücher an speziellen Positionen. Über die Position kannst Du auf die Bücher zugreifen. Im Buch muss die Position nicht stehen.
> ...


Okay, danke gutes Beispiel!


----------



## kneitzel (26. Aug 2020)

Zu 1: schau dir an, wie das Spiel abläuft. Der Client fragt den Server nach dem Maze. Der Server schickt dann das Maze: was genau sendet der Server zurück? Aus dem, was der Server zurück sendet musst du ja deine Daten aufbauen....

Zu 2. Du musst dir den Ablauf genau ansehen. Die Kommunikation zwischen Client und Server ist ja genau spezifiziert. Wie läuft denn dann so ein Spiel ab? Gev das einmal in Ruhe durch um eine Vorstellung davon zu bekommen, wann der Client was macht und was für Daten er verarbeiten muss.

Zu 3. Der Konstruktor dient der Initialisierung von neuen Instanzen. Für das Erzeugen ist das new verantwortlich. Wenn mit new eine neue Instanz einer Klasse erzeugt wird, wird der angegebene Konstruktor zur Initialisierung aufgerufen.
Dabei können Daten für die neue Instanz übergeben werden.


----------



## jono (26. Aug 2020)

JustNobody hat gesagt.:


> Zu 1: schau dir an, wie das Spiel abläuft. Der Client fragt den Server nach dem Maze. Der Server schickt dann das Maze: was genau sendet der Server zurück? Aus dem, was der Server zurück sendet musst du ja deine Daten aufbauen....


Ja, der Server sendet String commands die der CommandHandler in GameStatusModel updatet.




JustNobody hat gesagt.:


> Zu 2. Du musst dir den Ablauf genau ansehen. Die Kommunikation zwischen Client und Server ist ja genau spezifiziert. Wie läuft denn dann so ein Spiel ab? Geh das einmal in Ruhe durch um eine Vorstellung davon zu bekommen, wann der Client was macht und was für Daten er verarbeiten muss.


Warum den Ablauf ansehen, den habe ich ja schon genau verstanden! Mir geht es jetzt genau um den Konstruktor, ich bekomme Informationen vom CommandHandler aufgrund eines ServerBefehls. Dieser aktualisiert Daten in GameStatusModel, sei es Field oder Player...
Wenn es Field ist, werden z.B. Baits oder fieldTypes aktualisiert, heißt es werden neue Instanzen erzeugt oder wie ??? Ja im Prinzip schon aber wie werden die erzeugt, ich kenne das so dass ich z.B. Instanzen einer Klasse in einer anderen Klasse erzeuge bzw. in einer Main-Klasse. Ich kenne das nicht so wie das hier gemacht werden soll. Kannst du mir da konkreter behilflich sein?



JustNobody hat gesagt.:


> Zu 3. Der Konstruktor dient der Initialisierung von neuen Instanzen. Für das Erzeugen ist das new verantwortlich. Wenn mit new eine neue Instanz einer Klasse erzeugt wird, wird der angegebene Konstruktor zur Initialisierung aufgerufen.
> Dabei können Daten für die neue Instanz übergeben werden.


Ja, das ist mir alles bewusst, wichtig ist mir wirklich zu wissen wie der Konstruktor jetzt ganz konkret seine Aufgabe erfüllen soll..

Noch eine Frage:

```
private FieldType fieldType;
    private List<BaitType> baittypes = new ArrayList<BaitType>();
```
Eine Instanzvariable fieldType brauche ich dann jetzt nicht mehr ? Weil das wurde ja abgetan von euch, es hieß erst diese darf nicht null sein, dann habe ich sie ungleich null gemacht und das war dann auch falsch gewesen.


----------



## jono (26. Aug 2020)

Und wie baue ich diese jetzt noch dazu ein, ist sehr abstrakt hier formuliert.


----------



## jono (26. Aug 2020)

1. Wie implementiere ich Properties die einen Zustand speichern, 
2. Was ist da wieder genau mit Zustand gemeint, statische Variablen und enum werte auch oder?


----------



## jono (26. Aug 2020)

Also wie ich die Properties in GameStatus Model implementiere ist klar, aber wie setze ich das in JavaFX um, wobei ich denke, dass ich die Frage nochmal stelle wenn ich das FX-Subsystem angefangen habe


----------



## kneitzel (26. Aug 2020)

Sorry, aber ich bezweifle, dass Du das wirklich überblickst.

Irgendwo wirst Du hoffentlich die Felder des Labyrinths speichern wollen. Und diese Stelle musst Du aktualisieren, wenn Du die Daten vom Server bekommst, die ja so aussehen sollen:

```
MAZE;20;10
--------------------
-##################-
-#................#-
-#.###.#.###.##.#.#-
-#...###..#..#..#.#-
-#.#.........#..#.#-
-#.#########.#.##.#-
-#................#-
-##################-
--------------------
```

Also musst Du aus diesem Text irgendwie die Daten zusammen bekommen. Das könnte z.B. sein, dass Du ein 2d Array von Field erstellst mit der entsprechenden Größe also z.B. hier [20][10].
Und dazu musst Du dann die Zeichen auswerten. Aus dem '-' Zeichen soll ein Field werden vom Typ UNKNOWN. Aus dem'.' Zeichen ein Field vom Typ PATH und aus dem '#' ein Field vom Typ WALL (Oder wie die Typen bei Dir auch immer heißen - habe ich jetzt nicht nachgeschlagen!)

Also brauchst Du ganz offensichtlich Code, der aus einem Zeichen ein Field erstellt. Das könnte man über einen Konstruktor machen. Aber das kann man auch gerne anders machen - das ist mir auch relativ egal. Mach es so, wie Du es machen möchtest, aber MACH EINFACH. Setz Dich dran und schau, wie Du das erstellt bekommen kannst. Und wenn Du alles in eine zentrale Klasse packst die dann direkt auf den anderen Klassen agiert. Das kann man später anpassen (Refactoring). Nur mach die Logik! Dann siehst Du auch, was Du brauchst.

Und auf die Frage, ob man den FieldTyp braucht, da habe ich jetzt einfach keinen Ansatz mehr. Wir haben da nun wirklich lang und breit drüber gesprochen. Du hast den Typ auf einen festen Wert gesetzt. Das ist Quatsch, denn alle Felder sind ja nicht vom gleichen Typ! Und natürlich muss der Typ gesetzt werden, denn ein Feld ist entweder vom Typ UNKNOWN, PATH oder WALL. Also hast Du eine Variable, die gesetzt sein muss: Dann setz diese doch im Konstruktor. Und da es unterschiedliche Felder mit unterschiedlichen Typen gibt: Übergib etwas, so dass Du den Typ setzen kannst.

Das kann also einfach nur der FieldType sein, den du direkt übergibst. Oder Du übergibst das Zeichen und dann sucht der Konstruktor raus, was für ein Typ das ist. Das kann z.B. in einem switch passieren wenn Du das so machen möchtest. 

Was die Properties angeht: Nutz einfach die entsprechenden Property Klassen. Also erstell eine Instanz von StringProperty und schon kannst Du ein Control an diese Property binden. Aber da einfach mal ein paar Beispiele zu JavaFX ansehen. Das ist ja nun ein Gebiet, wo es im Internet sehr viele Seiten zu gibt....


----------



## jono (26. Aug 2020)

JustNobody hat gesagt.:


> Und da es unterschiedliche Felder mit unterschiedlichen Typen gibt: Übergib etwas, so dass Du den Typ setzen kannst.


Was soll das heißen? Wie übergebe ich etwas einem Konstruktor, die Begriffe die du da verwendest geben mir kein Aufschluss darüber?Was soll ich übergeben, was heißt ein Typ "setzen"?



JustNobody hat gesagt.:


> Du hast den Typ auf einen festen Wert gesetzt. Das ist Quatsch, denn alle Felder sind ja nicht vom gleichen Typ! Und natürlich muss der Typ gesetzt werden, denn ein Feld ist entweder vom Typ UNKNOWN, PATH oder WALL. Also hast Du eine Variable, die gesetzt sein muss: Dann setz diese doch im Konstruktor.


Ja ich habe doch eine Variable namens vom Typ FieldType in den Konstruktor gesetzt?


----------



## jono (26. Aug 2020)

JustNobody hat gesagt.:


> Also brauchst Du ganz offensichtlich Code, der aus einem Zeichen ein Field erstellt. Das könnte man über einen Konstruktor machen.


Wie macht man das mit einem Konstruktor, ich kenne nur die einfache Instanziierung von Variablen einer Klasse. Mit new wird ein Konstruktor aufgerufen. Aber wie erstelle ich dann mit einem Konstruktor aus einem Zeichen ein Field. Das ist mir einfach völlig fremd


----------



## kneitzel (26. Aug 2020)

Wenn eine Methode Parameter hat und dann wird die Methode aufgerufen: Dann wird da umgangssprachlich von "übergeben" gesprochen.
Also Du hast eine Methode test, die einen int Parameter hat. Dann kannst Du test aufrufen und z.B. 5 übergeben: test(5);

Einer Variable einen Wert zuweisen: Das wäre umgangssprachlich das setzen. "Typ" entsprach hier einfach deiner FieldType Variablen.

Und Du kannst einen Konstruktor schreiben wie jede Methode. Da kann also mehr drin sein als nur einfache Zuweisungen. Also sowas wie:

```
public Field(final char character) {
  switch (character) {
      case '.': fieldType = FieldType.WAY; break;
      case '#': fieldType = FieldType.WALL; break;
      case '-': fieldType = FieldType.UNKNOWN; break;
      default: throw new IllegalArgumentException("Character " + character + " is not valid!");
  }
}
```

Oder

```
public Field(final char character) {
  fieldType = FieldType.of(character);
}
```
Und in FieldType hast Du dann eine Methode

```
public static FieldType of(final char character) { ... }
```
die diese Umwandlung enthält. Und das entweder mit einem switch wie oben gezeigt oder ggf. wie schon einmal früher exemplarisch gezeigt mit einer for each Schleife und Prüfen eines Wertes, der jedem enum Eintrag zugewiesen wurde. Das suche ich jetzt aber nicht raus und Du kannsteinfach bei einem switch bleiben und gut ist es ...


----------



## jono (30. Aug 2020)

@JustNobody 
1. Wozu brauche ich Dann die Methoden in FieldType?

2. Nun möchte ich das Command-Pattern implementieren.
Wie Gehe ich dabei genauer vor?
Ich muss erstmal eine Klasse Command mit der execute() Methoden schreiben, die Dann von den jeweiligen Servernachrichten wie z.B. die MAZE (MAZE wird Dann eine Befehlsklasse public class Maze) implementieren wird. Als pro Servernachricht eine Befehlsklasse, die die jeweiligen Änderungen in GameStatusModel vornehmen?


----------



## jono (31. Aug 2020)

?


JustNobody hat gesagt.:


> diese Umwandlung enthält. Und das entweder mit einem switch wie oben gezeigt oder ggf. wie schon einmal früher exemplarisch gezeigt mit einer for each Schleife und Prüfen eines Wertes, der jedem enum


Warum Schreibst du es Dann erst in den Konstruktor von Field und Dann sagst du die Umwandlung soll in die Methoden von FieldType?


----------



## kneitzel (31. Aug 2020)

Ich habe einfach mehrere Möglichkeiten aufgezählt, wie es implementiert werden könnte.

Aber ich habe schon gesagt Spätestens in #173 ("Das könnte man über einen Konstruktor machen. Aber das kann man auch gerne anders machen - das ist mir auch relativ egal. Mach es so, wie Du es machen möchtest, aber MACH EINFACH. Setz Dich dran und schau, wie Du das erstellt bekommen kannst. Und wenn Du alles in eine zentrale Klasse packst die dann direkt auf den anderen Klassen agiert. Das kann man später anpassen (Refactoring). Nur mach die Logik!")

Das erste war einfach eine 08/15 Lösung für Dich. Einfach zu verstehen und vielleicht hast Du diese ja verstanden. Das was folgt, ist ein Refactoring - also eine Art Verbesserung, denn Code, der den FieldType betrifft sollte eigentlich auch da drin zu finden sein. Field sollte keine Entscheidungen treffen, die FieldType zustehen, also auch nicht, welches Zeichen denn nun welchem FieldType entspricht. Aber das ist nebensächlich. Bau nur einfach eine Lösung, die Du verstehst.


----------



## jono (2. Sep 2020)

Das wäre dann soweit geklärt.
Jetzt möchte ich den CommandHandler implementieren, d.h. die jeweiligen eingehenden Servernachrichten in ein Befehlsobjekt konvertieren. Dann sollen verschiedene Befehlsklassenn pro Servernachricht erstellt werden, um GameStatusModel über Änderungen zu informieren. Das Ganze stellt ja das Command-Pattern dar. 
Wie genau erstellt man jetzt die Befehlsobjekte die auf die jeweilige Befehlsklasse verweisen sollen?
Die jeweiligen Servernachrichten sind ja I'm CSV Format gegeben. Diese müssen eingelesen werden als String-Datentyp.
Meine Frage:
Wie genau gehe ich jetzt vor, wie verknüpfe ich die Blickrichtung (z.B. die 2. Position eines CSV-Datensatzes wie bei der PPOS Servernachricht in der exam-task.pdf) mit einer Befehlsklasse, welche die Blickrichtung ändern kann?
In der Befehlsklasse selbst wird die Blickrichtung geändert, nachdem die Nachricht ausgelesen würde und auf die jeweiligen Befehlsklassen verweist...
Kann mir da jemand konkret behilflich sein und mir gute Tipps gehen ? 🙂


----------



## jono (10. Sep 2020)

@JustNobody

```
if (parts[0].equals("PSCO")){
                
            }
```
das parts-Array ist das CSV-Array welches die Servernachricht enthält und durch ";" gesplitet wird.
Nun möchte ich der if-Anweisung sagen, wenn parts[0] "PSCO" ist, dann möchte ich dass die Command Klasse "X" angesprochen wird, bzw. ihre Methdoe ausführt?


----------



## kneitzel (10. Sep 2020)

jono hat gesagt.:


> @JustNobody
> 
> ```
> if (parts[0].equals("PSCO")){
> ...



Hast Du eine Instanz der Klasse "X" oder ist die Methode statisch? Dann kannst Du da den Aufruf einbauen. (Statisch ist aus Sicht von Java technisch möglich, aber aus Sicht der Objektorientierung ist es eher keine Option. Wobei ich jetzt nicht den Überblick habe, was Du da wie an Code hast und so.

Anregung (Wenn Du es nicht verstehst, dann bau es erst so, wie Du es verstanden hast - das kannst Du komplett ignorieren):
Generell scheint mir das schon fast etwas zu sein, dass man recht schön aufbauen kann mit einer Map also etwas in der Art:
commandMap.get(parts[0]).execute()
Die commandMap hat dann halt den Zusammenhang zwischen "PSCO" und einer "Command Klasseninstanz" und ich habe da die Methode, die aufgerufen wird, einfach mal execute genannt. Das kann natürlich in Deinem konkreten Fall etwas anders aussehen.

Oder wie schon so oft auf den Seiten dieses Threads erwähnt: Enum kann man auch nutzen, um sowas aufzubauen (So die Elemente fix sind, denn im Gegensatz zu der map kann man einer Enum zur Laufzeit keine Member hinzufügen).


----------



## jono (11. Sep 2020)

Den oben genannten commandMap-Befehl würde ich dann in die if-Anweisungen schreiben. Die if-Anweisungen kommen in die Klasse des MazeGameProtocol's, die die Servernachrichten einlesen. Der Code hier stellt ja die Befehlsklasse dar, die die PSCO Nachricht aktivieren soll. Wenn ich das jetzt so mache:

```
if (parts[0].equals("PSCO")){
            commandMap.get(parts[0]).execute()    
            }
```
wäre das ja noch nicht korrekt, wie mache ich das jetzt, dass die ScoreCommand-Befehlsklasse angesprochen wird.

```
public class ScoreCommand implements Command {

    private int score = parts[2];

    @Override
    public int execute() {

        return score.addToScore();
    }

}
```
addToScore ist dann hier die Methode aus der Empfängerklasse, wie z.B. die Playerklasse in der der Score verändert werden soll.
Die Befehlsklasse "ScoreCommand" soll ja jetzt nur die addToScore-Methode in "Player" ausführen, ist ja die Aufgabe einer Befehlsklasse...
Wie mache ich jetzt hier richtig, eher gesagt wie kann ich der Befehlsklasse das parts-array ansprechen, welches ich in der Readerklasse des MazeGameProtocols definiert habe:

```
try(
    LineNumberReader read = new LineNumberReader(new StringReader())){
        read.lines()
        .filter(line -> read.getLineNumber() = 0)
        .forEach(line -> {
            String [] parts = str.split(";");
            
            if (parts[0].equals("PSCO")){
                commandMap.get(parts[0]).execute();
```


----------



## kneitzel (11. Sep 2020)

Also ich habe keinen Überblick über dein Design und kann daher nur sagen:
a) Das mit der map hast Du falsch verstanden. Da brauchst Du dann kein if mehr! Das ist ja der Sinn dahinter - eine Serie von ifs bzw ein switch zu vermeiden.
b) Deine Klasse ScoreCommand macht keinen Sinn. So soll denn da das parts[2] her kommen?
c) Wieso meinst Du, da plötzlich mit Streams arbeiten zu müssen? Du scheinst noch Probleme mit den Java Basics zu haben - da würde ich dies erst einmal nicht nutzen. Und was genau willst Du da genau machen? Ich würde das an Deiner Stelle mit kleinen, sinnvollen Methoden machen. Und was ist da für eine Bedingung in .filter? Soll das == oder != sein? Das = alleine macht so keinen Sinn. Und wenn es ein Stream sein soll: Dann mach es wirklich einfach zu lesen - ebenfalls mit Methoden. Also sowas wie:

```
try(LineNumberReader read = new LineNumberReader(new StringReader())) {
    read.lines()
    .filter(line -> read.getLineNumber() != 0)
    .forEach(line -> verarbeiteZeile(line));
}
```
Ich habe da mal ein != 0 gemacht - willst evtl. die erste Zeile nicht haben oder so ... Und dann klar sauber Methoden aufgebaut. Wobei ich statt dem Lambda Ausdruck eine Methodenreferenz angegeben hätte, aber das mit dem Lambda ist evtl. lesbarer für Dich ...


----------



## jono (11. Sep 2020)

Zu a)
Okay, also die Reader-Klasse in MazeGameProtocol kann dann durch den commandMap-Befehl direkt die Methode "execute" in der Befehlsklasse ausführen?
Zu b)
Ja, ich weiß, dass das keinen Sinn macht. Das Problem ist, dass ich die 3. Position für den Punktestand benutzen muss weil das ja so vorgegeben ist. Und den brauche ich ja für die Methode addToScore, die ich in der Playerklasse schreibe. Also die dritte stelle des PSCO Befehls muss ja für die Methode verwendet werden, darum geht es mir da.
Zu c)
Weil die Servernachrichten eingelesen werden müssen?
Ja sinnvoll wäre da eher >= 0.


----------



## jono (11. Sep 2020)

Welches Attribut muss ich in der CommandScore Klasse verwendet...


----------



## jono (12. Sep 2020)

@JustNobody Ich würde es gerne mit den if Anweisungen so fortsetzen...

```
if (parts[0].equals("PSCO")){
                ScoreCommand psco = new ScoreCommand();
```
Das würde dann erstmal so aussehen. Dieser Code steht in einer Klasse der MazeGameProtocol-Komponente. Wie schaffe ich es jetzt in der Komponente COmmandHandler mehrere Verweise zu setzen auf die Objekte, denn ich muss ja natürlich noch mehr Befehlsklassen als ScoreCommand erstellen


----------



## jono (12. Sep 2020)

Also wie übergebe ich die Referenzvariable einer z.B. Klasse namens CommandHandler im CommandHandler.

```
ScoreCommand score = psco
```
So gebe ich "score" eine Referenz, die auf dasselbe Objekt verweist, nur wie übergebe ich diese Referenzvariable psco, weil diese kennt das Programm ja nicht bzw. erscheint die Meldung: psco cannot be resolved to a variable


----------

