Schere Stein Papier
-
Hab mal ein kleines Schere Stein Papier für die win32 console geschrieben.
Was haltet ihr davon?
viel Spass beim spielen#include <iostream> #include <ctime> #include <string> using namespace std; class Symbol{ public: Symbol(){ gewinnt = 0; verliert = 0; bezeichnung = ""; } string bezeichnung; Symbol* gewinnt; Symbol* verliert; }; int main(){ const int MAX_SYMBOL = 3; int iComputer; int iSpieler; string sEingabe; Symbol Schere; Symbol Stein; Symbol Papier; Symbol *Symbole[MAX_SYMBOL] = { &Schere, &Stein, &Papier }; srand((unsigned int) time(0)); Schere.bezeichnung = "Schere"; Stein.bezeichnung = "Stein"; Papier.bezeichnung = "Papier"; Schere.verliert = &Stein; Schere.gewinnt = &Papier; Stein.verliert = &Papier; Stein.gewinnt = &Schere; Papier.verliert = &Schere; Papier.gewinnt = &Stein; for(;;){ cin >> sEingabe; if(sEingabe[0] == 'e' || sEingabe[0] == 'E') break; iSpieler = -1; for(int i = 0; i < MAX_SYMBOL; i++){ if(sEingabe == Symbole[i]->bezeichnung) iSpieler = i; } if(iSpieler == -1) continue; iComputer = rand()%MAX_SYMBOL; cout << Symbole[iSpieler]->bezeichnung << " vs. " << Symbole[iComputer]->bezeichnung << endl; if(iComputer == iSpieler) cout << "Unentschieden!" << endl; else if(Symbole[iComputer]->gewinnt == Symbole[iSpieler]) cout << "Verloren!" << endl; else cout << "Gewonnen!" << endl; } }
mfG danie
-
Bei Zeile 37 hast du einen C-Cast. Und ich würde statt einer Endlosschleife mit einem
break
eher eine normale Schleife und eine kluge Abbruchbedingung nutzen.Tipp: Vermeide
using namespace std;
, es ruft Bezeichnerkonflikte hervor.
Tipp: Du hast einigeint
s, die duunsigned
hättest machen können.
Tipp: Wenn alles einer Klassepublic
ist, kannst du gleich einstruct
machen.Übung: Versuche es mal mit Enumatoren und einer
std::map
.Gut gemach! Weiter so
-
SUPER! Kompiliert mit VS2010 fehlerfrei. Leider fehlt eine Anleitung und
das Programm ist ohne Quelltext und OOP-Kenntnisse fast nicht spielbar.Eine Hilfe zum Programmstart wäre gut:
cout << "Geben sie bitte "; for(int i = 0; i < MAX_SYMBOL; i++) cout << Symbole[i]->bezeichnung << " "; cout << "oder E (=Ende) ein" <<endl;
Sowie ein Userfeedback in Fehlerfall:
if(iSpieler == -1) {
cout << "Keine gueltige eingabe" << endl;
continue;
}Danke für das nette Beispiel
-
Habe das Proggi nochmal etwas optimiert:
#include <iostream> #include <ctime> #include <string> using namespace std; enum ERGEBNIS {unendschieden, gewonnen, verloren}; enum ELEMENT {Schere, Stein, Papier, MAXELEMENTS}; int Name2Num(string name) { if(name == "Schere") return Schere; if(name == "Stein") return Stein; if(name == "Papier") return Papier; return -1; } class Symbol{ public: Symbol(string name){ bezeichnung = name; gewinnt = -1; verliert = -1; // Spielregeln if(name == "Schere") { gewinnt = Papier; verliert = Stein; } // besser waere: gewinnt = Name2Num("Stein"); verliert ist überflüssig if(name == "Stein") { gewinnt = Schere; verliert = Papier; } if(name == "Papier") { gewinnt = Stein; verliert = Schere; } } int Vergleich(string name); string GetName(){ return bezeichnung; }; private: string bezeichnung; int gewinnt; int verliert; }; int Symbol::Vergleich(string name) { int ergebnis = unendschieden; // bezeichnung == name int gegner = Name2Num(name); if(gegner == -1) ergebnis = -1; if(gegner == gewinnt) ergebnis = verloren; if(gegner == verliert) ergebnis = gewonnen; return ergebnis; } int main(){ int iComputer, iSpieler, iErgebnis; string sEingabe; Symbol CSchere("Schere"); Symbol CStein("Stein"); Symbol CPapier("Papier"); Symbol *Symbole[MAXELEMENTS] = { &CSchere, &CStein, &CPapier }; srand((unsigned int) time(0)); cout << "Geben sie bitte "; for(int i = 0; i < MAXELEMENTS; i++) cout << Symbole[i]->GetName() << " "; cout << "oder E (=Ende) ein" << endl; for(;;){ cout << ">"; cin >> sEingabe; if(sEingabe[0] == 'e' || sEingabe[0] == 'E') break; iSpieler = Name2Num(sEingabe); if(iSpieler == -1) { cout << "Keine gueltige eingabe" << endl; continue; } iComputer = rand()%MAXELEMENTS; cout << Symbole[iSpieler]->GetName() << " vs. " << Symbole[iComputer]->GetName() << endl; iErgebnis = Symbole[iComputer]->Vergleich(sEingabe); switch(iErgebnis) { case unendschieden: cout << "Unentschieden!" << endl; break; case gewonnen: cout << "Gewonnen!" << endl; break; case verloren: cout << "Verloren!" << endl; break; default: cout << "Kein Ergebnis ?" << endl; } } }
1. Membervariablen nicht public
2. Elementname im Konstruktor angebbar
3. Spielregeln in der Klasse gekapselt
4. Enums verwendet- Vielleicht wäre es besser als Parameter für die Memberfkt. int zu
verwenden.- Die Membervariable verliert ist überflüssig.
Das Problem mit std kann ich nicht nachvollziehen. Ich habe jedenfalls keine Lust bei jedem cout auch noch den Namespace anzugeben ...
-
merano schrieb:
Das Problem mit std kann ich nicht nachvollziehen.
Bezeichnerkollision?
Zeile 62 ein unnötiger C-Cast.
Zudem läuft dein Code mit C++0x nicht mehr (enum
missbraucht!).
Zudem noch unlokale Deklarationen bei Zeile 50 & Zeile 52.
Wieder Spaghetti-Code (continue
und Schleifen-break
)...
Keine Stream-Checks (EOF
,fail
undbad
).
Dann noch ein rohes Array .
Und eine#include
-Direktive fehlt:std::rand
undstd::srand
aus<cstdlib>
.
Zudem hätte man Zeilen 41 bis 43 eleganter lösen können.
Und was sollen all die Präfixe?
-
EOutOfResources schrieb:
Zudem läuft dein Code mit C++0x nicht mehr (
enum
missbraucht!)Könnten wir denn mal eine politisch korrekte Version von dir bekommen ?
Übrigens der C++0x ist kein Standard und wird wohl erst im Herbst 2011 als
Standard C++11 fertig werden. Wir reden also ein Stück weit über ungelegte
Eierhttp://www.linux-magazin.de/NEWS/C-0x-wird-als-C-11-standardisiert
Solange VS2010 nicht mal eine Warnung erzeugt sehe ich kein Problem - bin aber an Verbesserungen immer interessiert.
EOutOfResources schrieb:
Zudem hätte man Zeilen 41 bis 43 eleganter lösen können.
Ja. Habe ich bereits zugestanden.
EOutOfResources schrieb:
Und was sollen all die Präfixe?
Die sogenannte Ungarische Notation ist unter Windows absolut üblich - macht den
Code besser lesbar. Wen es stört, der kann seine Variablen auch anders benennen.
-
merano schrieb:
EOutOfResources schrieb:
Und was sollen all die Präfixe?
Die sogenannte Ungarische Notation ist unter Windows absolut üblich - macht den
Code besser lesbar. Wen es stört, der kann seine Variablen auch anders benennen.Die ungarische Notation (in der Form, wie du sie verwendest) ist Unsinn - das haben selbst die Microsoft'ler inzwischen eingesehen.
-
CStoll schrieb:
Die ungarische Notation ist Unsinn
Und für C++ überhaupt nicht geeignet.
-
ich hab die ungarische Notation auch früher öfter verwendet, aber bin inzwischen davon weg, weil es einfach nicht mehr nötig ist, bei all der Intellisense und den recht guten IDEs, die es inzwischen viel einfacher machen, den Hintergrund einer Variable zu erkennen.
-
Danke für die vielen Beiträge
ich versuche es gerade mit einer std::map umzusetzen, stehe aber auf dem Schlauch. Naja wenn ichs hinbekommen hab werde ich es posten.