Weltraumvernichtungssimulator
-
Stromberg schrieb:
Wie der Name schon sagt geht es darum den Weltraum zu vernichten.


Stromberg schrieb:
Mh ich glaub aber irgendwie das des n schlechter Stil ist, wenn ich das so mache. Wie würde ihr das machen?
Hab sowas noch nie gemacht, aber ich glaube ich würde es so tun:
Eine Klasse schreiben für ein "Event", also ein Ereignis, das eintreten kann. Die Klasse verwaltet die Frage die Antwortmöglichkeiten und wo man danach hinkommt.
So ungefähr:// Verwaltet alle Sachen die passieren, wenn eine Frage ausgewählt wurde class AnswerObject { public: string getAnswerString() const; // Wird aufgerufen, wenn diese Antwort ausgewählt wurde void OnCalled() { // Evtl irgendwas machen neue_frage.OnCalled(); } private: string answer; MirFälltKeinNameEin neue_frage; }; class MirFälltKeinNameEin { public: void OnCalled() { cout << question << endl; for ( size_t i=0; i<answers.size(); i++ ) cout << i+1 << ": " << answers[i].getAnswerString() << endl; unsigned int sel; // <- Kurzform für "Selection" :) cin >> sel; if ( sel < answers.size() ) answers.OnCalled(); } private: string question; // beinhaltet die Frage vector<AnswerObject> answers; // beinhaltet die Antworten };Ok, ziemlich schlecht geworden, aber ungefähr so in der Richtung würde ich's machen

-
@(D)Evil
Mh, also was struct ist weiß ich eigentlich schon, aber vll. hab ich nur immer Tutorials gemacht die "struct" nur ganz kurz beschrieben haben gelesen.... part(const std::string& question, const std::string answer_a, const std::string& answer_b, const std::string& answer_c, const std::string& effect_one, const std::string& effect_two, const std::string& effect_three) : question(question) { answer[0] = answer_a; answer[1] = answer_b; answer[2] = answer_c; effect[0] = effect_one; effect[1] = effect_two; effect[2] = effect_three; } ...Struct ist doch sowas wie eine Klasse nur das alles public ist oder?
Was soll den das ": question(question)". Und du hast dem vector ja dann "part" als Datentyp gegeben, aber in "struct part" gibts ja wieder eine Funktion namens part, mhh ich versteh des jetzt ent so ganz, ich kann doch über den vector keine Funktion dann mal aufrufen, oder geht des? Wird die Funktion part überhaupt irgendwo aufgerufen?
Und kannst du mir erklären warum genau du den Operator << überladen hast?
Erklär mir doch bitte deinen Code
Dankeschön schon mal im Voraus.
-
Das ist der Konstruktor.
Und ja structs sind wie Klassen nur default public.
Und da es Klassen sind können sie eben auhc Funktionen und
Kon bzw. Destruktoren enthalten.Das ": question(question)" nennt man Initalisierungsliste.
Dort kannst du die member deiner Klasse mit Werten initalisieren
(im Konstruktor selbst kannst du ihnen nur Werte zuweisen, was nicht dasselbe ist)
-
Aso...ich kann des fast wie eine echt Klasse ansehen...also auch mit Konstruktor und so. Aha. Kann ich eigentlich auch Klassen als Typ von nem vector angeben? Und was würde jetzt passieren wenn es in struct noch eine methode gäb? Was könnte ich in einem vector damit anfangen? Würde das überhaupt gehen?
MfG
Stromberg
-
Na klar würde das gehn, solange es sinnvoll ist.
Kleines Beispiel:#include <iostream> #include <vector> using namespace std; class Auto { public: //Hier der Konstruktor mit Initalisierungsliste Auto(string typ="Noname") : typ(typ) { cout << typ << " ist bereit zum fahren" << endl; } //Der Destruktor ~Auto() { cout << typ << " wurde verschrottet" << endl; } //Und noch eine Methode void Fahren() { cout << typ <<" fährt" << endl; } private: //Und hier ein Member string typ; }; int main() { //Der vector stellt jetzt eine Art Garage für //unsere Klasse Auto dar. In ihm können wir Auto "parken" vector<Auto> Garage; //Nun parken wir in unserer Garage einige Autos Garage.push_back(Auto("BMW")); Garage.push_back(Auto("Mercedes")); Garage.push_back(Auto("Opel")); //Wieviele Autos hab ich jetzt in meiner Garage? int size = Garage.size(); //Die will ich alle fahren for(int i = 0; i < size; i++) Garage[i].Fahren(); return 0; }
-
So hab mal nen neuen Code geschrieb, mit den Impressionen von euch:
#include <iostream> #include <vector> #include <string> using namespace std; struct part { string m_question, m_a, m_b, m_c, m_effect1, m_effect2, m_effect3; part(const string question_,const string a_,const string b_,const string c_,const string effect1_, const string effect2_,const string effect3_); }; part::part(const string question_,const string a_,const string b_,const string c_,const string effect1_, const string effect2_="",const string effect3_="") { m_question=question_; m_a=a_; m_b=b_; m_c=c_; m_effect1=effect1_; m_effect2=effect2_; m_effect3=effect3_; } class game { public: game(); ~game(); inline void new_story(const part& data) {m_story.push_back(data);} void set_story(size_t index); inline bool check() const; inline bool get_end() const {return m_end;} private: vector<part> m_story; short m_save; bool m_end; }; game::game() { } game::~game() { } void game::set_story(size_t index) { cout << m_story[index].m_question; cout << m_story[index].m_a; cout << m_story[index].m_b; cout << m_story[index].m_c; cin >> m_save; if (check()) { if (m_story[index].m_effect2=="" and m_story[index].m_effect3=="") { cout << m_story[index].m_effect1; } else { switch(m_save) { case 1: cout << m_story[index].m_effect1; break; case 2: cout << m_story[index].m_effect2; break; case 3: cout << m_story[index].m_effect3; break; } } } } bool game::check() const { if (m_save<1 or m_save>3) { cout << "Du bist doch Deutschlands d" << "\x81" << "mmster! Ist es so schwierig ein Zahl zwischen \n"; cout << "1 und 3 zu dr" << "\x81" << "cken?\n"; return false; } return true; } int main() { game wus; wus.new_story("Wer wollen sie sein?\n", "1. Hitler\n","2. Gahndi\n","3. Georg W. Bush\n", "Sie sind nun Hitler!\n", "Sie sind nun Gahndi!\n", "Sie sind nun Georg W. Bush!\n"); return 0; }nur kommt immer folgender Fehler:
-------------- Build: Debug in GAME ---------------
Compiling: main.cpp
main.cpp: In functionint main()': main.cpp:102: error: no matching function for call togame::new_story(const char[22], const char[11], const char[11], const char[18], const char[22], const char[22], const char[29])'
main.cpp:32: note: candidates are: void game::new_story(const part&)
Process terminated with status 1 (0 minutes, 0 seconds)
2 errors, 0 warningsWas ist falsch? Ich schaffs irgendwie nicht mehr, es ist schon zu spät für mich. Wer noch wach genug ist der solls mir doch bitte sagen.

MfG
Stromberg
-
wus.new_story( part( "Wer wollen sie sein?\n", "1. Hitler\n","2. Gahndi\n","3. Georg W. Bush\n", "Sie sind nun Hitler!\n", "Sie sind nun Gahndi!\n", "Sie sind nun Georg W. Bush!\n") );Das "part( " ist neu (und hinten die entsprechende schließende Klammer)

-
wenn das ein adventure gibt, hast ja immerhin 0,01 % vom Code geschaft;)
-
Aber du solltest auch nen streamoperator für deine struct "part" anlegen. Dann Initialisierungsliste nutzen, check einfach rausnehmen ... die ist nicht schön ... die komische m_end-Variable rausnehmen ... Default-Konstruktor lassen ...
=>class game { public: struct part { std::string question; std::string answer[3]; std::string effect[3]; part(const std::string& question, const std::string answer_a, const std::string& answer_b, const std::string& answer_c, const std::string& effect_one, const std::string& effect_two, const std::string& effect_three) : question(question) { answer[0] = answer_a; answer[1] = answer_b; answer[2] = answer_c; effect[0] = effect_one; effect[1] = effect_two; effect[2] = effect_three; } friend std::ostream& operator<< (std::ostream&, const game::part&); }; public: void new_story(const part& data) { m_story.push_back(data); } void show_story(std::size_t) const; private: std::vector<part> m_story; }; std::ostream& operator<< (std::ostream& out, const game::part& data) { out << data.question << "\n"; for (std::size_t i = 0; i < 3; ++i) out << data.answer[i] << "\n"; return out; } void game::show_story(std::size_t index) const { std::cout << m_story.at(index) << std::endl; unsigned short answer = 0; while (!(std::cin >> answer) || answer < 1 || answer > 3) { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } if (m_story.at(index).effect[1].empty() == true && m_story.at(index).effect[2].empty() == true) { std::cout << m_story.at(index).effect[0] << std::endl; return; } std::cout << m_story.at(index).effect[answer - 1] << std::endl; } int main() { game new_game; new_game.new_story(game::part( "Wer wollen sie sein?", "1. Hitler", "2. Gahndi", "3. Georg W. Bush", "Sie sind nun Hitler!", "Sie sind nun Gahndi!", "Sie sind nun Georg W. Bush!")); new_game.show_story(0); }
-
Ich würde gern noch einige Teile von (D)Evil's Code übernehmen, aber zum Beispiel bei dem Teil mit dem überladen von "<<" blick ich nicht durch. Also muss ich erst bisschen üben bis ich mich mit dem operator "<<" auskenne....sonst is ja sinnlos wenn ich nur abschreibe.
Also hab ich bissel in so nem Tutorial "rumgestöbert". Aber ich kenn mich imemr noch nicht richtig aus.
Wollte folgendes schreiben:#include <iostream> using namespace std; ostream& operator<<(ostream &out, string a); int main() { string l="Hans"; string m="Werner"; string n="Uschi"; cout << l << m << n; return 0; } ostream& operator<<(ostream &out, string a) { cout << a << " "; return out; }Ich wollte das so konstruieren, das wenn man die 3 String aneinandereit, das dann automatisch ein Leerzeichen eingfügt wird.
So ich hab aus dem Tutorial gelernt das cout so funktioniert:
cout << a << b << "\n" << "Blub";
((((cout << a) << b) << "\n" ) << "Blub")
Deshalb muss man unbedingt wieder das selbe cout Objekt vom anfang zurückgeben, sonst wär da nichts mehr weil der Befehl halt einfach ausgeführt worden wäre, und "rhs" könnte mit "lhs" nichts mehr anfangen. Und das wär so verpufft!!! Weg halt, oder kp was dann passiert. Stimmts bis jetzt?
Und dann hab ich mir halt einfach gedacht schreib ich den "string a" hin, + " das leerzeichen. Und gebe wieder das "Ur" cout Objekt zurück.
Mh des funzt bei mir aber net, bzw. es gibt keine Ausgabe, die Ausgabe ist gleich NULL :D!Nichts halt einfach. So was nun tun?
MfG
Stromberg
-
ehm weiß nicht ob er deinen operator nimmt aber:
std::ostream& operator<<(std::ostream&, const std::string&); int main() { std::string l("Hans"); std::string m("Werner"); std::string n("Uschi"); std::cout << l << m << n; return 0; } std::ostream& operator<<(std::ostream& out, const std::string& str) { out << str << " "; return out; }
-
@(D)Evil: Dein Programm resultiert bei mir (MinGW) in "Process terminated with status -1073741819". Wenn man das ganze mit einer eigenen Klasse macht scheint das irgendwie besser zu gehen. Folgendes funktioniert bei mir:
#include <iostream> #include <string> class MyString { friend std::ostream& operator<< (std::ostream& out, const MyString& obj); // ^^^^^^ damit wir Zugriff auf private member haben public: MyString(const std::string& s) : data(s) {} private: std::string data; }; std::ostream& operator<< (std::ostream& out, const MyString& obj) { out << obj.data << " "; // ^^^ return out; } int main() { MyString a("Hans"); MyString b("Werner"); MyString c("Uschi"); std::cout << a << b << c << std::endl; }
-
hmm ... ist ja auch logisch
Das verursacht eine Endlosschleife
Im Code wird ja der streamoperator wieder von sich selbst aufgerufen!std::ostream& operator<<(std::ostream& out, const std::string& str) { out << str.c_str() << " "; return out; }würde es unter umständen tun

-
Ah also was ich erst ma gelernt habe, is klar man leitet alles in das Objekt "out" rein und gibt dieses dann zurück. Ich hab da ja vorhin was mit cout gemacht....--> unsinn.
Wie "ohnename" schon gesagt hat, funktionierts bei mir auch nicht. (hab auch MinGW). Hmm...warum geht das ganze dann nur wenn mans in eine Klasse schreibt?
Mir fällt langsam auf, das ihr alle bei den Parametern (fast) IMMER Referenzen
nutzt. Ich hab gedacht sowas macht man nur bei Objekten, bzw. wenn man Variablen übergibt und nicht wenn man was mit Hand reinschreibt. Aber okay, auch wenn man anscheinend was mit Handreinschreibt, wird mit diesem dann eine Variable\Objekt.. erzeugt....und somit wieder --> Kopie --> Zeitaufwand.
Zumindestens nehm ich in Zukunft als Parameter dann halt auch immer Referenzen.MfG
Stromberg
-
(D)Evil schrieb:
ehm weiß nicht ob er deinen operator nimmt aber:
std::ostream& operator<<(std::ostream&, const std::string&); int main() { std::string l("Hans"); std::string m("Werner"); std::string n("Uschi"); std::cout << l << m << n; return 0; } std::ostream& operator<<(std::ostream& out, const std::string& str) { out << str << " "; return out; }Ich hab mal versucht das nachzuvollziehen...
Baust du dir hier nicht eine Endlosrekursion? Du rufst dich ja mit deinem Operator immer wieder selber auf...

Bei mir funktioniert er so....
std::ostream& operator<<(std::ostream&, const std::string&); int main() { std::string l("Hans"); std::string m("Werner"); std::string n("Uschi"); std::cout << l << m << n; return 0; } std::ostream& operator<<(std::ostream& out, const std::string& str) { for(int i = 0; i < str.length(); i++) out.put(str[i]); out.put(' '); return out; }[Edit:]
Ups, zu spät...
Gruß
zeigerzeiger
-
std::ostream& operator<<(std::ostream&, const std::string&);Das ist ganz schön brutal.
-
Stromberg schrieb:
Ich wollte eine Textadventure (was anderes kann ich net^^) machen, namens "weltraumvernichtungssimulator". Wie der Name schon sagt geht es darum den Weltraum zu vernichten.

Nette Idee. Klingt wie eine Space Quest Episode.

-
Wenn es zu einer endloschlefie führt, warum führt das denn dann eigentlich nicht zu einer, ist doch so n ähnliches System: [ausm anfangs Code der von (D)Evil gepostet wurde]
std::ostream& operator<< (std::ostream& out, const game::part& data) { out << data.question << "\n"; for (std::size_t i = 0; i < 3; ++i) out << data.answer[i] << "\n"; return out; }std::ostream& operator<<(std::ostream& out, const std::string& str) { out << str.c_str() << " "; return out; }Ah okay, ich glaub das verstehe ich, du hast halt keinen "string" mehr nach dem Operator "<<":
out << str.c_str() << " ";sondern machst mit "str.c_str()" einen C-String draus, sodass der überladene Operator "<<" nicht mehr drauf anschlägt. Als was wird den eigentlich " " angesehen, als C-String, also char? Und was wäre wenn das noch "BLABLA" stände, würde das dann auch als char angesehen, oder wärs n string...? Weil wenns n string wäre, dann würde der Operator "<<" ja wieder anschlagen. Hab ich das richtig verstanden?
Wies "zeigerzeiger" gemacht hat, hab ich glaub auch ungefähr verstanden, und zwar:
std::ostream& operator<<(std::ostream& out, const std::string& str) { for(int i = 0; i < str.length(); i++) out.put(str[i]); out.put(' '); return out; }Du hast eine for Schleife vom Buchstaben anfang bis zum Buchstaben Ende vom string "str" runtergezählt, in dieser stopftst du die einzelnen Buchstaben in "out" mit "put" rein? Woher kommt "put" hab ich noch nie gehört davon....
? Ist "put" sowas wie "<<"? Dann müsst ich glaub auch deine Funktion verstanden haben. Welche von beiden ist den nun schneller?@camper
Warum ist das ganz schön burtal? Stimmts etwa doch nicht? Des hatt mich jetzt bissel verwirrt.MfG
Stromberg
-
Woher kommt "put" hab ich noch nie gehört davon....
? Ist "put" sowas wie "<<"?http://www.cplusplus.com/reference/iostream/ostream/put.html ... nein. std::ostream::put(char c) ist eine Funktion, std::ostream::operator<< ist ein Stream-Operator.
warum führt das denn dann eigentlich nicht zu einer, ist doch so n ähnliches System
Nope. Du überlädst da ja den operator<< für game::part und nicht für std::string. data.question ist aber ein std::string!
Als was wird den eigentlich " " angesehen, als C-String, also char?
er sollte es als const char* interpretieren: { ' ', '\0' } ...
Und was wäre wenn das noch "BLABLA" stände
{ 'B', 'L', 'A', 'B', 'L', 'A', '\0' } => const char* ...
-
Stromberg schrieb:
@camper
Warum ist das ganz schön burtal? Stimmts etwa doch nicht? Des hatt mich jetzt bissel verwirrt.Ist keine Frage von stimmen. Es verändert die Semantik einer bereits wohldefinierten Operation in nichttrivialer Weise. Das es überhaupt geht, ist nur dem Zufall geschuldet (hier: die normale Überladung für diesen Fall ist eine Templatefunktion).