Optiemerungsprobleme bei langer If-Abfrage



  • Hallo Leute, ich baue gerade ein Kniffel-Spiel mit grafischer Oberfläche.
    Das Würfel-Fenster besteht aus 5 Würfeln die jeweils in einem Label angezeigt werden.
    Nun ist meine Frage, beim ersten Mal würfeln werden natürlich mit allen Würfeln gewürfelt. Um in der zweiten Runde die Würfel auszuwählen mit den nicht mehr gewürfelt werden soll, habe ich radio-Buttons neben die Labels(für die Würfel) gesetzt. Nun kommt mein Problem, wenn ich die radio-Buttons über eine if-Abfrage laufen lasse komme ich ja therotisch auf 5hoch5 Möglichkeiten die sich da für die 2 Runde ergeben. Hat jemand eine Idee wie ich das lösen kann ohne 3125 if-Abfragen zu schreiben?

    void NeuesFensterWuerfeln::on_pushButtonWuerfelnAusfuehren_clicked()
    {

    if (runde ==1)
    {
        wuerfelnneu();
        wuerfel1Ausgabe();
        wuerfel2Ausgabe();
        wuerfel3Ausgabe();
        wuerfel4Ausgabe();
        wuerfel5Ausgabe();
        QString info = "Bitte auswählen welche Wuerfeln stehen bleiben sollen!";
        QMessageBox::information(this,"Information", info);
        runde = 2;
    }
    
    
    //Runde 2
    
    if (runde == 2 && ui->radioButton->isChecked() && ui->radioButton_2->isChecked())
    {
        wuerfel3Ausgabe();
        wuerfel4Ausgabe();
        wuerfel5Ausgabe();
        return;
    
    }
    if (runde == 2 && ui->radioButton->isChecked() && ui->radioButton_3->isChecked())
    {
        wuerfel2Ausgabe();
        wuerfel4Ausgabe();
        wuerfel5Ausgabe();
        return;
    }
    if (runde == 2 && ui->radioButton->isChecked() && ui->radioButton_4->isChecked())
    {
        wuerfel2Ausgabe();
        wuerfel3Ausgabe();
        wuerfel5Ausgabe();
        return;
    }
    if (runde == 2 && ui->radioButton->isChecked() && ui->radioButton_5->isChecked())
    {
        wuerfel2Ausgabe();
        wuerfel3Ausgabe();
        wuerfel4Ausgabe();
        return;
    
    }
    if (runde ==2)
    {
        if (ui->radioButton->isChecked())
        {
            wuerfel2Ausgabe();
            wuerfel3Ausgabe();
            wuerfel4Ausgabe();
            wuerfel5Ausgabe();
        }
        else if (ui->radioButton_2->isChecked())
        {
            wuerfel1Ausgabe();
            wuerfel3Ausgabe();
            wuerfel4Ausgabe();
            wuerfel5Ausgabe();
        }
        else if (ui->radioButton_3->isChecked())
        {
            wuerfel1Ausgabe();
            wuerfel2Ausgabe();
            wuerfel4Ausgabe();
            wuerfel5Ausgabe();
        }
        else if (ui->radioButton_4->isChecked())
        {
            wuerfel1Ausgabe();
            wuerfel2Ausgabe();
            wuerfel3Ausgabe();
            wuerfel5Ausgabe();
        }
        else if (ui->radioButton_5->isChecked())
        {
            wuerfel1Ausgabe();
            wuerfel2Ausgabe();
            wuerfel4Ausgabe();
            wuerfel3Ausgabe();
        }
    
    }
    

    }


  • Mod

    Wenn du jemals Variablen mit Namen wie variable1, variable2, variable3, etc. hast, dann willst du stattdessen ein Array, Vector, oder ähnliches. Dann kann man Regeln darauf nämlich auch programmatisch abarbeiten. Gleiches gilt für gleichartige Funktionen funktion1, funktion2, funktion3, etc, das ist in Wirklichkeit eine Funktion mit einer Zahl als Parameter.

    Dann wird das insgesamt zu so etwas wie

    for (int i =0; i < 5; ++i)
    {
      if (not ui->radioButton[i]->isChecked())
        wuerfelAusgabe(i);
    }
    

    (und sogar völlig unabhängig davon, welche Runde gerade ist)



  • Ich denke bei so was an eine Klasse "Wuerfel" mit dem aktuellen Wert (von 1-6) und ob dieser noch variabel ist, also noch mal geändert werden kann; z.B. Attribute "wert" und "istVariabel"
    Dann eine Methode, die in Abhängigkeit von "istVariabel" den "wert" durch eine Zufallsfunktion neu setzt; z.B. "wuerfel()".

    Jetzt fehlt noch ein Container, der die 5 Würfel-Instanzen beinhaltet.

    Um neu zu würfeln werden nur die Würfel berücksichtigt (iterieren durch den Container mit den Würfeln), die das Attribut "istVariabel" auf false gesetzt haben, oder die Methode "wuerfel()" macht das und wird grundsätzlich aufgerufen.

    Deine Kennzeichnung durch die Radiobuttons setzen das Attribut "istVariabel" und werten es für die Anzeige aus.

    Na ja, oder so ähnlich 😉



  • @SeppJ
    An sowas habe ich auch schon gedacht... Auch auf die Gefahr hin mich hier jetzt als Volldepp zu entlarven, weiß ich gerade wie ich ein Array aus radioButtons bauen kann?



  • @chrisLA86

    Bei Radiobuttons kann man nur Einen aus Mehreren auswählen (du kannst am Radio nur einen Sender mit den Stationstasten auswählen)

    Du meinst Checkboxen.
    Und denen kannst du auch Elemente von Arrays zuordnen



  • @chrisLA86:

    #include <array> // ganz oben einfügen
    
    // Namen der Array-Elemente entsprechend anpassen
    std::array<QRadioButton*, 5> radioButtons = { radioButton1, radioButton2, radioButton3, radioButton4, radioButton5 };
    
    // bzw. sinnvoller, wie DirkB geschrieben
    std::array<QCheckBox*, 5> checkBoxes = { checkBox1, checkBox2, checkBox3, checkBox4, checkBox5 };
    

    s.a. std::array



  • @SeppJ sagte in Optiemerungsprobleme bei langer If-Abfrage:

    for (int i =0; i < 5; ++i)
    {
      if (not ui->radioButton[i]->isChecked())
      ...
    

    Tja, mir kam auch gerade in den Sinn: Wenn man mit einer "If-Abfrage" nicht mehr weiterkommt, dann hilft eine "If-Schleife" ... SCNR 😁





  • @Fragender sagte in Optiemerungsprobleme bei langer If-Abfrage:

    http://if-schleife.de/ 🙃

    Doch, das was @SeppJ da geschrieben hat, könnte man durchaus so nennen 😉



  • Ich habe jetzt mal gebaut was funktioniert. Ich bin immer noch ein zeimlicher Neuling was Programmierung angeht und deshalb bitte ich euch einmal Stellung zu nehmen zu meinem Code. Was haltet ihr davon?

    void NeuesFensterWuerfeln::on_pushButtonWuerfelnAusfuehren_clicked()
    {
    NeuesFensterWuerfeln *obj = this;

    if (runde ==1)
    {
        for (int i= 0;i<5;i++)
        {
            (obj->*wuerfelAusgeben[i])();
        }
        QString info = "Bitte auswählen mit welchen Wuerfeln neu gewuerfelt werden soll!";
        QMessageBox::information(this,"Information", info);
        runde = 2;
        return;
    }
    if (runde == 2)
    {
        for (int i = 0; i<5;i++)
        {
            if (radioButtons[i]->isChecked())
            {
                (obj->*wuerfelAusgeben[i])();
            }
        }
    }
    

    }



  • @chrisLA86

    Da fehlt ein bisschen Information 😉
    Als erstes lässt sich das Konstrukt NeuesFensterWuerfeln *obj = this wegoptimieren, dann kannst du direkt mit thisarbeiten. Da du dich in einer Memberfunktion der Klasse NeuesFensterWuerfeln befindest, kann du das dann auch noch wegoptimieren. Aus (obj->*wuerfelAusgeben[i])(); wird damit (*wuerfelAusgeben[i])(); Und da schrillen Alarmglocken, aber um mehr zu sagen müsste man wissen, was wuerfelAusgeben ist.



  • wuerfelAusgeben ist mein Vector in dem ich meine Methoden zur visuellen Ausgabe des Würfels in einem Label gespeichert habe, um sie dann später über die Schleife wieder abrufen zu können.

    QVector<void(NeuesFensterWuerfeln::*)()>wuerfelAusgeben;

    NeuesFensterWuerfeln::NeuesFensterWuerfeln(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::NeuesFensterWuerfeln)
    {
    ui->setupUi(this);
    srand(time(0));

    QRadioButton * ersterRadioButton = new QRadioButton(this);
    ersterRadioButton->setGeometry(150,50,100,100);
    ersterRadioButton->setText("Bitte anklicken falls Würfel stehen bleiben soll");
    ersterRadioButton->setAutoExclusive(false);
    
    QRadioButton * zweiterRadioButton = new QRadioButton(this);
    zweiterRadioButton->setGeometry(150,150,100,100);
    zweiterRadioButton->setText("Bitte anklicken falls Würfel stehen bleiben soll");
    zweiterRadioButton->setAutoExclusive(false);
    
    QRadioButton * dritterRadioButton = new QRadioButton(this);
    dritterRadioButton->setGeometry(150,250,100,100);
    dritterRadioButton->setText("Bitte anklicken falls Würfel stehen bleiben soll");
    dritterRadioButton->setAutoExclusive(false);
    
    QRadioButton * vierterRadioButton = new QRadioButton(this);
    vierterRadioButton->setGeometry(150,350,100,100);
    vierterRadioButton->setText("Bitte anklicken falls Würfel stehen bleiben soll");
    vierterRadioButton->setAutoExclusive(false);
    
    QRadioButton * fuenfterRadioButton = new QRadioButton(this);
    fuenfterRadioButton->setGeometry(150,450,100,100);
    fuenfterRadioButton->setText("Bitte anklicken falls Würfel stehen bleiben soll");
    fuenfterRadioButton->setAutoExclusive(false);
    
    //radioButton in den Vector übergeben
    radioButtons.push_back(ersterRadioButton);
    radioButtons.push_back(zweiterRadioButton);
    radioButtons.push_back(dritterRadioButton);
    radioButtons.push_back(vierterRadioButton);
    radioButtons.push_back(fuenfterRadioButton);
    
    wuerfelAusgeben.push_back(&NeuesFensterWuerfeln::wuerfel1Ausgabe);
    wuerfelAusgeben.push_back(&NeuesFensterWuerfeln::wuerfel2Ausgabe);
    wuerfelAusgeben.push_back(&NeuesFensterWuerfeln::wuerfel3Ausgabe);
    wuerfelAusgeben.push_back(&NeuesFensterWuerfeln::wuerfel4Ausgabe);
    wuerfelAusgeben.push_back(&NeuesFensterWuerfeln::wuerfel5Ausgabe);
    

    }



  • @DocShoe
    Sorry das oben stehende wollte ich eig. an dich richten hatte das @ setzen vergessen



  • Ah, ok. Ungewöhnlich.
    Jetzt fehlt nur noch der Code von wuerfel1Ausgabe. Ohne den gesehen zu haben vermute ich mal, dass wuerfel1Ausgabe bis wuerfel5Ausgabe prinzipiell das Gleiche tun und nur von anderen Objekten abhängen.



  • Du kannst das Erstellen der 5 QRadioButton gleich in einer Schleife durchführen und sie in den vector stecken (die y-Position kannst du ja einfach berechnen).


Anmelden zum Antworten