Anfängerfrage zum Thema Daten sortieren und abrufen



  • Sorry, es ist sehr gut möglich, dass ich etwas falsch verstanden habe. Jedoch sind deine Beschreibungen auch nicht gerade leicht verständlich, du bringst einige Begriffe (z.B. "Klasse") ein wenig durcheinander.

    Soweit wie ich verstanden habe, wäre es möglicherweise einfacher mit Arrays.
    Poste doch einfach mal den Code, so wie du es mit switch machen würdest, damit das Prinzip klar ist. Gut möglich, dass sich da noch etwas optimieren lässt, doch ohne Code kann ich mir es auch nicht genau vorstellen...



  • Jud4s schrieb:

    [...] benutze ich die Möglichkeit der Vererbung... also z.b. ist die Klasse Weaponset (also die ausgewählte waffe und deren Eigenschaften) eine eigenschaft der Klasse player (also die Spielerklasse)[...]
    )

    Ist das denn wirklich sinnvoll? Player erbt also von einem Waffenset, das bedeutet, Player ist ein Waffenset. Macht das wirklich Sinn?



  • Eben solche Sachen meine ich unter anderem - von Design keine Spur (soll jetzt nicht böse gemeint sein) 😉
    Die sprachliche Unklarheit kommt noch dazu.

    @ FoxY: Verdeutliche deinen Programmaufbau an einem Stück Quellcode.



  • Huhu,

    ich hatte schon irgendwie erwartet, dass meine Ausdrucksweise für einige Missverständnisse sorgen wird 😃
    Ich war bei meinem Spiel bisher noch nicht bei den Waffen, deshalb hab ich den wesentlichen Code erstmal improvisiert.

    cout << "Bitte wählen sie eine Waffe (Nummer eingeben und Enter drücken): " << endl;
    cout << "1 Schwert, 2 Knüppel, 3 Axt" <<endl;
    
    RETRY:                        //Wird bei einer falschen Eingabe angesteuert.
    cin >> Chosen_Weapon;
    
    switch(Chosen_Weapon)
    {
          case 1:
               Player_dmg = 4;
               break;
          case 2:
               Player_dmg = 6;
               break;
          case 3:
               Player_dmg = 8;
               break;
    
          default:         //Fehlerhafte Eingabe
                cout << "Bitte 1, 2 oder 3 eingeben!" << endl;
                goto RETRY;
    }
    

    Ich könnte die einzelnen Waffen auch in einer externen Datei in einem 'Päckchen' (beispielsweise einer eigenen Klasse) definieren können, aber trotzdem müsste ich für jede Wahlmöglichkeit einen eigenen Case schreiben.

    Solange es nur bei drei Waffen bleibt und diese sich auch nur in der Angriffsstärke unterscheiden, kann ich das natürlich so machen. Aber wie schon erwähnt, soll das ganze noch wachsen. Es wird zwar weiterhin auf Text basieren, aber es bekommt eine ansprechende grafische Oberfläche, eine Story und tatsächlich mehr als nur drei Waffen, die auch komplexer werden.
    Irgendwie glaube ich einfach nicht, dass ich 200 oder mehr Anweisungen (für jede Waffe eine) formulieren muss. Deshalb hatte ich gehofft, ich könnte jeder eine Art Index zuweisen und dann eine Funktion definieren, die soviel aussagt wie: "Weise dem Spieler den Datenbehälter (die Waffe) zu, die den Index trägt, welche der Eingabe entspricht". Welche Form der 'Behälter' nun haben wird, weiß ich noch nicht - ob eine Klasse, eine Struktur etc.



  • Oder eben ein Array, was wahrscheinlich das Einfachste wäre. Ich begreife deinen Einwand nicht, Jud4s. Ein switch -Block wäre hier definitiv an der falschen Stelle.
    Ausserdem ist ein goto nie gut, da es sehr schnell zu Verhalten führen kann, das du nicht mehr nachvollziehen kannst. Deshalb habe ich eine Do-While-Schleife geschrieben. Diese wird so lange wiederholt, bis die Bedingung am Schluss wahr ist.

    int DamageArray[] = {4, 6, 8, 13, 14, 25}; // 6 Waffen; Index von 0 bis 5
    
    do
    {
       cout << "Bitte Zahl zwischen 1 und 6 eingeben: ";
       cin >> Chosen_Weapon; // Eingabe zwischen 1 und 6
    } while (!(Chosen_Weapon >= 1 && Chosen_Weapon <= 6)); // wenn nicht Eingabe zw. 1 und 6, dann wiederholen
    // gleichwertige Alternative: while (Chosen_Weapon < 1 || Chosen_Weapon > 6); 
    
    Player_dmg = DamageArray[ChosenWeapon-1]; // Hier greifst du auf das Array zu (der Index steht in den []-Klammern)
    // ChosenWeapon-1, weil du ja Eingaben von 1 bis 6 statt 0 bis 5 machst
    

    Falls noch Verständnisfragen auftreten, schreib einfach.



  • Also, wenn ich das richtig abschätze, dann kann ich für jede Eigenschaft, die die Waffen haben sollen ein eigenes Feld machen - oder ich mach ein Array mit mehreren Dimensionen (berichtigt mich nur, wenn die Überlegung falsch sein sollte *g*).
    Einfach, aber genial. Danke 🙂



  • Oder auch irgendwie so:

    struct Weapon
    {
        std::string name;
        int         dmg;
        // Weitere Eigenschaften..
    
        Weapon() {} // Standard-Konstruktor
    
        Weapon( std::string n, int d ) : name(n), dmg(d) {}
    
        bool operator==( const Weapon& other ) const
        { return name == other.name; }
    };
    
    std::map<std::string,Weapon> weapons;
    
    // irgendwo Waffen 'laden':
    weapons["Schwert"] = Weapon( "Schwert", 17 );
    weapons["Dolch"] = Weapon( "Dolch", 6 );
    
    Weapon chooseWeapon()
    {
        std::cout << "Verfügbare Waffen: " << std::endl;
        for ( std::map<std::string,Weapon>::const_iterator i=weapons.begin(); i!=weapons.end(); i++ )
            std::cout << "  " << i->first << " (" << i->second.dmg << " Schaden)" << std::endl;
    
        std::string choice;
        bool weapon_found = false;
        do
        {
            std::cout << "Bitte eine Waffe auswählen: ";
            std::cin >> choice;
    
            if ( weapons.find(choice) != weapons.end() )
                weapon_found = true;
            else
                std::cout << "Ungültige Eingabe, bitte nochmal versuchen" << std::endl;
    
        } while ( ! weapon_found );
    
        return weapons[choice];
    }
    

    edit: Bzw kannst du auch einen std::vector statt einer std::map benutzen, kommt aber halbwegs aufs selbe raus.

    edit2: :p Dafür hat Nexus in seinem Post den sequenziellen Zugriff drin, das ist für einen Anfänger wahrscheinlich eine Ecke einfacher 🙂



  • FoxY schrieb:

    Also, wenn ich das richtig abschätze, dann kann ich für jede Eigenschaft, die die Waffen haben sollen ein eigenes Feld machen - oder ich mach ein Array mit mehreren Dimensionen (berichtigt mich nur, wenn die Überlegung falsch sein sollte *g*).
    Einfach, aber genial. Danke 🙂

    Ja, das wäre eine Möglichkeit. Wenn du allerdings mehrere Eigenschaften hast, lohnt es sich mit der Zeit, ein Array von Klasseninstanzen machen. Ich weiss nicht, ob du dich mit Klassen bereits auskennst, ansonsten ist das mit dem Array vielleicht eine gute Übung.

    Mit Klassen ginge es etwa so:

    struct Waffe
    {
       std::string Name;   // Halt irgendwelche Eigenschaften
       int Schaden;
       int Kosten;
       Waffe(std::string NeuerName, int NeuerSchaden, int NeueKosten) // Konstruktor
       : Name(NeuerName), Schaden(NeuerSchaden), Kosten(NeueKosten) {};
    };
    
    int main()
    {
       Waffe WaffenArray[7];
       WaffenArray[0].Waffe("Schwert", 4, 250);
       WaffenArray[1].Waffe("Speer", 7, 350);
       // und so weiter
       int WaffenName, WaffenSchaden, WaffenKosten;
       // hier käme die Eingabe der Nummer mit allem drum und dran;
       cin >> Index; // halt zwischen 0 und 7
       MeinName = WaffenArray[Index].Name; // hier könntest du auf die Klassenmember zugreifen
       MeinSchaden = WaffenArray[Index].Schaden;
       MeineKosten = WaffenArray[Index].Kosten;
    }
    

    Oder du könntest noch extra Funktionen dazu machen...

    Edit: Verdammt, zu spät 😉



  • Die letzten beiden Beispiele kann ich jetzt noch etwas schwer einschätzen. Ich weiß zwar, was Strukturen, Klassen usw. sind, aber die Möglichkeiten sind mir in ihrer vollen Pracht noch ein Rätsel 😕

    Ich glaub, da muss ich mich erstmal noch ein wenig reinlesen.



  • Ja, falls du noch nicht gross mit Klassen gearbeitet hast, sind unsere Methoden nicht unbedingt geeignet. Vorläufig würde ich es entweder bei einem 2D-Array oder mehreren eindimensionalen Arrays belassen, dann vertiefst du auch gerade ein anderes wichtiges Kapitel von C++ 😉



  • Achja, eine kleine Frage hätte ich da noch. Es hat eigentlich nicht wirklich mit dem bisherigen Thema zu tun, aber ich wollte keinen extra Thread dafür eröffnen.

    Und zwar benutze ich Dev-C++. Wenn ich da versuche zu debuggen taucht die Meldung auf, dass in dem Programm keine Debugging Informationen erhalten sind und ob ich erneut Kompilieren und Debugging aktivieren möchte. Bringt aber nichts, wenn ich bestätitge.
    Mir ist nicht ganz klar, was er da für Informationen braucht.



  • Passiert das nicht nur, wenn du versuchst, von einem Header aus zu kompilieren? Machs mal von einer .cpp-Datei aus...

    Ich hatte früher auch Dev-C++, aber bin auf Microsoft Visual C++ 2008 Express umgestiegen. Das würde ich dir auch empfehlen, der ist nämlich moderner und bietet mehr Funktionen und Benutzerfreundlichkeit (z.B. IntelliSense).



  • Darauf hab ich auf Grund persönlicher Antipathien gegen Microsoft verzichtet *g*
    Aber sieht wohl so aus, als wäre Visual C++ ein Grund, mal zähneknirschend über den Stolz hinwegzusehen.



  • FoxY schrieb:

    Darauf hab ich auf Grund persönlicher Antipathien gegen Microsoft verzichtet *g*
    Aber sieht wohl so aus, als wäre Visual C++ ein Grund, mal zähneknirschend über den Stolz hinwegzusehen.

    Guck Dir mal Codeblocks an. Das sollte ausreichend sein.



  • Du musst es natürlich selber wissen, ich finde VC++ eigentlich okay, und Dev-C++ ist wirklich mühsam dagegen... Ich würde VC++ einfach mal ausprobieren, und sonst kannst du ja immer noch zurückwechseln 😉

    Ansonsten gibt es z.B. noch Code::Blocks und einige weitere Entwicklungsumgebungen.
    Dev-C++ hat einfach das Problem, dass er veraltet ist. Teilweise werden auch gewisse Features nicht unterstützt (und er hat - glaube ich - auch einige Bugs).



  • Also ich hoffe mal, ich nerve nicht mit meinen häufigen Fragen, aber ich hätte noch eine - diesmal aber aus reiner Neugierde.

    Wie werde solche Dinge eigentlich in professionellen Projekten gelöst? Das letzte mal, als ich in einem kommerziellen Spiel rumgeschnüffelt hab (nur mit legalen Methoden, versteht sich), habe ich nur einfache Tabellen gefunden, wie man sie in jedem Textdokument vermuten könnte. Die enthielten ebenfalls alle Daten, die ich jetzt in Arrays stopfe.

    Im Übrigen auch Danke für den Ratschlag bezüglich Visual C++. Der Editor allein ist schon übersichtlicher, von dem ganzen Zucker drum herum garnicht zu sprechen.



  • Hallo,

    also das Problem mit dem Debuggen bei Dev-Cpp ist, dass er, selbst wenn du nach der Meldung debugging aktivieren willst, es nicht tut...du musst das per Hand aktivieren, das muss irgendwo in den Projektoptionen gehen. Leider kann ich das jetzt nicht genau nachschaun, habe das Teil vor kurzem deinstalliert^^ Code::Blocks und auch Microsoft VS sind da konfortabler...abgesehen davon, dass MVS etwas over the Top ist für kleinere Projekte (meine Meinung)...ansonsten ist auch Wascana(eclispe) nicht schlecht...

    Sahen die "Tabellen" in etwa so aus:
    Schwert 6 3 6
    Axt 7 18 6
    Peitsche 8 18 9

    Wenn ja, entsprechen diese Werte folgendem (z.B.):
    Waffenname : Damage als Krieger : Damage als Magier : Damage als Dieb

    Lies die Daten zeilenweiße bzw. Wortweiße ein und speicher sie entsprechend...z.B. in eine Struktur

    struct Waffe
    {
    std::string name;
    int dmgWarrior;
    int dmgMage;
    int dmgThief;
    }

    oder in einem 2-dimensionalem Array. Oder in einer eigenen Klasse.

    Professionelle Projekte nutzen, selbstdefinierte Formate, es sei denn, es gibt schon schöne, wie z.B. für 3D-Modelle etc...selbdefiniert wäre auch das, wie oben erwähnt^^

    Grüsse



  • Das klingt auf jeden Fall interessant. Ich glaub, das wird mein nächstes Zwischenziel, wenn ich die Grundlagen und die Objektorientierung abgeschlossen hab.

    Danke für all die geduldigen und hilfreichen Antworten 🙂


Anmelden zum Antworten