Memory-Spiel mit Schummelfunktion



  • Hallo, ich programmiere gerade ein Memory-Spiel mit einer Schummelfunktion, über einen Button, mit einen Timer. Es funktioniert auch soweit alles wunderbar. Nur nach endlichen Zügen und gefunden Pärchen, wie das immer wieder benutzen der Schummelfunktion. Gibt mir die Methode getUmdrehen() true zurück und läuft in den Else zweig wo der Timer gestoppt wird. Ich weiß echt nicht woran es liegen könnte, vielleicht habt Ihr ja eine Idee?

    Über hilfe wäre ich sehr dankbar.

    void Memoryspiel::ButtonfuerSchummeln()
    {
    int zeile = 0;
    int spalte = 0;
        if (zugErlaubt() == true)
        {
            if ((karten[(zeile * 7) + spalte]->getUmgedreht() == false))
            {
    
                 //QMessageBox::information(this, "Spielende", "false_1,");
                for (int zeile = 0; zeile < 7; zeile++)
                for (int spalte = 0; spalte < 6; spalte++)
                karten[(spalte * 7) + zeile]->umdrehen();
                timerschumeln->start(1000);
            }
            else
            {
    
               // QMessageBox::information(this, "Spielende", "true_1,");
                for (int zeile = 0; zeile < 7; zeile++)
                for (int spalte = 0; spalte < 6; spalte++)
                karten[(spalte * 7) + zeile]->umdrehen();
                timerschumeln->stop();
            }
    }
    


  • Du fragst ja immer die Karte mit dem Index 0 ab - was passiert denn in getUmgedreht(), wenn diese Karte schon entfernt wurde?
    Du könntest z.B. abfragen, ob der Timer noch nicht gestartet wurde.

    PS: Statt der Literale (z.B. 6, 7) solltest du dafür benannte Konstanten anlegen und verwenden.
    Und der Code bei den for-Schleifen sollte auch besser eingerückt sein (diese solltest du außerdem in eine eigene Funktion AlleKartenUmdrehen auslagern).



  • In getUmgedreht() wird mir nur der Status von umgedreht zugeliefert ob er true oder false ist.

    //den Status von umgedreht liefern
    bool Memorykarte::getUmgedreht()
    {
        return umgedreht;
    }
    
    

    und in umgedreht() wird die Karte gedreht

    void Memorykarte::umdrehen()
    {
        //ist die Karte schon umgedreht?
        //dann die Rückseite anzeigen, aber nur dann, wenn die Karte noch im Spiel ist
        if (nochImSpiel == true)
        {
    
            if (umgedreht == true)
            {
                setIcon(bildHinten);
                umgedreht = false;
            }
            //sonst die Vorderseite zeigen
            else
            {
                setIcon(bildVorne);
                umgedreht = true;
            }
        }
    }
    


  • Na also! Wenn die Karte aber nicht mehr im Spiel ist, dann wird weiterhin der umgedreht-Status zurückgeliefert (der ja true beim Entfernen der Karte ist).



  • Erstmals danke für den Bemühungen!!!!
    Ich verstehe deine Aussage noch nicht so richtig.
    Es wird so verhindert wenn die Karte rausgenommen wird das umdrehen() ausgerufen wird.

    //die Karte aus dem Spiel nehmen
    void Memorykarte::rausnehmen()
    {
        //die Grafik für aufgedeckt zeigen
        setIcon(QIcon(":/bilder/aufgedeckt.bmp"));
        nochImSpiel = false;
    }
    
    


  • Was ich jetzt rausgefunden habe ist, das Attribut umgedreht im Konstruktor der Klasse Memorykarte

    //der Konstruktor
    Memorykarte::Memorykarte(QString vorne, int id)
    {
        //die Vorderseite
        //der Dateiname des Bildes wird an den Konstruktor übergeben
        bildVorne = QIcon(vorne);
        //die Rückseite ist festgesetzt
        bildHinten = QIcon(":/bilder/back.bmp");
        //die Rückseite wird angezeigt
        setIcon(bildHinten);
        //die Karte ist nicht umgedreht
        umgedreht = false;
        //die Karte ist noch im Spiel
        nochImSpiel = true;
        //die Nummer setzen
        bildID = id;
    }
    
    

    Wechselt auf einmal von false aus true vermutlich durch den Schummelbutton dadurch wird mir über die Methode getUmdreht() nur noch true zurückgeben und er springt nur noch in den else zweig wo der Timer gestoppt wird.

    Was ich nicht verstehe der Schummelbutton ist in einer ganz anderen Klasse im Algorithmus des Spiels.



  • @M-W sagte in Memory-Spiel mit Schummelfunktion:

    void Memorykarte::rausnehmen()
    {
    //die Grafik für aufgedeckt zeigen
    setIcon(QIcon(":/bilder/aufgedeckt.bmp"));
    nochImSpiel = false;
    }

    Was @Th69 sagen wollte: was wenn die Karte zu dem Zeitpunkt wo sie rausgenommen wird umgedreht == true hat? Dann bleibt die weiterhin auf umgedreht == true. Und wenn das mit der ersten Karte passiert, dann bekommst du genau das Verhalten was du beschrieben hast.

    Jetzt könnte man auf die Idee kommen in rausnehmen einfach umgedreht == false zu setzen. Das würde zum Starten des Timers dann auch funktionieren - aber nicht zum Beenden. Weil du ja in umdrehen alle Karten überspringst die nicht mehr im Spiel sind.

    Also mach z.B. eine eigene Variable in der du dir merkst ob der Schummel-Timer gestartet wurde oder nicht.



  • @Th69 sagte in Memory-Spiel mit Schummelfunktion:

    Du könntest z.B. abfragen, ob der Timer noch nicht gestartet wurde.

    Dies ginge mit isActive().



  • Hallo, Ihr seit echt spitze danke für die Unterstützung.

    Ich versuche gerade das Umdrehen der Bilder nur durch den Timer zu steuern.
    Was dazu führt das er aus halb der Anfrage niemals true ist und die Bilder die ganze Zeit Toggeln.

    //if (karten[(zeile * i) + spalte]->getUmgedreht() == false) 
            if ( timerschumeln->isActive() == false)
            {
                  timerschumeln->start(1000);
                    for (int zeile = 0; zeile < i; zeile++)
                        for (int spalte = 0; spalte < y; spalte++)
                             karten[(spalte * i) + zeile]->umdrehen();
            }
            else 
            {
                   timerschumeln->stop();
                    for (int zeile = 0; zeile < i; zeile++)
                    for (int spalte = 0; spalte < y; spalte++)
                             karten[(spalte * i) + zeile]->umdrehen();
            }
    


  • Was machst du denn in der timeout-Slot-Funktion?
    Und möchtest du nicht eher einen singleShot-Timer (also der nur einmal die timeout-Slot-Funktion ausführt)?



  • Ich benutze den Timer als singelShot.

     timerschumeln = new QTimer(this);
        //er soll nur einmal ausgeführt werden
        timerschumeln->setSingleShot(true);
    
    

    Bei den Solt bin ich selbst ein bisschen unsicher, ich rufe immer wieder die Methode ButtonfuerSchummeln auf.

    void Memoryspiel::timerSchumeln()
    {
        //die Karten wieder umdrehen
        ButtonfuerSchummeln();
    }
    
    


  • War selber schon am überlegen die Logik für das hochzählen der Karten im Slot zu machen und das umdrehen im ButtonEvent.



  • Wie ich schon schrieb, mache dir eine Funktion AlleKartenUmdrehenund rufe diese im Timer auf (bisher aktivierst du ja immer wieder den Timer neu ;-).

    PS: Schummeln (mit 2 m).



  • Ich glaube ich habe es, erstmal soviel, werden noch ein bisschen Test, man soll ja nicht den Tag vor den Abend loben.

    Habe mir eine neue Member Variable in der Klasse erstellt mit 0 initialisiert.
    Im Buttonevent starte ich den timer und lasse die Member Variabel über isAktive() mit hochzählen.
    Im Slot machen ich alleKarten anzeigen und springe zurück zur Button Methode.

    Wenn Timer 3mal gestartet ist Stoppe ich in über die Member Variable.

    Bis jetzt läuft es sauber



  • Wofür soll denn das "3mal" sein?



  • Wenn ich nur bis 2 zähle werden mir die Bilder nur einmal umgedreht.
    So habe ich es jetzt.

    void Memoryspiel::ButtonfuerSchummeln()
    {
    if (zugErlaubt() == true)
       {
                 timerschummeln->start(1000);
             if (timerschummeln->isActive() == true){
                 i++;
                    }
                        if(i==3){
                            timerschummeln->stop();
                            i=0;
                          }
        }
    
    }
    


  • Schmerzen



  • Wieso Schmerzen?



  • Weil das weh tut was du postest.



  • Dann erkläre es mir doch richtig.


Anmelden zum Antworten