2D Vector, wie gehts?



  • Hallo,

    Ich komme nich ganz draus wie das mit den 2D Vektoren funktioniert, wie genau kann ich z.b. eine Map in ein 2D Vektor packen und dann immmer schön map[x][y] beschreiben?

    for (int x=0;x<20;x++)
    	{
    		for (int y=0;y<20;y++)
    		{
    			map[x][y] = 'G'; //Wie muss diese Zeile aussehen mit Vektoren?
    			if(y % 2 == 0)	if (x % 2 == 0)  map[x][y] = 'W';
    			if ((x == 0) || (x == 20) || (y==0) || (y==20))
    				map[x][y] = 'W'; //Wie muss diese Zeile aussehen mit Vektoren?
    		}
    	}
    

    Ich hab map bis jetzt als Array genommen aber würd gerne das als vector nu, wie mach ich denn das genau? schnall das irgendwie nicht..

    Vielen Dank für die Hilfe!



  • Genau so?



  • Hallo Flutscherino,

    so sollte das gehen:

    #include <iostream>
    #include <vector>
    
    int main()
    {
        using namespace std;
        const size_t N = 20;
        vector< vector< char > > map( N, vector< char >(N) );
        for (int x=0; x<N; x++)
        {
            for (int y=0;y<N; y++)
            {
                map[x][y] = 'G'; //Wie muss diese Zeile aussehen mit Vektoren?
                if(y % 2 == 0)    if (x % 2 == 0)  map[x][y] = 'W';
                if ((x == 0) || (x == 20) || (y==0) || (y==20)) // Bem.: x,y wird NIE ==20
                    map[x][y] = 'W'; //Wie muss diese Zeile aussehen mit Vektoren?
            }
        } 
        return 0;
    }
    

    Gruß
    Werner



  • lol es ging die ganze zeit nicht, jetzt hab ich den Beitrag geschrieben und jetzt gehts... tststs

    Danke auf jedenfall dennoch fürs Antworten 😉


  • Mod

    Noch eine Anmerkung: Die meisten Leute die meinen, einen vector<vector> zu brauchen, brauchen in Wirklichkeit einen vector<array> oder einen 2D-Wrapper um einen 1D-Vector (mit dynamischen, aber immer gleichen Zeilenlängen). Überleg dir, was du wirklich brauchst.



  • SeppJ schrieb:

    Noch eine Anmerkung: Die meisten Leute die meinen, einen vector<vector> zu brauchen, brauchen in Wirklichkeit einen vector<array> oder einen 2D-Wrapper um einen 1D-Vector (mit dynamischen, aber immer gleichen Zeilenlängen). Überleg dir, was du wirklich brauchst.

    Naja ich bin jetzt mal am lernen wie mit Vektoren umgehn damit ich von Arrays wegkommen kann... mehr nicht 😉
    Dennoch Danke!



  • Flutscherino schrieb:

    Naja ich bin jetzt mal am lernen wie mit Vektoren umgehn damit ich von Arrays wegkommen kann... mehr nicht 😉

    SeppJ meinte ein gekapseltes, kein rohes Array. 😋



  • SeppJ schrieb:

    Noch eine Anmerkung: Die meisten Leute die meinen, einen vector<vector> zu brauchen, brauchen in Wirklichkeit einen vector<array> oder einen 2D-Wrapper um einen 1D-Vector (mit dynamischen, aber immer gleichen Zeilenlängen). Überleg dir, was du wirklich brauchst.

    SeppJ hat Recht. Ich hatte so eine Konstruktion hier schon mehrfach gepostet, aber finde i.A. nichts.

    Das sieht im allereinfachsten Fall so aus:

    #include <vector>
    
    class Matrix
    {
    public:
        Matrix( std::size_t height, std::size_t width )
            : width_( width )
            , data_( height * width_ )
        {}
        char* operator[]( std::size_t iLine )
        {
            return &data_[ iLine * width_ ];
        }
    private:
        std::size_t width_;
        std::vector< char > data_;
    };
    

    und Zeile 8 meines ersten Postings ersetzt man dann durch

    Matrix map(N,N);
    

    Mit so einer Klasse Matrix hast Du ganz andere Möglichkeiten, spezielle Matrix-Funktionen hinzuzufügen.

    Gruß
    Werner



  • Hmm wie klappt das jetzt mit dem auslesen?

    Wenn ich das versuch

    if ( map[x][y] == 'G' ) MACH WAS!;
    

    ergibt es diese Fehlermeldung, wie frag ich den das nun ab?

    error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::vector<_Ty>' (or there is no acceptable conversion)


  • Mod

    Zeig mal bitte den Code mit allen relevanten Definitionen, der diesen Fehler verursacht.



  • void Graphics::DrawMap()
    {
    	if (mapLoaded == true)
    	{
    		karte.Load();
    		mapLoaded = true;
    	}
    
    	map = karte.getMap();
    
    	for (int x=0;x<20;x++)
    	{
    		for (int y=0;y<20;y++)
    		{
    			if ( map[x][y] == 'G' ) gameWindow->draw(SGround);
    			if ( map[x][y] == 'W' ) gameWindow->draw(SWall);
    
    		}
    	}
    
    }
    
    #pragma once
    #include <SFML\Graphics.hpp>
    #include <SFML\System.hpp>
    #include <SFML\Window.hpp>
    
    #include "Map.hpp"
    
    class Graphics
    {
    public:
    	Graphics();
    	sf::RenderWindow *CreateWindow();
    	void DrawMap();
    
    private:
    
    	sf::RenderWindow *gameWindow;
    	bool mapLoaded;
    
    	Map karte;
    	vector < vector < char > > *map;
    
    	sf::Texture TWall, TGround;
    	sf::Sprite SWall, SGround;
    };
    
    #pragma once
    #include <vector>
    
    using namespace std;
    
    class Map
    {
    
    public:
    	Map();
    	~Map();
    	void Load();
    	vector <vector <char> > *getMap() {return &map;}
    
    private:
    	int GroesseX, GroesseY;
    	vector< vector< char > > map;
    
    };
    

    Kann ja nich alles posten, hoffe hier is alles drin 😉



  • wenn du statt dem zeiger ne referenz zurückgibst gehts

    greetz KN4CK3R



  • hmmm, scheint zu gehn 😃 mein fehler, danke vielmals!

    weis einer auch noch warum das es geht? danke!


  • Mod

    Flutscherino schrieb:

    weis einer auch noch warum das es geht? danke!

    Das große Geheimnis an Arrays/Zeigern: foo[i] ist kurz für *(foo+i) *

    Damit beantworte zur Übung folgende Fragen:


    Was ist somit map[x][y] in deiner alten Version?
    Was sind diese Sachen, wenn du stattdessen eine Referenz zurück gibst?
    Was ist die Bedeutung dieser Ausdrücke in der alten Version?
    Wieso funktioniert das, beziehungsweise nicht, und wieso bekommst du die Fehlermeldung, die du bekommen hast?

    *: Dies hat, lieber Leser, übrigens die interessante Wirkung, dass i[foo] auch *(i+foo) ist und, da die Addition kommutativ ist, somit das gleiche wie foo[i] . Jetzt könnt ihr auch so unlesbare Programme schreiben, wie die coolen Kinder hier im Forum:
    https://ideone.com/nv3Ow



  • Ich muss die Referenz (map) initialisieren aber ich weis nicht wie ich das mache... kann mir da wer helfen?

    Der Error ist folgender:
    error C2758: 'Graphics::map' : must be initialized in constructor base/member initializer list


  • Mod

    Weißt du, was eine Initialisierungsliste/initializer list ist? Falls ja: Nutze sie um Member ohne Standardkonstruktoren zu initialisieren (und auch alle anderen). Falls nein: Informier dich und fahre bei der "Ja"-Antwort fort.

    Ich bin nun jedoch wirklich erstaunt: Ein vector/map haben beide einen Standardkonstruktor, die Meldung sollte daher nicht auftauchen. Ich spekuliere mal: Du hast jetzt die Membervariable map selbst als Referenztyp deklariert? Falls ja: Ojeh 😞 . Besser nochmal Grundlagen zu Referenzen, Pointern, Membern usw. lernen. Falls die Spekulation richtig ist, scheint da einiges zu fehlen.



  • SeppJ schrieb:

    Weißt du, was eine Initialisierungsliste/initializer list ist? Falls ja: Nutze sie um Member ohne Standardkonstruktoren zu initialisieren (und auch alle anderen). Falls nein: Informier dich und fahre bei der "Ja"-Antwort fort.

    Ich bin nun jedoch wirklich erstaunt: Ein vector/map haben beide einen Standardkonstruktor, die Meldung sollte daher nicht auftauchen. Ich spekuliere mal: Du hast jetzt die Membervariable map selbst als Referenztyp deklariert? Falls ja: Ojeh 😞 . Besser nochmal Grundlagen zu Referenzen, Pointern, Membern usw. lernen. Falls die Spekulation richtig ist, scheint da einiges zu fehlen.

    Jop du hast rechts, mir fehlt noch einiges in dem Gebiet, bin ja eben grad am lernen 😉

    Danke, werd das mal nachschlagen was du mir da geschrieben hast!


Log in to reply