C++ Memory Game, Weird Problem



  • Hello guys,
    I'm trying to make a memory game GUI application in C++ for school. This is the code I have so far:

    Widget Header:

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QSignalMapper>
    #include <QPushButton>
    
    namespace Ui {
        class Widget;
    }
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit Widget(QWidget *parent = 0);
        ~Widget();
    
    private slots:
    
        void on_btnLogin_clicked();
    
        void on_btnOffline_clicked();
    
        void on_btnSingle_clicked();
    
        void on_btnMulti_clicked();
    
        void on_btn4x4_clicked();
    
        void on_btn6x4_clicked();
    
        void on_btn6x6_clicked();
    
        void myEventHandler(QString);
    
    private:
        Ui::Widget *ui;
        static const int BTNSIX=6;
        static const int BTNFOUR=4;
        QPushButton* FourFour[BTNFOUR][BTNFOUR]; //button arrays, lines + rows
        QPushButton* SixFour[BTNSIX][BTNFOUR];
        QPushButton* SixSix[BTNSIX][BTNSIX];
        QSignalMapper *mySignalMapper;
    };
    
    #endif // WIDGET_H
    

    Widget.cpp:

    #include "widget.h"
    #include "ui_widget.h"
    
    QString text;
    
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
        ui->stackedWidget->setCurrentWidget(ui->swLogin);
    
            mySignalMapper = new QSignalMapper(this); //creating a new signal mapper
    
                for (int x=0; x<BTNFOUR; x++) {  //creating the 4x4 field with 16 buttons
                for (int y=0; y<BTNFOUR; y++) {
                  FourFour[y][x] = new QPushButton(ui->swFourFour);
                  text = QString::number(x)+","+QString::number(y);
                  FourFour[y][x]->setText("I am Nr. ("+ text +")");
                  FourFour[y][x]->setGeometry(0+x*100,0+y*100,100,100);
                  connect(FourFour[y][x],SIGNAL(clicked()),mySignalMapper,SLOT(map()));
                  mySignalMapper->setMapping(FourFour[y][x],text);
                }
              }
    
                for (int x=0; x<BTNSIX; x++) { //creating the 6x4 field with 24 buttons
                for (int y=0; y<BTNFOUR; y++) {
                  SixFour[y][x] = new QPushButton(ui->swSixFour);
                  text = QString::number(x)+","+QString::number(y);
                  SixFour[y][x]->setText("I am Nr. ("+ text +")");
                  SixFour[y][x]->setGeometry(0+x*100,0+y*100,100,100);
                  connect(FourFour[y][x],SIGNAL(clicked()),mySignalMapper,SLOT(map()));
                  mySignalMapper->setMapping(FourFour[y][x],text);
                }
              }
    
                for (int x=0; x<BTNSIX; x++) { //creating the 6x6 field with 36 buttons
                  for (int y=0; y<BTNSIX; y++) {
                    SixSix[y][x] = new QPushButton(ui->swSixSix);
                    text = QString::number(x)+","+QString::number(y);
                    SixSix[y][x]->setText("I am Nr. ("+ text +")");
                    SixSix[y][x]->setGeometry(0+x*100,0+y*100,100,100);
                    connect(SixSix[y][x],SIGNAL(clicked()),mySignalMapper,SLOT(map()));
                    mySignalMapper->setMapping(SixSix[y][x],text);
                  }
                }                     
                connect(mySignalMapper, SIGNAL(mapped(QString)),this, SLOT(myEventHandler(QString)));
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::on_btnLogin_clicked()
    {
        ui->stackedWidget->setCurrentWidget(ui->swModus); //not important, its just for switching the current widget
    }
    
    void Widget::on_btnOffline_clicked()
    {
        ui->stackedWidget->setCurrentWidget(ui->swLevel);
    }
    
    void Widget::on_btnSingle_clicked()
    {
        ui->stackedWidget->setCurrentWidget(ui->swLevel);
    }
    
    void Widget::on_btnMulti_clicked()
    {
        ui->stackedWidget->setCurrentWidget(ui->swSixSix);
        QWidget::setGeometry(600,200,1200,600); // not  important, just changing the size of the widget
    }
    
    void Widget::on_btn4x4_clicked()
    {
    
        ui->stackedWidget->setCurrentWidget(ui->swFourFour);
        QWidget::setGeometry(400,200,800,400);
    
    }
    
    void Widget::on_btn6x4_clicked()
    {
        ui->stackedWidget->setCurrentWidget(ui->swSixFour);
        QWidget::setGeometry(400,200,1200,400);
    }
    
    void Widget::on_btn6x6_clicked()
    {
        ui->stackedWidget->setCurrentWidget(ui->swSixSix);
        QWidget::setGeometry(600,200,1200,600);
    }
    
    void Widget::meinEventHandler(QString signal)
    {
        QString signal2 = signal;         
        int x = signal.remove(1,2).toInt(); 
        int y = signal2.remove(0,2).toInt();
        FourFour[y][x]->setStyleSheet("background-color: rgb(255, 0, 0);");
        SixFour[y][x]->setStyleSheet("background-color: rgb(255, 0, 0);");
        SixSix[y][x]->setStyleSheet("background-color: rgb(255, 0, 0);");
    }
    

    As you might have noticed, it's not playable yet. First of all, I wanted to generate 3 different memory game fields 4x4, 6x4, 6x6 and generate dynamic buttons on them. This is already working. I have 3 different fields. One of them with 16 Buttons, the other one with 24 and the last one with 36 buttons. Now, what I'm trying to do is, letting them react on clicks and change their background colour to red (I'll add pictures later). The 4x4 field is working perfectly. Every button changes it's backgroundcolour to red once I click it. But the 6x4 field and the 6x6 field aren't working. The last 10 buttons of the 6x6 field arent working. The programm just crashes, without any error or something. It just says programm doesn't react anymore. And there are only 2 Buttons working on the 6x4 field, and I just cannot find the problem.

    Important lines explanation(last 6 lines):

    Cheers.

    PS: Sorry for this wall-of-text, lol.



  • ohman, ich hab nach dem schreiben erst gemerkt, dass das hier ein deutsches forum ist... ihr könnt mir auch ruhig auf deutsch helfen und schreiben! 😃



  • void Widget::meinEventHandler(QString signal)
    {
        QString signal2 = signal;        
        int x = signal.remove(1,2).toInt();
        int y = signal2.remove(0,2).toInt();
        FourFour[y][x]->setStyleSheet("background-color: rgb(255, 0, 0);");
        SixFour[y][x]->setStyleSheet("background-color: rgb(255, 0, 0);");
        SixSix[y][x]->setStyleSheet("background-color: rgb(255, 0, 0);");
    }
    



  • stimmt du hast recht, da geht es ja nur bis 4. Aber wie ist das lösbar? Soll ich fuer FourFour vielleicht andere int werte nehmen, z.B a,b anstatt x,y und diese auch neue signals zuweisen? oder würde das nicht funktionieren? 🙂



  • Du könntest auch abfragen, welches widget gerade in dem Moment aktiviert ist.



  • Wirf deine statischen Arrays raus und benutz´ stattdessen einen std::vector . Man kann MxN Arrays durch einen Vektor mit M*N Elementen abbilden, damit sparst du dir schon mal die ganzen Fallunterscheidungen, auf welchem Spielfeld gerade gespielt wird. Außerdem lassen sich problemlos neue Spielfeldgrößen hinzufügen, ohne dass der Code großartig geändert werden muss. Wenn du mal die Suchfunktion bemühst findest du hier im Forum etliche Beiträge zu 2D Arrays durch Vektoren.



  • otze schrieb:

    Du könntest auch abfragen, welches widget gerade in dem Moment aktiviert ist.

    weiß jemand zufaellig wie der befehl dafür lautet?
    if (swVierVier.??==??) {
    code code code
    }



  • if(ui->swVierVier->isActiveWindow()) {
                    for (int x=0; x<BTNVIER; x++) {
                    for (int y=0; y<BTNVIER; y++) {
                      VierVier[y][x] = new QPushButton(ui->swVierVier);
                      text = QString::number(x)+","+QString::number(y);
                      VierVier[y][x]->setText("Ich bin Nr. ("+ text +")");
                      VierVier[y][x]->setGeometry(0+x*100,0+y*100,100,100);
                      connect(VierVier[y][x],SIGNAL(clicked()),meinSignalMapper,SLOT(map()));
                      meinSignalMapper->setMapping(VierVier[y][x],text);
                    }
                  }
                }
    

    Wenn ich das so mache, erzeugt der die Buttons gar nicht mehr... 😞



  • Ich wiederhol mich da gerne, auch nachdrücklich:

    DocShoe schrieb:

    Wirf deine statischen Arrays raus und benutz´ stattdessen einen std::vector. Man kann MxN Arrays durch einen Vektor mit M*N Elementen abbilden, damit sparst du dir schon mal die ganzen Fallunterscheidungen, auf welchem Spielfeld gerade gespielt wird.



  • DocShoe schrieb:

    Ich wiederhol mich da gerne, auch nachdrücklich:

    DocShoe schrieb:

    Wirf deine statischen Arrays raus und benutz´ stattdessen einen std::vector. Man kann MxN Arrays durch einen Vektor mit M*N Elementen abbilden, damit sparst du dir schon mal die ganzen Fallunterscheidungen, auf welchem Spielfeld gerade gespielt wird.

    Nein, danke so möchte ich das nicht machen. Ich verstehe überhaupt nichts davon was du oben beschreibst. Ich bin erst im ersten Informatik Schuljahr und bin nicht wirklich gut. Ich würde gerne bei meinen Arrays bleiben und eine andere Lösung finden. Dazu kommt noch das wir Vektoren etc. noch nicht hatten und der Lehrer sich fragen würde, woher ich das kann. Es sollte so simpel wie möglich sein.


Anmelden zum Antworten