For-Schleife soll warten



  • 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.



  • volkard schrieb:

    Gerade hab ich dieses Werk gebaut, und das hat mich an diesen Thread erinnert.

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    #include <cmath>
    
    using namespace std;
    
    int main()
    {
        srand(time(0));
        int punkte=0;
        while(punkte<100){
            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;
            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;
    }
    

    Die beiden continues finde ich schön.

    Auch nur, weil das ganze ein Minispiel ist, das total in sich verstrickt ist und Modularisierung sich nicht lohnt.



  • Ich hab mir sagen lassen, dass sich auch große Projekte in viele kleine Mini-"Projekte" zerlegen lassen, bei denen sich Modularisierung nicht lohnt...



  • mmmmmmmmmmmmmm schrieb:

    Auch nur, weil das ganze ein Minispiel ist, das total in sich verstrickt ist und Modularisierung sich nicht lohnt.

    Ja, absolut.
    Wäre das Programm größer, oder sollte es länger leben oder mal ausgebaut werden oder sowas, dann wäre die frage() längst ausgelagert. In ernsthaften Projekten würde ich mehr auf funktionale Zerlegung achten:

    #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()
    {
    nochmal:
        int basis=rand()%10;
        int exponent=rand()%10;
        if(basis==0 && exponent==0)
            goto nochmal;
        int potenz=pow(basis,exponent);
        if(potenz>500)
            goto nochmal;
        cout<<basis<<'^'<<exponent<<'=';
        int tip;
        cin>>tip;
        return tip==potenz;
    }
    //something went wrong
    


  • 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.


Anmelden zum Antworten