Memory-Spiel mit Schummelfunktion



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



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

    Wieso Schmerzen?

    1. du vergleichst ständig unnütz mit true. if (variable == true). Das returnt, richtig, einen bool, den du wieder vergleichen kannst. Also warum nicht if ((variable == true) == true)? Das if ist mit irgendwas, das nach bool konvertiert werden kann, zufrieden. Also einfach: if (variable).
    2. bitte immer ordentlich einrücken! (oder einfach clang-format oder andere Formatierungstools nutzen)
    3. wo kommen all deine Variablen her? Sowas wie i sollte immer eine LOKALE Variable mit KLEINEM Scope sein.
    4. was ist zugErlaubt() für eine Funktion? Warum kann sie funktionieren - d.h. woher weiß sie, um welchen Zug es sich handelt?

    Die letzten beiden Punkte sind wesentliche Probleme deines Codes. Wer ist hier eigentlich für was zuständig? Und woher kommt all der State?



  • Hallo,
    zugErlaubt() ist das man nur den Schummelbutton benutzen kann wenn der Spieler am Zug ist.

    bool Memoryspiel::zugErlaubt()
    {
        bool erlaubt = true;
        //zieht der Computer?
        if (spieler == 1)
            erlaubt = false;
        //sind schon zwei Karten umgedreht?
        if (umgedrehteKarten == 2)
            erlaubt = false;
        return erlaubt;
    }
    
    

    und soviel ich weiß gibt mir isActive() nur ein true oder flase zurück und deswegen vergleich ich hier.

    ``if (timerschummeln->isActive() == true)
    

    auf true



  • I habe ich deswegen nicht Lokal vereinbart, weil wenn mir der Timerslot die Methode wieder aufruft, wird I wieder auf Null gesetzt. Deswegen habe ich sie in der Klasse mit vereinbart. Weil mir nicht bewusst ist wie ich sonst den Timer wieder Stoppen sollen.

    Man sollte auch nicht vergessen jeder hat mal angefangen.



  • Puh, du scheinst die Logik des Codes überhaupt nicht zu verstehen.

    Also jetzt mal mein Vorschlag:

    void Memoryspiel::AlleKartenUmdrehen() // zusätzlich noch in der Klassendefinition hinzufügen!
    {
        const int MaxZeilen = 7; // dies kannst du auch global anlegen, falls noch öfter benötigt
        const int MaxSpalten = 6;  // dito
    
        for (int zeile = 0; zeile < MaxZeilen; zeile++)
            for (int spalte = 0; spalte < MaxSpalten; spalte++)
                karten[(spalte * MaxZeilen) + zeile]->umdrehen();
    }
    
    void Memoryspiel::ButtonfuerSchummeln()
    {
        if (zugErlaubt())
        {
             if (!timerschummeln->isActive()) // beachte: ! bedeutet 'nicht'
             {
                 AlleKartenUmdrehen();
                 timerschummeln->start(1000);
             }
             else
             {
                 timerschummeln->stop();
                 AlleKartenUmdrehen();
             }
        }
    }
    
    void Memoryspiel::timerSchummeln()
    {
        //die Karten wieder umdrehen
        AlleKartenUmdrehen(); // jetzt paßt auch der Kommentar ;-)
    }
    


  • @Th69
    Es ist tatsächlich so, das ich die Logik nicht richtig verstanden habe, ich habe Jahre lange eine Hausinterne Skripsprache programmiert, wo einen die Treiber-Entwickler sehr viel abgenommen haben und danach war es Teststand von Ni was nur noch ein zusammen Kopieren von Sequence ist. Und den richtigen haken setzen, an der richtigen Stelle.

    Ich danke Dir endlich habe ich die Logik vom Timer verstanden


Anmelden zum Antworten