Seite 1 von 1

Karten per Drag&Drop einsortieren - Modellierung?

Verfasst: 19. November 2010 11:35
von lx2
Hi Forum,

ich hab die etwas komplexere Aufgabe bekommen, einen Korrekturmodus für Zufalls-Karten zu programmieren.

Man muss sich das so vorstellen: Der User bekommt eine zufällige Reiehnfolge von Karten gezeigt die er sich möglichst schnell einprägen soll. Danach erschein der hier vorgestellte Korrekturmodus in dem die Reihenfolge rekonstruiert werden soll - je schneller, desto mehr Punkte (am besten Ihr schaut euch erstmal das Attachment an).

Folgende Funktionen sollen implementiert werden:

- Karten können beliebig verschoben werden:
--Wenn sie schon in einer Lücke sind können Sie auch in eine andere Lücke verschoben werden
-- Karten können in die Ausgangsliste zurückgelegt werden

- Wird eine Karte über eine belegte Lücke gezogen erscheint ein "Rechts/Links-Overlay" (erkennbar im Attachment). Dropt man sie dann z.B. auf der rechten Hälfte (markiert mit "R"), wird die aktuelle Karte(also die die sich momentan in der Lücke befindent) eins nach links verschoben. Ist dieses Feld ebenfalls belegt, wird dies rekursiv fortgeführt bis maximal zum Anfang der "Lückenliste". Die erste Karte würde dann rausfallen d.h. zur Ausgangsliste zurückgelegt werden. Analog dazu der Drop auf der linken Kartenhälfte.

- ist man sich bei der Lücke unsicher, so sollte dies irgendwie Markierbar sein. Evtl per Leertaste. Die Toggelt dann ein rotes "?" das als Overlay über die zuletzt gedroppte Karte einblendet wird.

Nun meine Fragen hierzu , die eher architektonischer als syntaktischer Natur sind:

1. welche Klassen würdet Ihr verwenden
2. sollte man versuchen das ganze eher mit dem Graphics View Framework zu machen und einzelne Mauspositionen abfangen oder doch lieber jedes Objekt einzeln Modellieren da es ja auch Informationen in sich trägt
3. Ich hab mir mal BEIDE "Puzzle"-Beispiele von QT angeschaut:
http://doc.trolltech.com/4.7/draganddrop-puzzle.html
http://doc.trolltech.com/4.7/itemviews-puzzle.html

meint ihr man könnte diese Ansätze soweit umfunktionieren, dass die oben genannten Punkte mit einbaut werden?


Freue mich schon auf eure Resonanz!
Grüße aus München

Verfasst: 19. November 2010 21:22
von lx2
Hat keiner einen Vorschlag?
Wir doch sicherlich jemand mit "Drag&Drop-Erfahrung" geben... :wink:

Verfasst: 19. November 2010 21:44
von padreigh
mh, wo hast du die bilder her/ rechte daran? Ich suchte mal ein Bildersatz für Karten.

Verfasst: 19. November 2010 21:53
von lx2
von dem verlag der sie herstellt natürlich!
Wer aber ein bisschen Photoshop kann, macht sich sowas sowiso schnell selbst.

Aber das bringt mich leider hier nicht weiter und ist off-topic

Verfasst: 20. November 2010 00:47
von padreigh
die Relevanz ist dann wohl das du eine Copyrightverletzung begehst ... also Photoshoppe mal schön ;)

ohne Grafik:

Code: Alles auswählen

#include <QtCore/QCoreApplication>

#include <QtCore>

class Spielfeld {
public:
    Spielfeld()
    {
        init();
    }

    void place(quint8 card, qint8 field, bool left)
    {
        // wenn ausserhalb pack sie in die Hand
        if (field < 0 | field > 51  )
        {
            cardsInHand.insert(card); // unnötig ... aber auch egal
            return;
        }

        // karte noch in hand?
        if (! cardsInHand.contains(card))
        {
            // suche Karte
            for (int i=0; i < 52; ++i)
            {
                if (allFields[i] == card)
                {
                    // nimm sie weg
                    allFields[i]=-1;
                    // pack sie in die Hand
                    cardsInHand.insert(card);
                    break; // break for und unten weiter mit plazierung
                }
            }
        }

        if (allFields[field] == -1 )
        {
            // nimm karte aus der Hand
            cardsInHand.remove(card);
            // pack sie aufs feld
            allFields[field] = card;
        }
        else
        {
            // nimm die karte die da liegt
            qint8 oldCard = allFields[field];
            // pack sie ins in die Hand
            cardsInHand.insert(oldCard);
            // nimm karte aus der Hand
            cardsInHand.remove(card);
            // pack sie ins Feld
            allFields[field] = card;
            // abhängig von richtung: rekursiere
            if (left)
                place(oldCard,field-1, true);
            else
                place(oldCard,field+1, false);
        }
    }

    QString output()
    {
        QString all = "Spielfeld:\n\t";
        for(int i=0;i<52;++i)
        {
            all.append(QString::number(allFields[i])+"\t");
            if ((i+1)%13 == 0) all.append("\n\t");
        }
        all.chop(1);

        all.append("\nin der Hand:\n\t");

        QList<quint8> tmp = cardsInHand.toList(); // sorted

        bool col1=false,col2=false,col3=false;
        for(int i=0;i<tmp.size();++i)
        {            
            if (i>0)
            {
                int val = tmp[i-1];
                while (val != tmp[i]-1)
                {
                    all.append(QString(" \t"));
                    ++val;
                }
            }

            if (tmp[i]<10) all.append(" ");
            all.append(QString::number(tmp[i])+"\t");

            if (!col1 && tmp[i] >= 12) { col1=true; all.append("\n\t");}
            if (!col2 && tmp[i] >= 25) { col2=true; all.append("\n\t");}
            if (!col3 && tmp[i] >= 38) { col3=true; all.append("\n\t");}
        }
        if (!tmp.isEmpty())
            all.chop(1);

        all.append("\n");

        qDebug() << all;
        return all;
    }

private:
    void init()
    {
        cardsInHand.clear();
        for (quint8 i=0; i<52; ++i)
        {
            allFields[i]=-1;
            cardsInHand.insert(i);
        }
    }

    qint8 allFields[52];
    QSet<quint8> cardsInHand;

};




int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Spielfeld f;
    f.output();
    f.place(8,8,true);
    f.output();
    f.place(9,8,true);
    f.place(10,8,false);
    f.output();
    f.place(0,0,true);
    f.output();
    f.place(1,0,true);
    f.output();
}
da ist redundantes zeug drin, zB das nochmal reinstecken wenns übern rand geht ... platz für verbesserung ist da massig., es fehlt das triviale Karte aus Feld auf Hand nehmen, karten von feld zu feld legen sollte klappen.

Verfasst: 20. November 2010 15:53
von lx2
Hi , danke schonmal für den Code.

Würd mich nur interessieren was das mit meiner Frage zu tun hat.
Ich seh da weder Drag&Drop noch irgendwelche QT Klassen die mein Problem angehen. Nur irgendwelche qDebug-Ausgaben...

Interresant wäre höchstens wo dein "cardsInHand" herkommt.

=====

Für weitere Hilfe von Christian81, upsala, franzf, RHBaum oder AuE wäre ich sehr dankbar!

Verfasst: 20. November 2010 19:44
von padreigh
Abgesehen von der trivialen Karte aus dem Deck zurück in die Hand nehmen ist das die Spielmechanik. Lass die Klasse von QObject erben, gib ihr ein paar signale und slots und verknüpfe das mit einer Gui die in 2 QFrames je 4*13 QLabels (zB) hat (was dnd angeht guck mal lieber die Kühschrankmagneten an oder das hier: http://doc.trolltech.com/4.7/draganddro ... icons.html).

Verfasst: 20. November 2010 23:58
von franzf
padreigh hat geschrieben:Ich suchte mal ein Bildersatz für Karten.
Lad dir den neuesten kdegames (kde.org) und geh nach libkdegames/carddecks. Oder zieh es direkt über webdvn.kde.org, wenn du nicht die ganzen kdegames ziehen willst.

Tip für Spielkarten

Verfasst: 21. November 2010 21:00
von padreigh
Guter Tipp, danke. Das ist zZ auf Eis da ich auf Zahlen/Klein/Großbuchstabenmemory umgestiegen bin. Nächste WE kommt dann vielleicht die die Spielidee von "Das Geisterschloss" da mit rein - mein Tochter (5J) ist Gametesterin nachdem die mich immer beim Memory abzockt.