Objektkoordinaten 2d Array



  • Hi Furble

    Leider weis ich so gut wie nichts über klassen. wir sind in der schule noch nicht so weit. Wir sind eigentlich noch bei den grundlangen in C. Deswegen will ich jetzt durch solche projekte üben. Also Objektorientiert programmieren. Ich weiss aber ehrlich gesagt nicht genau was das bedeutet. Ich stelle mir die dinge dadurch übersichtlicher und einfacher zu handhaben vor.

    Ich denke sicherer im umgang mit funktionen werden ist der erste schritt oder?

    Ist es möglich 2 vektoren in einem array zu speichern? Also das man ein feld mit der höhe 2 und undendlicher länge erzeugen könnte?

    Ein 2d array-vektor oder sowas?



  • Photon schrieb:

    Leider weis ich so gut wie nichts über klassen. wir sind in der schule noch nicht so weit. Wir sind eigentlich noch bei den grundlangen in C. Deswegen will ich jetzt durch solche projekte üben. Also Objektorientiert programmieren. Ich weiss aber ehrlich gesagt nicht genau was das bedeutet. Ich stelle mir die dinge dadurch übersichtlicher und einfacher zu handhaben vor.

    Wesentlich leichter.

    Ich denke sicherer im umgang mit funktionen werden ist der erste schritt oder?

    Jein.
    Objektorientiert programmieren heißt, dass man in Objekten denkt.
    Diese haben bestimmte Daten und Verhaltensweisen (durch Funktionen implementiert, in C++ Memberfunktionen). Es stehen aber nicht die Daten, sondern diese Verhaltensweisen im Vordergrund.
    In deinem Snakebeispiel hättest du beispielsweise eine Klasse Snake, die hat einen Vektor, der die Position für jedes Feld speichert. Eine Funktion update() bearbeitet diesen Vektor, indem die Schlange dort bewegt wird.
    Eine Funktion draw() zeichnet die Schlange.
    Ähnliches auch für die Map.
    Du solltest dir aber auf jeden Fall ein gutes Grundlagenbuch besorgen und das durcharbeiten, dort lernst du mehr als in der Schule.
    Denn rohe Arrays sollte man im modernen C++ nicht mehr benutzen.

    Ist es möglich 2 vektoren in einem array zu speichern? Also das man ein feld mit der höhe 2 und undendlicher länge erzeugen könnte?

    Ein 2d array-vektor oder sowas?

    Ja.

    std::vector<std::vector<some_type>> vec
    

    Zugriff via:

    vec[5][2]
    

    Besser ist es aber einen 2 dimensionalen Vektor auf einen eindimensionalen abzubilden, das ist aber für dich vermutlich zu kompliziert.



  • Photon schrieb:

    Hi Furble

    Leider weis ich so gut wie nichts über klassen. wir sind in der schule noch nicht so weit. Wir sind eigentlich noch bei den grundlangen in C. Deswegen will ich jetzt durch solche projekte üben. Also Objektorientiert programmieren. Ich weiss aber ehrlich gesagt nicht genau was das bedeutet.

    Lernst Du C oder C++?
    Das sind verschiedene Sprachen!

    Objektorientiert heisst ja erstmal nur, dass Du in Kategorien denkst wie: Welche Entitäten habe ich? welche Eigenschaften haben diese Entitäten?

    Z.B. könntest Du Dir beim snake Spiel überlegen: ich habe Positionen auf dem Spielfeld und eine Schlange mit einer bestimmten Länge und einem Körper.
    Damit hast Du schon zwei Arten von Objekten und legst los:

    #include <iostream>
    #include <vector>
    
    struct pos{ int x, y; };
    
    std::ostream& operator<<(std::ostream& out, const pos& p){
        return out << '(' << p.x << ", " << p.y << ')';
    }
    
    struct snake{
    	unsigned int length_;
    	std::vector<pos> body_;
    };
    
    snake make_snake(unsigned int length){
    	snake s{length};
    	return s;
    }
    
    void move(snake& s, const pos& p){
    	s.body_.insert(begin(s.body_), p);
    	if(s.length_ < s.body_.size())
    		s.body_.pop_back();
    }
    
    void print(const snake& s){
    	for(const pos& p : s.body_)
    		std::cout << p << ' ';
    }
    
    int main(){
    	snake snakey_snake = make_snake(5u);
    	for(int i=0; i<10; ++i){
    		move(snakey_snake, {42+i, 6});
    		print(snakey_snake);
    		std::cout << '\n';
    	}
    }
    

    Das war's schon.
    Wie Du siehst findest Du die beiden Entitäten Position und Schlange im Code wieder und dann Funktionen, die damit arbeiten. In der main() , z.B. lasse ich die Schlange sich 10 Felder bewegen und gebe immer die Lage Ihrer Körpersegmente aus.

    Ich denke, der Code kommt ohne weitere Erklärungen aus.

    Das ist allerdings noch kein richtiges C++, sondern eher C.
    C++ unterstützt Objektorientierung noch viel weitgehender. Aber Objektorientiert ist das Programm alle mal - kein Hexenwerk also.



  • Furble Wurble schrieb:

    Das war's schon.

    Finde ich didaktisch schlecht, einem Anfänger, der durchaus interessiert ist, sich selbst was beizubringen und mit seinen Fragen schon auf dem richtigen Weg ist, eine fertige Lösung hinzuknallen. ostream? operator<<? Referenzen? 5u? Wie soll er da durchblicken?

    Er hat doch Freude daran, das Problem selbst zu lösen. Diese Freude nimmst Du ihm, indem Du prinzipiell zeigst: Weg da, ich kann das eh viel besser.

    Erklär doch erstmal, wie sich ein Vector im Vergleich zum Array verhält, wie man eine Klasse (oder struct) erstellt, wie man auf die Member zugreift, wie man dann einen Vector of Type xy baut usw. Was Photon braucht, sind die Grundlagen, nicht die Lösungen. Schade.



  • Hallo leute,

    danke für die vielen antworten. Ja über ein grundlangen buch habe ich schon nachgedacht und stand auch schon ein paar mal im buchladen davor und habe mir welche angeschaut. Allerdings weiss ich nicht welches gut und welches nicht so gut ist. Einfach zeilen ohne große erklärung abtippen mag ich nicht. Vieleicht kann mir jemand eins empfehlen.

    Wir lernen in der Schule allgemein Programmieren. Wir hatten ein bischen java am anfang. Da haben wir aber nur ganz grob die grundlagen angeschnitten. Mysql und Php hatten wir auch eine woche und auch da nur grob grundlagen. Und vor einem monat hatten wir 1 woche C grundlagen. Allerdings habe ich keine lust immer zu warten und so.
    Deshalb habe ich mich entschieden erstmal c++ für mich als hauptsprache zu wählen und mir das so gut es geht selber bei zu bringen.
    Das gute ist all das mathematische hintergrund zeug kriegen wir in der schule auch. Ich denke das wird dann später fruchten weil leute die sich das selbst beibringen das eben vernachlässigen.

    Soviel dazu. Zu Furbles post. Ich finde das ok weil ich den code sowieso nicht kopieren oder sowas ich lese ihn und versuche ihn nach zu voll ziehen werde gleich mal einige sachen davon googlen. In erster linie dient er mir als anreiz das mein code später auch mal so in etwa ausehen soll. Eben nicht alles in die main knallen.
    Vor allem das was hier als objekt gilt und warum finde ich gut erklärt.

    Was für mich in diesen moment ganz gut wäre ist wenn mir jemand grob ein plan für die nächste zeit gibt sowas wie:

    1 Funktionen
    2 Klassen
    2 Strukturen

    Eine liste zu abarbeiten um tiefer in die materie einzutauchen. Es gibt nämlich so viel ich weiss nicht wo ich anfangen soll.

    Kurze frage noch. Sehe ich das richtig das die ganze schlange also jedes element bewegt wirrd? Ist es nicht gut so wie ich immer das element von vor 5 runden zu löchen?

    Edit: zu deim vector im vector ist es dann nicht ein feld mit unenddlich mal unendlich länge?

    Grüße an alle
    ist ein tolles Forum 😃



  • Photon schrieb:

    Kurze frage noch. Sehe ich das richtig das die ganze schlange also jedes element bewegt wirrd? Ist es nicht gut so wie ich immer das element von vor 5 runden zu löchen?

    Ich pappe vorne in den vector body_ die neue Position des "Kopfes".
    Wichtig: ich füge die neue Position hinzu. Wenn der Körper vorher 5 Felder belegte, belegt er nun 6.
    Im nächsten Schritt schaue ich, ob der Körper mehr Positionen belegt, als die Schlange lang ist, wenn ja lösche ich das letzte Element. Das alles in move() .
    Dabei "bewege" ich tatsächlich immer "die ganze Schlange" - d.h. jedes Positionsobjekt wird verschoben, das ist richtig. Aber der Vektor mit den Körperelementen ist immer höchsten eins größer als length_ .

    Photon schrieb:

    Edit: zu deim vector im vector ist es dann nicht ein feld mit unenddlich mal unendlich länge?

    Da gibt es keinen vector im vector. Wahrscheinlich ist die Zeile hier kryptisch:

    s.body_.insert(begin(s.body_), p);
    

    Was da steht ist: füge die Position p vor das bislang erste Element ( begin(s.body_) ) in den vector body_ ein.
    Siehe hier:
    http://en.cppreference.com/w/cpp/container/vector/insert Variante (1)



  • Hey

    Ich habe ein wenig gerätselt und so halb verstehe ich deinen codde. Lediglich daas mit der x und y position macht mir zu schaffen. Vor allemweil du ja nur 1 vector benutzt. Speicherst du immer x und y in ein fach? oder ist es doch irgendwie 2d?

    Das mit den structs will ich jetzt gleich auch mal testen.

    Ist snake_make_snake sowas wie ein unter-struct? weil es wird ja nicht deklariert aber snake ist vorher schon da.

    Das mit der länge verstehe ich auch noch nicht so ganz. Wo wird die länge festgelegt? Sie ist da aber hat keinen wert oder?

    Ja ich hab noch einen weiten weg vor mir 😮



  • ...



  • Ja so langsam kommt das verständnis und die denkweise danke leute.
    Ich habe gerade schwierigkeiten mit structs und funktionen.

    #include <iostream>
    
    int h_generator();
    
    struct hero {int dmg, def, hp;};
    
    int h_generator(hero) // Welcher typ muss hier hin?
    {
        hero red = {5,3,10};
        return (red);  //Hier will ich hero red übergeben aber ich bekomme eine fehlermeldung.
    }
    
    int main()
    {
        h_generator();
        std::cout << red; //Hier unten auch. Red ist nicht deklariert.
        return 0;
    }
    

    WAs mache ich noch flasch? 😕



  • Deine Funktion "h_generator()" hat den Rückgabewert "int". Das du hier kein Object vom Typ "hero" zurückgeben kannst, sollte denke ich logisch sein. Auch macht der Parameter vom Typ "hero" keinen Sinn. Du solltest dir dringend nochmal Funktionen im Allgemeinen ansehen.

    #include <iostream>
    
    struct hero {int dmg, def, hp;};
    
    hero h_generator()
    {
        hero red = {5,3,10};
        return red;
    }
    
    int main()
    {
        hero red = h_generator();
        std::cout << "dmg: " << red.dmg << " def: " << red.def << " hp: " << red.hp << std::endl;
        return 0;
    }
    


  • ...



  • ok leute nochmals danke langsam komm ich wirklich rein 😃

    #include <iostream>
    #include <stdlib.h>
    
    using namespace std;
    
    struct hero {int dmg, def, hp;};
    
    hero h_generator()
    {
        int arr[3];
        for(int i = 0; i<3;i++){
        arr[i] = rand() % 10 + 1;}
        hero randy = {arr[0],arr[1],arr[2]};    //Hier sollten zufällige zahlen enstehen
        return randy;                           //aber es werden immer die gleichen generiert
    }
    
    hero showdown (hero a, hero b)
    {
        a.dmg -= b.def;
        if(a.dmg<0){a.dmg=0;}
        {b.hp -= a.dmg;}
        return a;
    }
    
    hero print_value(hero temp)
    {
        cout << "dmg: " << temp.dmg << " def: "
             << temp.def << " hp: " << temp.hp << endl << endl;
    }
    
    int main()
    {
        hero store;
    
        hero red = h_generator();
        hero blue = h_generator();
        store = red;
        cout << "red: \n"; print_value(red);
        cout << "blue: \n"; print_value(blue);
    
        cout << "\nSHOWDOWN!!!\n" << endl;
    
        red = showdown(red,blue);
        blue = showdown(blue,store);
        cout << "red: \n"; print_value(red);
        cout << "blue: \n"; print_value(blue);
    }
    

    Weis jemand warum diese random funktion nicht macht was ich will?

    Und ist es möglich eine art funktion zu bauen die mehr als nur eine sache zurück gibt?



  • Photon schrieb:

    Und ist es möglich eine art funktion zu bauen die mehr als nur eine sache zurück gibt?

    Nein, das geht so erst einmal nicht. Du kannst allerdings Referenzen als Parameter übergeben, welche dann innerhalb der Funktion gesetzt werden.

    Photon schrieb:

    Weis jemand warum diese random funktion nicht macht was ich will?

    Du musst random zuerst einmalig in deinem Programm seeden. Beim seeden übergibst du einen Wert, anhand dessen sich dann die zukünftigen Zufallszahlen berechnen lassen. Da du nicht seedest, ist dieser Wert immer 0. Würdest du jetzt einfach nur eine Zahl als seed übergeben, würde das gleiche passieren, nur mit anderen Zahlen. Sie wären bei jedem Programmstart identisch. Deswegen übergibt man die Systemzeit, um einen möglichst zufälligen Wert zu erhalten.

    http://www.cplusplus.com/reference/cstdlib/rand/

    demzufolge fehlt deinem Programm folgendes:

    #include <time.h>
    
    ...
      /* initialize random seed: */
      srand (time(NULL));    // natürlich innerhalb der main funktion, und das am besten ganz an den Anfang
    ...
    


  • ...



  • danke anti-freak und danke swordfish für die erwiterung. 👍

    Allerdings funktioniert das bei mir nicht mit nullptr und mit null auch nicht nur wenn ich 0 benutze. Ich verstehe die zeile auch nicht 100%

    std::srand( std::time( nullptr ) );
    

    könnte jemand ein paar erklärende worte abgeben? Habe eben mal gegooglet zu 0 null und nullptr und ich weiss das es was mit zeigern zu tun hat ich blicke aber nicht ganz durch.



  • Photon schrieb:

    Allerdings funktioniert das bei mir nicht mit nullptr und mit null auch nicht nur wenn ich 0 benutze. Ich verstehe die zeile auch nicht 100%

    std::srand( std::time( nullptr ) );
    

    "Funktioniert nicht" ist keine Fehlerbeschreibung.

    Bei uns funktioniert das.

    Merk Dir diese Seite: http://en.cppreference.com/w/.
    Dort wirst Du wahrscheinlich häufig vorbeischauen, wenn Du C++ lernst.

    Dort steht z.B. fuer time()

    Defined in header <ctime>

    time_t time( std::time_t *time );

    Returns the current calendar time encoded as a std::time_t object.

    Hast Du den Header <ctime> inkludiert?

    Sonst: wie ist die Fehlermeldung?



  • ...



  • Swordfish schrieb:

    nullptr (C++11), NULL bzw. (void *) 0 ist der Null Pointer.

    Nein, nullptr (C++11), NULL aka 0 bzw. 0L ist der Null Pointer.

    (void*)0 ist in C++ nicht der Nullpointer (funktioniert nicht für Memberpointer).



  • So habe ich es genau gemacht:

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    
    struct hero {int dmg, def, hp;};
    
    hero h_generator()
    {
        int arr[3];
        for(int i = 0; i<3;i++){
        arr[i] = rand() % 10 + 1;}
        hero randy = {arr[0],arr[1],arr[2]};
        return randy;
    }
    
    hero showdown (hero a, hero b)
     {
        b.dmg -= a.def;
        if(b.dmg<0){b.dmg=0;}
        a.hp -= b.dmg;
        return a;
    }
    
    hero print_value(hero temp)
    {
        cout << "dmg: " << temp.dmg << " def: "
             << temp.def << " hp: " << temp.hp << endl << endl;
    }
    
    int main()
    {
    
        srand(time(nullptr));
    
        hero red   = h_generator();
        hero blue  = h_generator();
        hero store = red;
        cout << "red: \n"; print_value(red);
        cout << "blue: \n"; print_value(blue);
    
        cout << "\nSHOWDOWN!!!\n" << endl;
    
        red  = showdown(red,blue);
        blue = showdown(blue,store);
        cout << "red: \n"; print_value(red);
        cout << "blue: \n"; print_value(blue);
    }
    

    Also die beteffende zeile ist eine funktion die eine funktion aufruft die den wert auf den der 0 pointer zeigt behandelt?!

    std::srand( std::time( nullptr ) );
    

    Soweit ich es verstanden habe sind structs wie klassen nur das alle sachen public sind. An welchen stellen macht es sinn richtige klassen anzulegen? Gibt es klassen die als "parameter"(ist das der richtige ausdruck?) structs besitzen?



  • Photon schrieb:

    So habe ich es genau gemacht:

    Und was funktioniert daran nicht?

    Du wirst nicht um den Kauf eines C++-Buches herumkommen, wenn Du es ernsthaft meinst mit dem Lernen - ein Forum ist kein Ersatz für ein Buch
    und die mir bekannten Online Quellen auch nicht.
    Hier im Forum gibt es immer mal wieder Threads in denen nach Büchern gefragt wird, und in denen Empfehlungen ausgesprochen werden.

    Zum Thema Funktionen:

    hero print_value(hero temp);
    hero showdown (hero a, hero b);
    

    Weisst Du, was das hero vor dem Funktionsnamen bedeutet?

    Kennst Du Übergabe per Wert/Übergabe per Referenz?
    Wenn ja: welche Konsequenz hat dieses Wissen für showdown() ?
    Wenn nein: lies es nach.


Anmelden zum Antworten