OO Ansatz für Strategie Spiel - Designfrage



  • Ja ne, den Müller brauchts schon. Kennst du Siedler? Erst Häuschen bauen, dann kommt ein Siedler rein und arbeitet.
    Ok, ev ist es unnötig, könnte einfach ein Member der Mühle sein:
    "bool hasMiller"

    Zu deinem Codebrocken, was heisst "extends"?

    Werde mal nach Observer googlen...
    Danke!!



  • @.filmor

    Zu spät gesehn, hast recht, brauche nur die Träger. ( Bin friedliebend 😉 )



  • Drüber steht Pseudocode, extends heißt hier öffentliche Vererbung.

    Klar kenn ich die Siedler (II versteht sich). Und wenn du ein wenig "generischer" denken würdest wäre das kein Problem :). hasMiller ist Quatsch, aber die Basisklasse der "einfachen" Gebäude (Brunnen, Bäckerei, Fleischerei, Sägewerk und eben auch die Mühle) braucht nur eine Variable, die anzeigt, ob das Gebäude besetzt ist.
    Wenn ein neues Gebäude gebaut ist schaust du im Lager nach, ob du die nötigen Werkzeuge und einen Siedler hast, generierst einen mit dem entsprechenden Beruf und lässt ihn dann vom Lagerhaus oder Hauptgebäude zu seinem Arbeitsplatz laufen. Ist er da angekommen wird "istBesetzt" gesetzt und das Gebäude nimmt die Waren an.
    Mit Trägern kannst du es ähnlich machen, deren "Arbeitsplatz" ist dann halt zwischen 2 Fahnen (vorausgesetzt du willst das echte Wegsystem benutzen.



  • Jetzt habe ich extra scho C++-like Pseudocode geschrieben und bewusst nicht "implements MuehleListener" geschrieben und dann alles umsonst *g*

    extends ist dann in dem Fall
    class Muhele : public MuehleListener

    MfG SideWinder



  • Schuldigung
    Kenn mich nur mit C++ etwas aus, Pseudocode ist mir nicht so geläufig.
    Und das "generische Denken" will ich ja grade üben 🙂 , darum bin ich froh über solche Hinweise 👍

    Danke an euch, ich wurschtel dann mal weida..
    greez



  • So, hallo nochmal

    Hab dank der Forensuche das hier gefunden, und die Klassen Observer und Observable so ähnlich implementiert. Funktioniert auch soweit.
    So und nun Leite ich die Klassen Farm, Mill, Bakery und Path von den beiden und vom Basistyp Building ab. Nun will ich im Baumenu natürlich Instanzen erzeugen, mit new.
    Meine Frage ist nun, wo pack ich die rein?
    In nen Vektor für jeden Gebäudetyp, oder alle in einen für den Basistyp Building?
    Ich dachte ich mach ne Klasse Village (o.ä) wo ich nen Container für bereitstelle. Macht das irgendwie Sinn?



  • Factory-Pattern?!



  • Danke!
    Muss ich mal googeln...

    Wo findet man eigentlich all die Patterns, und weiss wann man welches einsetzt. Ist das Erfahrung oder gibts da ein Schema F?



  • eine übersicht inklusive beispielen gibt es hier:
    http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29
    (es gibt auch noch ne deutsche version, eventuell ist die ja verständlicher. die englische ist auf jeden fall ausführlicher.)

    dann gibt es noch "das" referenzwerk von der "gang of four" mit dem gleichnamigen titel "design pattern". das buch ist allerdings ziemlich trocken, und schwer verständlich, wenn man nicht wirklich fit im objekt-orientiertem design ist. dafür aber sehr vollständig (was die enthaltenen patterns betrifft) und somit ein sehr gutes nachschlagewerk.
    sehr viel lebendiger ist das buch von head first:
    http://www.amazon.de/gp/product/0596007124/302-2971792-6420869?v=glance&n=52044011
    Das gibts auch auf deutsch, ist aber 20€ teurer und bei übersetzungen weiss man nie so recht ;).

    auch nicht schlecht ist diese seite: http://www.dofactory.com/Patterns/Patterns.aspx. die erklärungen sind allerdings nicht besonders ausführlich, deswegen ist es auch eher als nachschlagewerk zu gebrauchen, für den fall, dass dir im forum ein "Abstract Factory" an den kopf geworfen wurde ;).



  • So, back again...
    Danke mal soweit für die Hilfe 👍
    Also nun hab ich ne Factory Methode, wenigstens mal das Gerüst.
    Die bau ich nun in mein Spiel ein.
    Meine Grundfrage von vorhin bleibt aber, wo speichere ich die erzeugten Objekte?
    In ner Extraklasse Village in nem Vector für Products?
    Gibts da etwa noch ein Manager Pattern 😕 🤡

    Und ne andere Frage ist nun, ein Gebäude das sowohl Waren empfängt und bereitstellt (fast alle ausser der Farm) erbt doch nun von 3 Klassen allein durch die Observer und Factory Geschichten. Zusätzlich dachte ich ja an eine Basisklasse Building. Das wären dann 4 Basisklassen. Ist das nicht etwas komplex bzw. ein unnötiger Overhead?

    Letzte Frage für den Moment: Gibt es die Funktion GetType().Name auch bei C++ oder nur bei C#?



  • Ooptimist schrieb:

    Meine Grundfrage von vorhin bleibt aber, wo speichere ich die erzeugten Objekte?
    In ner Extraklasse Village in nem Vector für Products?
    Gibts da etwa noch ein Manager Pattern 😕 🤡

    Brauchst du gar nicht. Du wirst ja irgendwo die ganzen Daten des Spielers abspeichern (z.B. auch die Position des Hauptgebäudes, das Volk, Statistiken etc.). Da kannst du einen Gebäude-Vektor einfügen. Aufgrund der Verwendungsart als Container ausschließlich polymorpher Objekte solltest du ptr_vector verwenden. IIRC funktioniert der auch mit Boost.Serialization, sehr praktisch für Spielstände.

    Ooptimist schrieb:

    Und ne andere Frage ist nun, ein Gebäude das sowohl Waren empfängt und bereitstellt (fast alle ausser der Farm) erbt doch nun von 3 Klassen allein durch die Observer und Factory Geschichten. Zusätzlich dachte ich ja an eine Basisklasse Building. Das wären dann 4 Basisklassen. Ist das nicht etwas komplex bzw. ein unnötiger Overhead?

    Du kannst noch einige Abstraktionen machen, z.B. eine Producer-Klasse die von Building abgeleitet ist und eine Receiver-Klasse, die wiederum von Producer abgeleitet ist (die "Ist-ein" Beziehung ergibt sich aus der Spiellogik, wenn du dich an die Siedler-Regeln hältst, sollte aber dennoch gut dokumentiert sein. Militärgebäude sind zwar auch Empfänger, aber wenn du nur deshalb Receiver nicht von Producer ableiten würdest, dann müsstest du Producer und Receiver virtuell ableiten, was hier aber nicht praktisch ist. Militärgebäude "verarbeiten" die ankommenden Rohstoffe ja auch ganz anders.

    Ooptimist schrieb:

    Letzte Frage für den Moment: Gibt es die Funktion GetType().Name auch bei C++ oder nur bei C#?

    Nein. Es gibt nur typeid(typ).name, aber das ist nicht eindeutig. Wenn du so etwas haben willst, dann implementier es als virtuelle Methode.



  • Danke für den Tipp mit Serialization. Werd ich dann auch verwenden für Spielstände, aber soweit bin ich noch nicht. Boost hat ja noch einiges aufm Kasten 😮

    .filmor schrieb:

    Ooptimist schrieb:

    Und ne andere Frage ist nun, ein Gebäude das sowohl Waren empfängt und bereitstellt (fast alle ausser der Farm) erbt doch nun von 3 Klassen allein durch die Observer und Factory Geschichten. Zusätzlich dachte ich ja an eine Basisklasse Building. Das wären dann 4 Basisklassen. Ist das nicht etwas komplex bzw. ein unnötiger Overhead?

    Du kannst noch einige Abstraktionen machen, z.B. eine Producer-Klasse die von Building abgeleitet ist und eine Receiver-Klasse, die wiederum von Producer abgeleitet ist (die "Ist-ein" Beziehung ergibt sich aus der Spiellogik, wenn du dich an die Siedler-Regeln hältst, sollte aber dennoch gut dokumentiert sein. Militärgebäude sind zwar auch Empfänger, aber wenn du nur deshalb Receiver nicht von Producer ableiten würdest, dann müsstest du Producer und Receiver virtuell ableiten, was hier aber nicht praktisch ist. Militärgebäude "verarbeiten" die ankommenden Rohstoffe ja auch ganz anders.

    Ok sorry, ich kapiers nicht mehr 😕
    Im Observer-Pattern hab ich Observers und Observables, in der Factory hab ich Creators und Products. Kann ich die Factory und Observer Methoden nicht in die Basisklasse der Bereitsteller und Empfänger einfügen? Ich hab ja sonst ewig viele Abhängikeiten und Dateien, ich hab einfach keinen Überblick mehr, was wo ist 😕



  • Habe nun nochmal die Hierarchie überdacht:

    Factory						Observer
    
    Creator      Product          Subject      Observer    
       |            |                |            |
       |            |                |            |
       |            |                |            |
    Builder ---->Building            |            |
       |            |                |            |
       |            |                |            |
       |            ---------------| |  --------| |
       |                          Pure          Pure
       |                          Producer      Receiver
       |                          |   |          |    | 
       |                          |   |          |    |
       |                          |   ----| |-----    |
       |                          |    Processor      |
       |                          |        |          |
       |                          |        |          |
       |                          |        |          |
    Farm* Builder ------------>Farm   Mill/Bakery  Storage       
    *needed for each
    spec. Building Type
    

    Macht das Sinn so? Kritik wäre toll! 🙂



  • Nochmal, willst du dich wirklich genau an die Siedler II halten? Dann gibt es keine Pure Receiver (außer Militärgebäude). Das ist das worauf ich beim letzten eingehen wollte.
    Das Farm ein Pure Producer ist ist genauso falsch (eine Farm nimmt Wasser an), wie dass Storage ein Pure Receiver ist (Lagerhäuser musst du definitiv gesondert behandeln).
    Zusätzlich heißt ein Pattern benutzen nicht zwingend, dass du deine Klassen auch direkt von den Observable etc. ableiten musst (hast du auch nicht getan und richtig erkannt) Das gehört in die (richtige) Basisklasse, dann ergibt sich alles implizit aus der Vererbungshierarchie. Deshalb hast du eine (fast) lineare Vererbung und daher fast keinen Overhead. Um virtuelle Methoden wirst du eh nicht herumkommen.
    Der sinnlose und unschöne Overhead ergibt sich erst, wenn du sowohl von Pure Receiver als auch Pure Producer ableitest (wie hier bei Mill/Bakery), such zu dem Thema mal nach dem "deadly diamond". Siehe auch mein letztes Posting.



  • Hallo Ooptimist,

    schau dir doch einmal www.widelands.org an. Widelands ist ein Spiel, das Siedler II sehr sehr ähnlich ist. Das Spiel ist Opensource, du kannst dir also einmal den Quellcode herunterladen und ansehen wie dort das Klassendesign realisiert wurde.

    Ciao



  • .filmor schrieb:

    Nochmal, willst du dich wirklich genau an die Siedler II halten?.

    Nein eigentlich nicht. Schongar nicht Siedler II, wenn schon das erste 🙂 Habe nur das Prinzip gemeint, Bauspiel mit Wirtschaftssystem und Transport etc. aber ohne Milität. Ich mags friedlich.

    .filmor schrieb:

    Dann gibt es keine Pure Receiver (außer Militärgebäude). Das ist das worauf ich beim letzten eingehen wollte.
    Das Farm ein Pure Producer ist ist genauso falsch (eine Farm nimmt Wasser an), wie dass Storage ein Pure Receiver ist (Lagerhäuser musst du definitiv gesondert behandeln).

    Ok, habs nicht genau genug gelesen. Du meintest die Reciever vom Producer ableiten. So gehts dann natürlcih. In meinem System soll es aber reine Produzenten geben, die Farmen, denn Wasser regnets vom Himmel 😉 Am Ende der Kette stehen Konsumenten. Die werd ich dann wohl nochmal extra machen und nur vom Observer ableiten.

    .filmor schrieb:

    Zusätzlich heißt ein Pattern benutzen nicht zwingend, dass du deine Klassen auch direkt von den Observable etc. ableiten musst (hast du auch nicht getan und richtig erkannt) Das gehört in die (richtige) Basisklasse, dann ergibt sich alles implizit aus der Vererbungshierarchie. Deshalb hast du eine (fast) lineare Vererbung und daher fast keinen Overhead. Um virtuelle Methoden wirst du eh nicht herumkommen.
    Der sinnlose und unschöne Overhead ergibt sich erst, wenn du sowohl von Pure Receiver als auch Pure Producer ableitest (wie hier bei Mill/Bakery), such zu dem Thema mal nach dem "deadly diamond". Siehe auch mein letztes Posting.

    Den "deadly diamond" kenn ich, ist mir gar nicht aufgefallen in meinem "Diagramm". Gibt halt noch keine UML Tags für dieses Forum 😉



  • Factory                        Observer
    
    Builder      Product          Subject      Observer    
    (Creator)       |                |            |
       |            |                |            |
       |            |                |            |
       |         Building            |            |
       |            |                |            |
       |            |                |            |
       |            ---------------| |           / \
       |                           | |           |  \
       |                         Producer        |   \
       |                          |   |          |    | 
       |                          |   |          |    |
       |                          |   ----| |-----    |
       |                          |       | |         |
       |                          |    Fabricator     |
       |                          |        |          |
       |                          |        |          |
       |                          |        |          |
    Farm* Builder ------------>Farm   Mill/Bakery  Consumer       
    *needed for each
    spec. Building Type
    

    Also jetzt aber 😉



  • Ooptimist schrieb:

    .filmor schrieb:

    Nochmal, willst du dich wirklich genau an die Siedler II halten?.

    Nein eigentlich nicht. Schongar nicht Siedler II, wenn schon das erste 🙂 Habe nur das Prinzip gemeint, Bauspiel mit Wirtschaftssystem und Transport etc. aber ohne Milität. Ich mags friedlich.

    Hey, was ist gegen S2 einzuwenden? Außerdem unterscheidet sich das Regelwerk doch iirc nicht besonders ...

    Ooptimist schrieb:

    Ok, habs nicht genau genug gelesen. Du meintest die Reciever vom Producer ableiten. So gehts dann natürlcih. In meinem System soll es aber reine Produzenten geben, die Farmen, denn Wasser regnets vom Himmel 😉 Am Ende der Kette stehen Konsumenten. Die werd ich dann wohl nochmal extra machen und nur vom Observer ableiten.

    Welche Konsumenten?! Ohne Militärgebäude sind nur die Lagerhäuser "Konsumenten".

    Ooptimist schrieb:

    Den "deadly diamond" kenn ich, ist mir gar nicht aufgefallen in meinem "Diagramm". Gibt halt noch keine UML Tags für dieses Forum 😉

    Man braucht kein UML, dass musst du spüren, junger Padawan ;). Im Ernst, wenn es zwei Vererbungspfade zur Basisklasse gibt hast du automatisch den "Diamanten des Todes" (klingt cooler ;)) und den gilt es imo zu vermeiden.

    /edit Joa, das letzte Diagramm sieht gut aus. Übrigens, die Creator Objekte (bitte nicht Builder, dass ist mehrdeutig) kannst du schön in ein Template verfrachten.



  • Hehe, ganz ruhig. Ich hab die ganze Siedler Reihe bis 4 durchgezockt, inklusive allen Mission CDs. Das 5 ist mir zu weit weg vom Original und der Charme ging auch verloren. 2 ist sicher das beste, nach 1 natürlich. :p

    Naja, die Konsumenten halt. Irgendjemand geht dann zum "Bäcker" und kauft sich ein "Brot" und "isst" das dann. ( Auf den Farmen wächst kein Wheat sondern Weed, aber pssst.. 😃 )

    Ich finds halt graphisch dargestellt viel übersichtlicher, machs bei mir aber immer auf Papier. Nix UML. Mit Ascii Art ist halt etwas unschön, aber Du bist ja draus gekommen 🙂
    Jetzt ists aber besser oder?



  • [quote=".filmor]/edit Joa, das letzte Diagramm sieht gut aus. Übrigens, die Creator Objekte (bitte nicht Builder, dass ist mehrdeutig) kannst du schön in ein Template verfrachten.[/quote] Ah ja? Was müsste ich für Parameter haben? Doch nur den Gebäudetyp oder?


Anmelden zum Antworten