Problem bei Zahlenrate Programm



  • #include <windows.h> 
    #include <mmsystem.h> //<< Diesen Header noch einbinden, dann wird auch timeGetTime () erkannt und mit eingebunden!
    

    mfg



  • Hallo, hab das probiert was du mir vorgeschlagen hast aber ich bekomme immernoch den selben fehler.

    [Linker error] undefined reference to `timeGetTime@0'
    ld returned 1 exit status
    C:\Dev-Cpp\Projekts\Zahlenraten2\Makefile.win [Build Error] [Projekt1.exe] Error 1



  • @Balduin: Linker-Fehler wirst du kaum durch zusätzliche Includes beheben können 😉

    @Sebbo: Geh mal in die Projekteinstellungen und trag dort die "winmm.lib" bei den Linker-Optionen ein. Oder denk nochmal über Jockelx' Aussage nach und ändere das "srand(timeGetTime());" in "srand(time(NULL));" (dafür brauchst du noch die <ctime>) - mit Standard-Funktionen bist du idR besser beraten als mit systemspezifischen Lösungen.



  • also ich hab das ganze nochma überarbeitet und habs jetzt soweit laufen.

    habe das srand auf NULL gesetzt. Dabei is mir aufgefallen das es auch ohne das includieren der <ctime> funktioniert.

    Bin auf jedenfall ziemlich beeindruckt wie Komplex C++ im vergleich zu Visual Basic ist. Werde mich da voll reinknien!
    Und auch sehr krass was für ein Maß an wissen hier in diesem Forum steht!!!

    Danke für eure antworten. falls jemand noch verbesserungsvorschläge hat bitte Posten.

    hier nochmal das aktuelle listing

    // Autor: Sebbo
    // Datum: 2.2.07
    // Title: Zahlenraten
    // version: 1.0
    
    #include <iostream>
    #include <windows.h>
    
    using namespace std;
    
    #pragma comment (lib, "winmm.lib")
    
    // Funktionsprototypen
    //
    int Spielen (int Level);
    int WaehleLevel (int Level);
    int TesteHighscore (int Punkte, int Highscore);
    void ZeigeInfos();
    
    // Hauptprogramm
    //
    int main()
    {
        // Variablen
        //
        char Auswahl;           // Gewählter Menüpunkt
        int Level = 5;          // Aktueller Level
        int Highscore = 100;    // Aktueller Highscore
    
        // Zufallszahlengenerator initialisieren
        //srand (timeGetTime());
        srand(time(NULL));
        //Verarbeitung des Menüs
        do
        {
            // Menü ausgeben
            //
            cout << "Zahlenraten - Menue " << endl;
            cout << "--------------------" << endl;
            cout << "(N)eues spiel starten" << endl;
            cout << "(L)evel waehlen" << endl;
            cout << "(H)ighscore anzeigen" << endl;
            cout << "(I)nfo" << endl;
            cout << "(B)eenden\n\n";
    
            // Eingabe abfragen
            cout << "Auswahl: ";
            cin >> Auswahl;
    
            // je nach eingabe verzweigen
            switch (Auswahl)
            {
                //Neues Spiel Starten
                case ('n'):
                case ('N'):
                {
                    // Spielen
                    int Punkte;
                    Punkte = Spielen (Level);
    
                    Highscore = TesteHighscore (Punkte,Highscore);
                }break;
    
                //Level Wählen?
    
                case ('l'):
                case ('L'):
                {
                    Level = WaehleLevel (Level);
                }break;
    
                //Highscore anzeigen?
                case ('h'):
                case ('H'):
                {
                    cout << "Der Aktuelle Highscore liegt ebi: ";
                    cout << "Highscore " << "Punkte \n\n";
                }break;
    
                //Informationen anzeigen
                case ('i'):
                case ('I'):
                {
                    ZeigeInfos ();
                }break;
    
                // Spiel beenden?
                case ('b'):
                case ('B'):
                {
                    cout << "Spiel beendet." << endl;
    
                }break;
    
                // Falsche eingabe ?
                default:
                {
                    cout << "Falsche Eingabe!\n\n";
    
                }
            }
        }while (Auswahl != 'b' && Auswahl != 'B'); // Spiel beenden?
    
        cout << "Bis zum naechsten mal" << endl;
    
        return 0;
    } // main
    
    //Zeige Infos
    //
    // Aufgabe: Informationenj zum spiel zeigen
    //
    void ZeigeInfos ()
    {
        cout << "Zahlenraten V1.0" << endl;
        cout << "Uebungsspiel zur C++ Programmierung" << endl << endl;
    } // Zeige infos
    
    // Waehle level
    //
    // Aufgabe: Neuen Level waehlen
    //
    int WaehleLevel (int Level)
    {
        int NeuerLevel;
    
        do
        {
            // Neuen Level Waehlen
            cout << "Aktueller Level " << Level << endl;
            cout << "Neuer Level: ";
            cin >> NeuerLevel;
    
            // Ungueltige eingabe
            if (NeuerLevel <1 || NeuerLevel >10)
            {
                // Fehlermeldung
                cout << "Ungueltige Eingabe. 1-10" << endl;
            }
        }while (NeuerLevel < 1 || NeuerLevel > 10);
    
        // Gewählten Level zurück geben
        return NeuerLevel;
    } // Waehle Level
    
    // Spielen
    //
    // Aufgabe Das eigendliche Spiel
    //
    int Spielen (int Level)
    {
        int Zufallszahl;            // Zufallszahl die erraten werden muss
        int GerateneZahl = 0;       // Zahl die der spieler eingibt
        int Bereich = Level * 10;   // Bereich der Zufalls Zahl
        int Versuche =0;            // Anzahl der bisherigen versuche
        int Punkte = 0;             // Punktestand
    
        // Zufallszahl ermitteln
        Zufallszahl = (rand()%Bereich)+1;
    
        // Bereich ausgeben, in dem erraten wird
    
        cout << "Die gesuchte Zahl liegt zwischen 1 und ";
        cout << Bereich << endl;
    
        // Solange raten bis die zahl gefunden wurde
        while (GerateneZahl != Zufallszahl)
        {
            cout << "Dein Tipp: ";
            cin >> GerateneZahl;
    
            Versuche++;
    
            // Zahl hat nicht gestimmt, also hinweis ausgeben
            if (GerateneZahl < Zufallszahl)
            cout << "Die gesuchte Zahl ist groesser" << endl;
            if (GerateneZahl > Zufallszahl)
            cout << "Die gesuchte Zahl ist kleiner" << endl;
    
        }
        // Die zahl wurde eraten!
        cout << "\nGeschafft! " << endl;
        cout << "Du hast die Zahl nach "<< Versuche;
        cout << " Versuchen erraten!\n\n";
    
        // Punkte berechnen
        // Desto weniger versuche und je höher das level
        // umso mehr Punkte bekommt man
        //
        Punkte = Bereich - Versuche +1;
        Punkte *= Level;
    
        // Wenn mehr versuche benötigt wurden, als es Zahlen gibt,
        // Kann das ergebnis negativ sein.
        //
        if (Punkte < 0)
            Punkte = 0;
    
        // Punkte ausgeben
        cout << "Punkte : " << Punkte  << endl;
    
        // Punkte zurück geben
        return Punkte;
    } // Spielen
    
    // TesteHighscore
    //
    // Aufgabe: Prüfen ob der Hioghscroe geknackt wurde
    //
    int TesteHighscore( int Punkte, int Highscore)
    {
        // Prüfen ob der highsore geknackt wurde
        if (Punkte > Highscore)
        {
            cout << "Glueckwunsch. Neuer Highscore!\n\n";
            Highscore = Punkte;
        }
        else
        {
            cout << "Leider kein neuer Highscore\n\n";
        }
    
        //Highscore zurückgeben
        return Highscore;
    }//TesteHighscore
    


  • Sebbo schrieb:

    habe das srand auf NULL gesetzt. Dabei is mir aufgefallen das es auch ohne das includieren der <ctime> funktioniert.

    Verbesserungsvorschlag:
    Includiere ctime. Wenn irgendjemand anderes (windows.h) für dich ctime oder time.h inkludierst, hast Du allerhöchstens Glück. Ist aber keinerlei Beleg für "es auch ohne das includieren der <ctime> funktioniert." 😉

    EDIT: Weiteres
    - Du könntest auf toupper(Auswahl) (aus <cctype>) switchen, dann bräuchtest Du nur die Großbuchstaben prüfen
    - Die Klammern um die chars in den case-Labels ist unnötig (sieht komisch aus)
    - dito für die Schleife - while (toupper(Auswahl) != 'B')



  • ok cool danke für deine verebsserungs vorschläge.

    Das die klammern für die chars unötig sidn erklärt Heiko Kalista in seinem Buch, gibt aber den rat es zwecks lesbarkeit zu machen.

    Würde da gern wissen ob das sich nun echt anzugewöhnen lohnt oder nicht?

    Du könntest auf toupper(Auswahl) (aus <cctype>) switchen, dann bräuchtest Du nur die Großbuchstaben prüfen

    mit meinem derzeitigen wissen kann ich das leider noch nicht umsetzen werde mir das aber im hinterkopf bewahren und in angriff nehmen bzw zumindest mal ausprobieren wenn ich soweit bin.



  • Sebbo schrieb:

    Das die klammern für die chars unötig sidn erklärt Heiko Kalista in seinem Buch, gibt aber den rat es zwecks lesbarkeit zu machen.

    Würde da gern wissen ob das sich nun echt anzugewöhnen lohnt oder nicht?

    Ich kenne das Buch nicht, stelle nur selbst fest dass ich diese Schreibweise noch in keinem Programm gesehen habe. Deshalb sagte ich "sieht komisch aus".

    Deine Entscheidung, die case-Labels mit oder ohne Klammern zu notieren, ist ein Schritt dahin Dir Deinen eigenen Stil anzueignen - mach was Du am lesbarsten findest 😉



  • So da bin ich wieder. neuer tag neues problem *g*

    Bei dem Zahlenraten hat mich noch bischen gestört das der bildschirm bzw die console so unordentlich ausah usw. hab dann also nach ner lösung gesucht wie ich das bischen ordentlicher hinbekomme und kam dann auf system("CLS")

    desweiteren störte mich das z.b bei der Levelwahl funktion das programm in eine endlosschleife rutscht wenn man ein buchstabe eingibt. das wollte ich mit einer if abfrage abfangen. wenn ein buchstabe eingegeben wurde sollte die funktion den alten Level wert einfach mit return zurück geben so das die funktion abgebrochen wird und der user eine entsprechende meldung bekommt.

    So nun ist es aber so das es hier zu einem erneuten bug kommt den ich mir nicht erklären kann und ich unbedingt hilfe brauche. allein schon um das zu verstehn!

    ich poste hier nochmal den gesamten überarbeiteten Code

    ------
    Der BUG: Wenn man sich ein Level wählt und statt ner zahl ein buchstabe tippt rutscht das programm in eine art endlosschleife.
    ------

    // Autor: Sebbo
    // Datum: 6.4.07
    // Title: Zahlenraten
    // version: 1.0
    
    #include <iostream>
    #include <windows.h>
    #include <ctime>
    
    using namespace std;
    
    #pragma comment (lib, "winmm.lib")
    
    // Funktionsprototypen
    //
    int Spielen (int Level);
    int WaehleLevel (int Level);
    int TesteHighscore (int Punkte, int Highscore);
    void ZeigeInfos();
    
    // Hauptprogramm
    //
    int main()
    {
        // Variablen
        //
        char Auswahl;           // Gewählter Menüpunkt
        int Level = 5;          // Aktueller Level
        int Highscore = 100;    // Aktueller Highscore
    
        // Zufallszahlengenerator initialisieren
        //srand (timeGetTime());
        srand(time(NULL));
        //Verarbeitung des Menüs
        do
        {
            system("CLS");
            // Menü ausgeben
            //
            cout << "Zahlenraten - Menue " << endl;
            cout << "--------------------" << endl;
            cout << "(N)eues spiel starten" << endl;
            cout << "(L)evel waehlen" << endl;
            cout << "(H)ighscore anzeigen" << endl;
            cout << "(I)nfo" << endl;
            cout << "(B)eenden\n\n";
    
            // Eingabe abfragen
            cout << "Auswahl: ";
            cin >> Auswahl;
    
            // je nach eingabe verzweigen
            switch (Auswahl)
            {
                //Neues Spiel Starten
                case ('n'):
                case ('N'):
                {
                    // Spielen
                    system("CLS");
                    int Punkte;
                    Punkte = Spielen (Level);
    
                    Highscore = TesteHighscore (Punkte,Highscore);
                    system("PAUSE");
                }break;
    
                //Level Wählen?
    
                case ('l'):
                case ('L'):
                {
                    system("CLS");
                    Level = WaehleLevel (Level);
                    //system("PAUSE");
                }break;
    
                //Highscore anzeigen?
                case ('h'):
                case ('H'):
                {
                    system("CLS");
                    cout << "### Highscore ###\n";
                    cout << "Der Aktuelle Highscore liegt bei: ";
                    cout << Highscore << " Punkte \n\n";
                    system("PAUSE");
                }break;
    
                //Informationen anzeigen
                case ('i'):
                case ('I'):
                {
                    system("CLS");
                    ZeigeInfos ();
                    system("PAUSE");
                }break;
    
                // Spiel beenden?
                case ('b'):
                case ('B'):
                {
                    system("CLS");
                    cout << "### Spiel Beenden ###\n\n";
                    cout << "Danke fuers Spielen!\n";
                    cout << "Spiel beendet." << endl;
    
                }break;
    
                // Falsche eingabe ?
                default:
                {
                    cout << "Falsche Eingabe!\n\n";
    
                }
            }
        }while (Auswahl != 'b' && Auswahl != 'B'); // Spiel beenden?
    
        cout << "Bis zum naechsten mal" << endl;
    
        return 0;
    } // main
    
    //Zeige Infos
    //
    // Aufgabe: Informationenj zum spiel zeigen
    //
    void ZeigeInfos ()
    {
        cout << "### Informationen ###\n";
        cout << "Zahlenraten V1.0" << endl;
        cout << "Uebungsspiel zur C++ Programmierung" << endl << endl;
    } // Zeige infos
    
    // Waehle level
    //
    // Aufgabe: Neuen Level waehlen
    //
    int WaehleLevel (int Level)
    {
        int NeuerLevel;
    
        do
        {
            // Neuen Level Waehlen
            cout << "### Levelauswahl ###\n";
            cout << "Waehlen sie einen Level (1 bis 10)\n\n";
            cout << "Aktueller Level " << Level << endl;
            cout << "Neuer Level: ";
            cin >> NeuerLevel;
    
            // Ungueltige eingabe
            if (NeuerLevel <1 || NeuerLevel >10)
            {
                // Fehlermeldung
                cout << "Ungueltige Eingabe. 1-10" << endl;
            }
            if(NeuerLevel != 1 && NeuerLevel != 2 &&
               NeuerLevel != 3 && NeuerLevel != 4 &&
               NeuerLevel != 5 && NeuerLevel != 6 &&
               NeuerLevel != 7 && NeuerLevel != 8 &&
               NeuerLevel != 9 && NeuerLevel != 10)
            {
                // Fehlermeldung
                // Bei ungueltiger eingabe durch buchstaben z.b soll der Level
                // Unverändert wieder zurück gegeben werden
                cout << "Level nicht geaendert" << endl;
                NeuerLevel = Level;
                return NeuerLevel;
            }
    
            cout << endl << endl;
        }while (NeuerLevel < 1 || NeuerLevel > 10);
    
        // Gewählten Level zurück geben
        return NeuerLevel;
    } // Waehle Level
    
    // Spielen
    //
    // Aufgabe Das eigendliche Spiel
    //
    int Spielen (int Level)
    {
        int Zufallszahl;            // Zufallszahl die erraten werden muss
        int GerateneZahl = 0;       // Zahl die der spieler eingibt
        int Bereich = Level * 10;   // Bereich der Zufalls Zahl
        int Versuche =0;            // Anzahl der bisherigen versuche
        int Punkte = 0;             // Punktestand
    
        // Zufallszahl ermitteln
        Zufallszahl = (rand()%Bereich)+1;
    
        // Bereich ausgeben, in dem erraten wird
    
        cout << "### Neues Spiel begonnen ###\n\n";
        cout << "Die gesuchte Zahl liegt zwischen 1 und ";
        cout << Bereich << endl;
    
        // Solange raten bis die zahl gefunden wurde
        while (GerateneZahl != Zufallszahl)
        {
            cout << "Dein Tipp: ";
            cin >> GerateneZahl;
    
            Versuche++;
    
            // Zahl hat nicht gestimmt, also hinweis ausgeben
            if (GerateneZahl < Zufallszahl)
            cout << "Die gesuchte Zahl ist groesser" << endl;
            if (GerateneZahl > Zufallszahl)
            cout << "Die gesuchte Zahl ist kleiner" << endl;
    
        }
        // Die zahl wurde eraten!
        cout << "\nGeschafft! \a" << endl;
        cout << "Du hast die Zahl nach "<< Versuche;
        cout << " Versuchen erraten!\n\n";
    
        // Punkte berechnen
        // Desto weniger versuche und je höher das level
        // umso mehr Punkte bekommt man
        //
        Punkte = Bereich - Versuche +1;
        Punkte *= Level;
    
        // Wenn mehr versuche benötigt wurden, als es Zahlen gibt,
        // Kann das ergebnis negativ sein.
        //
        if (Punkte < 0)
            Punkte = 0;
    
        // Punkte ausgeben
        cout << "Punkte : " << Punkte  << endl;
    
        // Punkte zurück geben
        return Punkte;
    } // Spielen
    
    // TesteHighscore
    //
    // Aufgabe: Prüfen ob der Hioghscroe geknackt wurde
    //
    int TesteHighscore( int Punkte, int Highscore)
    {
        // Prüfen ob der highsore geknackt wurde
        if (Punkte > Highscore)
        {
            cout << "Glueckwunsch. Neuer Highscore!\n\n";
            Highscore = Punkte;
        }
        else
        {
            cout << "Leider kein neuer Highscore\n\n";
        }
    
        //Highscore zurückgeben
        return Highscore;
    }//TesteHighscore
    


  • Hey lasst mich nich hängen ich verzweifel. kann sich den code bitte jemand mal ansehn und mir erklärung geben wo der fehler liegt? Ich hab probiert und probiert ich werd aus der sache nicht schlau 😞

    Ich glaube das die eingaben von cin irgendwie weiterhin bestehen und das deswegen diese art von endlosschleife auftritt.
    Frage mich dann aber warum das passiert da ich ja nach der If abfrage eingedlich genauso die funktion mit nem legalen wert verlasse wie am eigendlichen ende...

    bitte schaut sich das ma einer an



  • aus cin >> neuerlevel machste das:

    cin >> neuerlevel;
    while(cin.fail()) {
        cin.ignore(std::numeric_limits<int>::max)); // ohne meine tolle ide kann ich das net auswendig
        cin.clear();
        cout << "Du Depp, du musst eine Zahl eingeben! Nochmal: ";
        cin >> neuerlevel;
    }
    

    Kannst dir das ja in eine Funktion packen.



  • oah bombe !!! Ich danke dir ich hab da heute bestimmt 4 stunden rumgebastelt und den fehler gesucht und durch die ausgaben bin ich dann darauf gekommen das er die cin eingabe nich löscht.

    Habe dein codeteil angepasst und eingebaut, ergab aber leider ne menge fehler. eventuell hab ich die richtige header file nich eingebunden(Bin noch Noobie *g*)

    auf jedenfall hab ich jetzt ne lösung und zwar setz ich vor jede cin aufforderung ein cin.clear()

    ich weis nich ob das ne gute lösung is aber ich weis mir bisher nich weiter zu helfen.

    Nochwas: habe mir heute überlegt ob man nich den eingabe wert als String aufnimmt und den dann irgendwie umwandelt in ne Int. das müsste die sache ja auch einfacher machen oder ?



  • Sollte das eine Frage sein nach der Umwandlung von string nach int sieh dich mal in der FAQ um. "Einmal Zahl nach String und zurück" oder so ähnlich heiszt der Thread.


Anmelden zum Antworten