For-Schleife soll warten



  • In einem Anflug von Genialität konnte ich sogar noch die beiden gotos wegmachen.

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    #include <cmath>
    
    using namespace std;
    
    bool frage();
    
    int main()
    {
        srand(time(0));
        int punkte=0;
        while(punkte<100)
        {
            if(frage())
            {
                cout<<"richtig!\n";
                ++punkte;
            }
            else
            {
                cout<<"falsch!\n";
                punkte/=2;
            }
            cout<<"Punkte: "<<punkte<<'\n';
            cout<<"\n\n\n\n\n";
        }
        return 0;
    }
    
    bool frage()
    {
        for(;;)
        {
            int basis=rand()%10;
            int exponent=rand()%10;
            if(basis==0 && exponent==0)
                continue;
            int potenz=pow(basis,exponent);
            if(potenz>500)
                continue;
            cout<<basis<<'^'<<exponent<<'=';
            int tip;
            cin>>tip;
            return tip==potenz;
        }
    }
    

    Aber mir scheint, ich bin ein continue-Junkie. Ist das nicht traurig?



  • Wenn es sich lohnen würde, würde man eine Klasse für das Spielchen machen und dann z.B. sowas:

    bool isValidData()
    	{
    		if(basis==0 && exponent==0)
    			return false;
    
    		potenz=pow(basis,exponent);
    		return potenz>500;
    	}
    

    Du würdest dann wahrscheinlich so weiter machen

    if(!isValidData())
        continue;
    auswerten(frage());
    

    Ich wahrscheinlich so

    if(isValidData())
    {
        auswerten(frage());
    }
    

    😃



  • mmmmmmmmmmmmmm schrieb:

    Wenn es sich lohnen würde, würde man eine Klasse für das Spielchen machen und dann z.B. sowas:

    Nein, das würdest Du (hoffentlich!) auch nicht.

    bool isValidData()//ACHTUNG! Diese Methode tut NICHT nur prüfen,
    //sondern sie berechnet erstmalig das Attribut potenz. Sie muß daher 
    //nach createData() aber vor jeder weiteren Verwendung aufgerufen werden. 
    	{
    		if(basis==0 && exponent==0)
    			return false;
    		potenz=pow(basis,exponent);
    		return potenz>500;
    	}
    

    Das wäre zu bereinigen, indem man potenz schon in createData() und vor allen Prüfungen berechnet, aber das wollte ich ja gerade nicht.



  • Wo ist meine Antwort hin?



  • Mis2com.. schrieb:

    Wo ist meine Antwort hin?

    Von mir aus Versehen gelöscht.



  • Michael E. schrieb:

    padreigh schrieb:

    müsste das nicht if(basis==0 || exponent==0) heissen?

    Warum? Er nimmt nur den nicht einheitlich definierten Fall 0^0 raus.

    Das erste finde ich überflüssig - ich würde eher beide rand() 's anpassen auf rand()%10+1; .

    Geht nicht, wenn lediglich 0^0 verhindert werden soll.

    Schon klar, aber wie witzlos ist "Rate irgendwas hoch 0" ... daher würd ich gleich beide wechmachen 😉



  • padreigh schrieb:

    Schon klar, aber wie witzlos ist "Rate irgendwas hoch 0" ... daher würd ich gleich beide wechmachen 😉

    Wie witzlos ist x^1? Wie witzlos ist 1^x? Die Funktionalität nach eigenem Gusto veränder, gilt nicht 😉



  • padreigh schrieb:

    Schon klar, aber wie witzlos ist "Rate irgendwas hoch 0" ... daher würd ich gleich beide wechmachen 😉

    Nee. Die Auswahl der Fragen ist gut so.



  • Ok, dann halt so 😛 [ins Lager der continue -Vermeider wechsel]

    bool frage()
    {
        int basis, exponent, potenz;
        do
        {
            basis=rand()%10;
            exponent=rand()%10;
        } while ( (basis==0 && exponent==0) || (potenz=pow(basis,exponent)) > 500 );
    
        cout<<basis<<'^'<<exponent<<'=';
        int tip;
        cin>>tip;
        return tip==potenz;
    }
    


  • padreigh schrieb:

    Ok, dann halt so 😛 [ins Lager der continue -Vermeider wechsel]

    bool frage()
    {
        int basis, exponent, potenz;
        do
        {
            basis=rand()%10;
            exponent=rand()%10;
        } while ( (basis==0 && exponent==0) || (potenz=pow(basis,exponent)) > 500 );
    
        cout<<basis<<'^'<<exponent<<'=';
        int tip;
        cin>>tip;
        return tip==potenz;
    }
    

    Das werte ich als Argument für continue .

    Und wenn wir schonmal Aufeinanderfolgende Sachen nicht untereinander schreiben wollen, hier eine weitere Stufe der Uglifikation.

    bool frage()
    {
        int basis, exponent, potenz;
        while ( ((basis=rand()%10)==0 && (exponent=rand()%10)==0) || (potenz=pow(basis,exponent)) > 500 );
    
        cout<<basis<<'^'<<exponent<<'=';
        int tip;
        cin>>tip;
        return tip==potenz;
    }
    

    oder

    bool frage()
    {
        int basis, exponent, potenz;
        if ( ((basis=rand()%10)==0 && (exponent=rand()%10)==0) || (potenz=pow(basis,exponent)) > 500 ) return frage();
    
        cout<<basis<<'^'<<exponent<<'=';
        int tip;
        cin>>tip;
        return tip==potenz;
    }
    


  • Wie ich geschrieben hatte, vor es gelöscht wurde, einfach if und einrücken, sieht genauso leserlich aus. continue um jeden Preis vermeiden ist genauso sinnvoll wie einrückungen vermeiden.



  • Du hast recht - deine sind uglier 😉 Mir pers. gefallen unnötig lange Blöcke nicht. Dein for (;;) { /* ... */ } enthält Zeug das IMMER ausgeführt wird - warum nuss das dann mit in den Block? Dann lieber eine kurze Schleife mit dem nötigstens.

    bool frage()
    {
        int basis;
        int exponent;
        int potenz = 501;
    
        do
        {
            basis=rand()%10;
            exponent=rand()%10;
            if( (basis!=0 && exponent!=0)
                potenz=pow(basis,exponent);
        } 
        while (potenz > 500);
    
        cout<<basis<<'^'<<exponent<<'=';
        int tip;
        cin>>tip;
        return tip==potenz;   
    }
    


  • padreigh schrieb:

    int potenz = 501;
    

    Uih, der Trick eröffnet sich aber spät.

    Solche Tricks sind doch nichts wert. Warum nicht einfach hinschreiben, was man macht?

    Vielleicht hast Du eine Continuephobie, weil Du es nicht richtig liest. Es heißt nicht "Nochmal von vorn versuchen", sondern es heißt "Diesen Schleifendurchlauf abbrechen."



  • padreigh schrieb:

    Mir pers. gefallen unnötig lange Blöcke nicht. Dein for (;;) { /* ... */ } enthält Zeug das IMMER ausgeführt wird - warum nuss das dann mit in den Block? Dann lieber eine kurze Schleife mit dem nötigstens.

    Das AUslagern der frage() war offensichtlich ein Fehler. Bleiben wir bei der Ur-Version.



  • Wie gesagt.

    int main()
    {
        srand(time(0));
        int punkte=0;
        while(punkte<100){
            int basis=rand()%10;
            int exponent=rand()%10;
    		if(basis!=0 || exponent!=0) {
    			int potenz=pow(basis,exponent);
    			if(potenz<=500) {
    				cout<<basis<<'^'<<exponent<<'=';
    				int tip;
    				cin>>tip;
    				if(tip==potenz){
    					cout<<"richtig!\n";
    					++punkte;
    				}
    				else{
    					cout<<"falsch!\n";
    					punkte/=2;
    				}
    				cout<<"Punkte: "<<punkte<<'\n';
    				cout<<"\n\n\n\n\n";
    			}
    		}
        }
        cout<<"Gewonnen!\n";
        return 0;
    }
    


  • volkard schrieb:

    Solche Tricks sind doch nichts wert. Warum nicht einfach hinschreiben, was man macht?

    Hinschreiben, man würde für immer schleifen drehen oder die punkte-schleife für was anderes nehmen ist auch nicht hinschreiben was man macht.



  • Funktioniert aber immer noch, wenn ich alle Potenzen größer als 1000 ausschließen will :p

    Edit: Zu deinem Code: Pack das mal noch in ne Klasse in nen Namespace in nen Namespace...



  • Schwierigkeiten beim Refactoring weisen nicht auf guten Code hin.



  • Michael E. schrieb:

    Funktioniert aber immer noch, wenn ich alle Potenzen größer als 1000 ausschließen will :p

    😕

    Edit: Zu deinem Code: Pack das mal noch in ne Klasse in nen Namespace in nen Namespace...

    Rückst du die ein? Sieht doch dumm aus, wenn eine Funktion schon zweimal eingerückt ist.



  • Mis2com.. schrieb:

    Michael E. schrieb:

    Funktioniert aber immer noch, wenn ich alle Potenzen größer als 1000 ausschließen will :p

    😕

    Wenn du die Grenze 500 ändern willst, musst du das nun an zwei Stellen im Code tun.

    Edit: Zu deinem Code: Pack das mal noch in ne Klasse in nen Namespace in nen Namespace...

    Rückst du die ein? Sieht doch dumm aus, wenn eine Funktion schon zweimal eingerückt ist.

    ...


Anmelden zum Antworten