[c++] besserer programmierstil/ rekursion ersetzen

zane2007

Grünschnabel
Hallo,
ich habe mal wieder mit c++ angefangen und habe aus dem stehgreif angefangen ein kleines zahlenraten zu programmieren. was mich überrascht ich habe es innerhalb eines abends geschaft...
das einziege ist, dass ich ein kleinen "schönheitsfehler" hab, aber zuerst der code:
Code:
#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;


void start();
void mode();
int grenze = 100;

int menü ()
{
    system("cls");
    int Wahl;

    cout << "###########ZAHLENRATEN##########" << endl
         << "################################" << endl
         << "(1)###########Start#############" << endl
         << "(2)#######Schwierigkeit#########" << endl
         << "(3)##########Beenden############" << endl;

    cin >> Wahl;

    return Wahl;
}


int main ()
{
    switch (menü ())
    {
    case 1: 
        start();
        break;
    case 2: 
        mode();
        main();
        break;
    case 3: 
        exit(0);
        break;
    default: cout << "Falsche Eingabe!";
    }

}

void start()
{
    system("cls");
    int x, og, i=0;
    char w;

    srand((unsigned) time(0));

    og = (rand()%grenze);

    system("cls");
    cout << "Raten sie los!!\n";
    
    do
    {
        i++;
        cin >> x;
        if (x < og)  cout<< "Die Zahl ist zu klein" << endl;
        if (x > og)  cout << "Die Zahl ist zu gross" << endl;
    } while (x != og);
    cout << "Gratuliere sie haben die Zahl erraten\n"
         << "Sie haben "<<i<<"´Versuche gebraucht!\n"
         << "Nochmal Spielen? (y/n)\n";
    cin >> w;
    if (w == 'y' || 'Y') main();
    else exit(0);

}

void mode()
{
    system("cls");
    cout <<"in welchem Bereich soll die zu erratende zahl leigen?"<< endl
         <<"Bitte die Obergrenze eingeben:" << endl;
    cin >> grenze;
}
so mein problem ist, dass ich nicht genau wusste wie ich das menü immer wieder aufrufen lassen kann wenn man die schwierigkeit geändert hat, so hab ich einfach eine rekursion gestartet (Zeile 39).
Und genau hier liegt das problem (denke ich), denn wenn ich die schwierigkeit ändere und dann ein spiel erfolgreich gemacht hab und 'n' eingebe, damit das programm beendet wird, wird aber wieder das menü angezeigt.

jetzt weiß ich nicht was ich dagegen machen soll. ich hoffe auf antwort.

mfg zane 2007
 
O

onlyfoo-na

Pack einfach noch eine while(true)-Schleife um den Inhalt deiner Main-Funktion und verzichte auf die Rekursion.
 

zane2007

Grünschnabel
das hab ich mir schon überlegt, aber irgendwie scheiterts an der bedingung, die ich für die schleife nehmen soll... denn es müsst ja solange durchlaufen, bis menü() == 3 ist, aber so kann ich es doch nicht in die schleife schreiben, denn dann würde der doch wieder menü aufrufen oder?
 

sheel

I love Asm
Also...

Zuerst einmal: Wenn du schon C++-Header verwendest, warum dann nicht konsequent?
Iostream hast du ja schon drinnen, aber dann kannst du statt "stdlib.h" auch gleich "cstdlib" verwenden
Die time.h gibts glaub ich auch als "ctime" (beide ohne .h)

2:
C++:
void start();
void mode();
ist da, warum nicht gleich auch für menü?
Geht zwar auch ohne, würde das ganze aber irgendwie übersichtlicher machen

3)das ü aus menü sollte weg. Erlaubt das dein Compiler? :suspekt:
Schreib menue, menu etc

4) Eine globale Variable für die Grenze ist nicht wirklich nötig.
Besser in mode den Wert zurückgeben
Hab ich im Code später noch drinnen.

5) An drei Stellen ein exit(0) ist auch nicht gerade toll...schau dir den Code unten an

Und zuletzt die von dir angesprochene main-Rekursion...ich würds so machen:
C++:
#include <iostream>
#include <cstdlib>
#include <ctime>
 
using namespace std;
 
int start();
int mode();
int menue();
 
int menue ()
{
    int Wahl;
 
    cout << "###########ZAHLENRATEN##########" << endl
         << "################################" << endl
         << "(1)###########Start#############" << endl
         << "(2)#######Schwierigkeit#########" << endl
         << "(3)##########Beenden############" << endl;
 
    cin >> Wahl;
 
    return Wahl;
}

int main ()
{
    int grenze=100, auswahl=0;
    while(auswahl!=3)
    {
        auswahl=menue();
        system("cls");
        if(auswahl==1)
        {
             if(!start())
                 break;
        }
        else if(auswahl==2)
            grenze=mode();
        system("cls");
    }
    return 0;
}
 
void start()
{
    int x, og, i=0;
    char w;
 
    srand((unsigned)time(0));
 
    og = (rand()%grenze);
 
    system("cls");
    cout << "Raten sie los!!\n";
    
    do
    {
        i++;
        cin >> x;
        if (x < og)  cout<< "Die Zahl ist zu klein" << endl;
        if (x > og)  cout << "Die Zahl ist zu gross" << endl;
    } while (x != og);
    cout << "Gratuliere sie haben die Zahl erraten\n"
         << "Sie haben "<<i<<"´Versuche gebraucht!\n"
         << "Nochmal Spielen? (y/n)\n";
    cin >> w;
    if (w == 'y' || w == 'Y') return 1;
    return 0;
}
 
int mode()
{
    int grenze;
    cout <<"in welchem Bereich soll die zu erratende zahl leigen?"<< endl
         <<"Bitte die Obergrenze eingeben:" << endl;
    cin >> grenze;
    return grenze;
}

start schau ich mir nochmal genauer an...

edit: So, das Ende von Start ist auch angepasst

Habs nicht getestet, sollte aber funktionieren.

edit2: Rechtschreibfehler im Programm hab ich jetzt einmal nicht korrigiert, das sollte aber das kleinste Problem sein :D
 
Zuletzt bearbeitet:

zane2007

Grünschnabel
ui danke für die schnelle antwort. also:

zu 1: ich kenn mich mit dem nutzen von headern nicht so sehr aus und ich hab halt gedacht, das das c im namen der header auf c und nicht auf cpp hinweißt, aber wenn ich jetzt überlege, dann müsste es ja auch nicht *.h sondern *.hpp heißen... ok, dass muss ich mir merken.

zu2: kann ich machen, wie gesagt war mein erstes c++ programm nach ca. 6-5 jahren. da war mir das noch nicht so wichtig, auserdem hab ich in dem moment mehr im stil von delphi programmiert (so wie wir es in der schule gelernt haben)^^

zu3: also microsoft visual c++ 2010 express hat sich deswegen noch nicht gemeldet.

zu4: das hab ich nur gemacht, weil ichtesten wollte wie das mit den globalen variabeln war. aber ich kann mich noch erinnern, dass man lieber sparsam mit den globalen variabeln umgehen muss.

zu der schleife: eigentlich wollte ich es verhindern mir eine neue variabel (auswahl) zu arbeiten, ich wollte es mal ohne "zwischenvariabel" probieren, aber so wie es aussieht, ist es unvermeindbar.

aber trozfem ein großes dankeschön für die hilfe zur späten stunden.

ps: auf rechtschreibung- und tippfehler- suche hatte und habe ich zur zeit keine lust.
 
Zuletzt bearbeitet:

sheel

I love Asm
2+4+Rechtschreibung: Macht doch nichts, solangs funktioniert :D

3: Interessant. Dann werd ich mal suchen, ob ich nicht auf dem aktuellsten Stand bin; oder MS schon wieder seine eigenen Ideen in die Sprache steckt.