Kentnisse über Klassen mittels Übung festigen



  • Hallo ihr Lieben, ich komme gleich zur Sache:

    Ich habe mir kürzlich erste Kentnisse über die objektorientierte Programmierung angeeignet. Um gelerntes anzuwenden und dadurch zu verinnerlichen, habe ich mir eine kleine Projektidee ausgedacht. Es handelt sich um ein Rollenspiel, welches ich gleich noch näher beschreiben werde.

    Ich stoße leider auf einige Probleme, wenn ich versuche darüber nachzudenken, wie man den Quellcode möglichst sauber gestalten kann.

    Kurz zu den Rahmenbedingen:
    Ich bin in der Lage eine Klasse mit (überladenen Konstruktoren) zu schreiben, die Begriffe public, private und protected korrekt anzuwenden und kann Klassen ableiten.
    Ich packe den gesamten Code in eine Datei, nix Modularisierung.

    Ein Problem was sich noch nebenbei ergibt: In Python beispielsweise gibt es Listen (Arrays), in denen man Daten völlig unterschiedlicher Datentypen hineinpacken kann. Etwas vergleichbares brauche ich für die Erstellung von Gegenständen auch in C++, da diese Werte haben, dessen Datentyp nicht immer übereinstimmt.

    Ich wollte nun alle Erfahrenen unter euch fragen, wie ihr mein Projekt strukturieren würdet, dazu stelle ich einmal den Grundriß vor:

    Es handelt sich um ein Rollenspiel, in dem man einen Magier spielt und gegen Monster kämpft. Es gibt hierbei zwei zentrale Phänomene bzw. Objekte, die existieren: Der Spieler und das Monster.

    ### SPIELER

    ## Der Spieler hat:

    # Werte:

    Stufe (int)
    Erfahrung (int)
    Leben (int)
    Schaden (Array; bestehend aus zwei Werten, Zufallsprinzip, wieviel Schaden gemacht wird)
    Mana (int; brauch man um Fähigkeiten zu wirken)

    # Gegenstaende

    Waffe (Name; Schadwert1, Schadwert2; z.B.: Zauberstab des Grauens, 10, 20)
    Rüstung (Name; Leben)
    Amulett (Name, Mana)

    # Fähigkeiten

    Feuerball (Verursacht Schaden * Stufe der Fähigkeit)
    Heilung (Der Spieler heilt sich im Kampf)

    ## Der Spieler tut:

    Stufen aufsteigen
    Faehigkeiten nutzen (z.B Feuerball zaubern)

    ### Monster

    ## Das Monster hat:

    Name (z.B. Wolf)
    Leben
    Schaden

    ## Das Monster tut:

    Im Kampf Faehigkeiten anwenden
    Beim Sterben Gegenstaende fallen lassen

    Das wär's soweit. Wie würdet ihr an die Sache rangehen? Welche Klassen sollten ungefähr wie erstellt werden? Ich bin froh über alle klugen Richtungsweisungen, die ich bekommen kann. 🙂



  • Ich will ein Autorennen programmieren ... da gibt es
    ### Autos

    ### Strecken

    ### Reifen

    ### Wetter

    Wie mache ich das?

    ------------------------------------------------------

    Soooo wirst du hier wahrscheinlich kaum eine Antwort erwarten dürfen. Die Leute hier im Forum helfen Dir aber sicher gerne, wenn du genauere Fragen stellst zu speziellen Problemen! Und ganz bestimmt, wenn du vorher schon ein wenig Eigeninitiative gezeigt hast.

    Ich würde da auch evtl. erstmal mit einem "kleineren" Projekt anfangen an deiner Stelle. z.B.
    https://tinodidriksen.com/2003/05/06/but-can-you-make-pong/

    -------------------------------------------------------

    Dexter1997
    "Ein Problem was sich noch nebenbei ergibt: In Python beispielsweise gibt es Listen (Arrays), in denen man Daten völlig unterschiedlicher Datentypen hineinpacken kann. Etwas vergleichbares brauche ich für die Erstellung von Gegenständen auch in C++, da diese Werte haben, dessen Datentyp nicht immer übereinstimmt. "

    Das ist doch schon mal eine spezielle Frage!

    Der Beispiel-Code wurde von mir mal aus dem Wiki-Artikel kopiert (URL s. unterhalb des Codes):

    #include <iostream>
    #include <cstdlib>
    #include <vector>
    #include <typeinfo>
    
    using namespace std;
    
    class A
    {
    	private:
    	public:
    		virtual int getStatus() = 0;
    };
    
    class B : public A
    {
    	private:
    		int status;
    	public:
    		B(int status)
    		{
    			this->status = status;
    		}
    		int getStatus()
    		{
    			return this->status;
    		}
    		// ... weitere Methoden
    };
    
    class C : public A
    {
    	private:
    		int status;
    	public:
    		C(int status)
    		{
    			this->status = status;
    		}
    		int getStatus()
    		{
    			return this->status;
    		}
    		// ... weitere Methoden
    };
    
    int main(void)
    {
    	vector<A*> vec;
    	int i;
    
    	// A *a = new A(1); // geht nicht da A abstrakt ist
    	B *b  = new B(2);
    	A *ab = new B(3);
    	C *c  = new C(4);
    
    	vec.push_back(b);
    	vec.push_back(ab);
    	vec.push_back(c);
    
    	for(i=0;i<vec.size();i++)
    	{
    		A *tmp = vec.at(i);
    		cout << "Value: " << tmp->getStatus() << " Klasse: " << typeid(*tmp).name() << endl;
    	}
    
    	delete b;
    	delete ab;
    	delete c;
    
    	cin.get();
    	return EXIT_SUCCESS;
    }
    

    https://de.wikibooks.org/wiki/C%2B%2B-Programmierung:_Polymorphie

    Wie du siehst, kann man in den Vektor "vec" mehrere untersch. Typen ("B", "C") stecken.



  • Da hast du aber echt mal ein hässliches Beispiel gefunden.
    Steht aber auch 'veraltet; wird nicht gepflegt' dran.



  • Erstmal vielen Dank für die Antwort. Der erstgenannte Link läßt sich bei mir leider nicht öffnen, da ich eine Meldung erhalte, die besagt, daß die Seite nicht sicher sei oder sowas. Nur eins regt mich doch ein wenig auf...

    Teacher schrieb:

    Soooo wirst du hier wahrscheinlich kaum eine Antwort erwarten dürfen. Die Leute hier im Forum helfen Dir aber sicher gerne, wenn du genauere Fragen stellst zu speziellen Problemen! Und ganz bestimmt, wenn du vorher schon ein wenig Eigeninitiative gezeigt hast.

    Man muß nicht immer spezielle Fragen stellen. Es gibt nicht nur sture Mathematik und einen Plan sondern auch Nachdenken und Grübeln. Und so unkonkret wie in deinem Beispiel war mein Entwurf nun wirkklich nicht, ich habe zwar nichts ausformuliertes gegeben, aber auch nichts ausformuliertes erwartet, lediglich einen kleinen Richtungshinweis.

    Sicher habe ich schon eigene Ansätze entwickelt, die ich aber allesamt in die Tonne treten konnte. Ich nenne mal ein Beispiel:

    Ich hätte eine Klasse Mensch und eine Klasse Monster erstellt, weil alles andere
    keinen Sinn macht.
    Nun kann der Mensch beispielsweise das Monster angreifen, weswegen man eine Elementmethode Angreifen() schreibe. Diese Methode soll den Lebenswert des Monsters reduzieren. Da aber von der Programmiererkaste einschlägig davon abgeraten wird, Elementvariablen public zu setzen, weiß ich nicht wie ich unter dieser Einschränkung auf eine Elementvariable der Klasse Monster mit einer fremden Methode einer fremden Klasse zugreifen soll... Es gäbe Möglichkeiten, die Dinge anders zu strukturieren. Dann würden sie aber unlogisch und verworren werden. Und das soll ja nicht passieren...



  • Ich fand die Frage jetzt auch nicht so unspezifisch. Es ist aber auch nicht so wirklich klar, was man darauf antworten soll...

    z.B. "In Python beispielsweise gibt es Listen (Arrays), in denen man Daten völlig unterschiedlicher Datentypen hineinpacken kann. Etwas vergleichbares brauche ich für die Erstellung von Gegenständen auch in C++, da diese Werte haben, dessen Datentyp nicht immer übereinstimmt.":

    - Nein, brauchst du nicht
    - virtual ist schon ein gutes Stichwort, nur ist das Beispiel wirklich hässlich
    - type erasure wäre ein anderes Stichwort, aber vielleicht noch etwas zu fortgeschritten
    - generell in dem Zusammenhang "Component Entity System", aber wahrscheinlich auch noch etwas zu fortgeschritten

    Du brauchst keine Elementvariablen public machen. Dein "Gegner" kann ja auch eine Methode zum Reduzieren seiner Werte anbieten.
    Das ganze ist übrigens gar nicht so ohne. Ein textbasiertes Rollenspiel zu schreiben kann ziemlich interessant und beliebig komplex werden. Finde ich auch interessanter als dieses Pong Beispiel.



  • Dexter1997 schrieb:

    Ich hätte eine Klasse Mensch und eine Klasse Monster erstellt, weil alles andere
    keinen Sinn macht.
    Nun kann der Mensch beispielsweise das Monster angreifen, weswegen man eine Elementmethode Angreifen() schreibe. Diese Methode soll den Lebenswert des Monsters reduzieren. Da aber von der Programmiererkaste einschlägig davon abgeraten wird, Elementvariablen public zu setzen, weiß ich nicht wie ich unter dieser Einschränkung auf eine Elementvariable der Klasse Monster mit einer fremden Methode einer fremden Klasse zugreifen soll... Es gäbe Möglichkeiten, die Dinge anders zu strukturieren. Dann würden sie aber unlogisch und verworren werden. Und das soll ja nicht passieren...

    Du solltest dir an dieser Stelle überlegen wer am Ende welche Entscheidungen trifft. Nicht jede Klasse die du baust muß aktiv auftreten, es gibt durchaus die Möglichkeit Container zu schaffen die alle wichtigen Daten halten und die Daten ausgeben und Empfangen können. So könnte dein Mensch zB eine Funktion "Angriff ausführen" besitzen und dein Monster eine Funktion "Angriff abwehren" bei denen verschiedene Ergebnisse auftreten können die von einer Logik aufgerufen und bewertet werden.



  • Servus,

    ich wäre bereit etwas zu helfen. Aber nur mal so ne Frage: Das soll schon textbasiert in der Konsole ablaufen, oder?

    LG


Anmelden zum Antworten