how do I use two-dimensional arrays?

So yeah I’m really new to programming in general just started a couple of months ago.

But anyway, I’m having trouble using 2d arrays in openframeworks (mainly because I can’t really figure out how to use them)

so what I’m having trouble with is, I’m trying to create a map using a 2d array.
Not sure on how to do it but this is how I tried to atleast

int the Setup() part I would write:

  
  
int w = 1;  
int R = 2;  
  
int Map[8][8] = {  
{ w,w,w,w,w,w,w,w },  
{ w,w,w,w,w,w,w,w },  
{ R,R,R,R,w,w,w,w },  
{ w,w,w,R,w,R,R,R },  
{ w,R,R,R,w,R,w,w },  
{ w,R,w,w,w,R,w,w },  
{ w,R,R,R,R,R,w,w },  
{ w,w,w,w,w,w,w,w }};  
  
  

And then in the draw() part I would use it like:

  
for(int i = 0; i < 8; i++)  
{  
    for(int j = 0; j < 8; j++)  
    {  
	if(Map[i][j] == w)  
	{  
             drawSomething;  
        }  
  
	if(Map[i][j] == R)  
	{  
             drawSomethingElse;  
        }  
     }  
}  
  

But for some reason when I compile it, all the values and everything gets turned into some kind of trash value or whatever, even tried changing the R and W to static const but they still change / doesn’t get set as if the compiler doesn’t even run through the Setup() part.

Anyways would love an answer on what’s wrong or rather how to use 2d arrays properly.
Thanks!

hey darkoccisor,

welcome to the openFrameworks forums!

i wrote a reply to a topic about 2D arrays about four years ago, try this link:

http://forum.openframeworks.cc/t/arrays-for-c+±newbies/918/2

cheers!
damian

Thank you for the welcome and the quick reply.

Yeah I actually read your post before I posted but it only made me more confused so I thought I’d make a new post and ask again in hope for some simpler answers :slight_smile:
(I’m bad with pointers, didn’t really study them that much yet) :stuck_out_tongue:

And since I also wanted to use the 2d arrays as a way to figure out the X Y coords as in:

if Map[5][10] contained a "R"oad piece then I would draw up a road there by doing x = 5 * 20 and y = 10 * 20. (if resolution was 800x600 and Map[][] was [40][30].
(sorry for the bad explanations, haven’t really slept at all so)
Anyway that’s why I decided against using 1d arrays, since I wouldn’t be able to figure out the coords if I did.

I think your problem is with scope.

In order to access your R,w, and Map variables in both your setup(), update(), and draw() functions, you need to declare them in your header file (testApp.h) and then not re-declare them in setup.

The code you pasted says you’re doing this in setup():

int w = 1;
int R = 2;
int Map[8][8] = …

When you include the type declaration like that (the “int” before the variable name), you’re declaring those as local variables to the setup() function. The values you put into them will not be available in your other functions.

Any variable you want to use in every function should be declared in your header file and then only set in your functions. Like this. In testApp.h

class testApp : public ofBaseApp {
public:

int w, R;
int Map[8][8];

};

then in your setup function (and elsewhere) you refer to them with the type declaration:

void testApp::setup(){
w = 1;
R = 2;
map = {…etc
}

That way the values actually get stored into the member variables that you declared in the header file and use in the other functions.

Thanks gregab

actually had them declared in the header file aswell.
Now the values are stored correctly except for the 2d array which gives me an error

Error: expression must be a modifiable lvalue
and
Error: expected an expression

I guess it’s because it’s already been declared in the header file so that’s why I can’t modify the values like the way you said, or maybe it’s something else.

Can you post your code somewhere so I can see it. It sounds like a simple problem that’s hard to guess at without seeing all the relevant files.

here’s the header file

  
  
#ifndef _ofTDMap  
#define _ofTDMap  
  
#include "ofMain.h"  
  
class ofTDMap {  
  
public:  
  
	ofImage menuFrame;  
  
	void update();  
	void draw();	  
	ofTDMap();  
  
	int Map[30][40];  
	int S;  
	int R;  
	int W;		  
	int T;  
	int E;  
  
private:  
};  
  
#endif  
  

And the cpp file

  
  
#include "ofTDMap.h"  
  
//--------------------------------------------------------------  
ofTDMap::ofTDMap()  
{  
	menuFrame.loadImage("menu.png");  
	  
	//=======================================================  
	// Map Setup  
	//=======================================================  
	//    ([S]tart) ([R]oad) ([W]all) ([T]owerSpot) ([E]nd)	  
	S = 0;  
	R = 1;  
	W = 2;  
	T = 3;  
	E = 4;  
  
	Map = {    
	{ W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W },  
	{ W,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W },   
	{ S,R,R,R,R,R,R,R,R,R,R,R,R,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W },   
	{ W,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,R,R,R,R,R,R,R,R,R,R,T,T,T,T,T,T,W },  
	{ W,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,W },   
	{ W,T,R,R,R,R,R,R,R,R,R,R,R,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,W },   
	{ W,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,W },   
	{ W,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,W },  
	{ W,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,W },   
	{ W,T,R,T,T,T,T,T,T,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,T,T,T,T,T,T,W },   
	{ W,T,R,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W },   
	{ W,T,R,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W },  
	{ W,T,R,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W },  
	{ W,T,R,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W },   
	{ W,T,R,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W },   
	{ W,T,R,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,R,R,R,R,R,R,R,R,R,R,E },  
	{ W,T,R,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,W },  
	{ W,T,R,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,W },   
	{ W,T,R,T,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,T,T,T,T,R,T,T,T,T,T,R,T,T,T,T,T,T,T,T,T,W },  
	{ W,T,R,R,R,R,R,R,R,R,T,T,T,T,T,T,T,T,T,T,T,T,T,R,R,R,R,R,R,R,T,T,T,T,T,T,T,T,T,W },   
	{ W,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W },   
	{ W,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W },  
	{ W,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,W },   
	{ W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W },   
	{ W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W },   
	{ W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W },   
	{ W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W },   
	{ W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W },   
	{ W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W },  
	{ W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W }};	  
}  
//--------------------------------------------------------------  
void ofTDMap::update()  
{  
	//======================================================  
	// Map Update  
	//======================================================  
}  
//--------------------------------------------------------------  
void ofTDMap::draw()  
{	  
	//======================================================  
	// Map Draw  
	//======================================================  
	ofSetColor(255,255,255);  
	menuFrame.draw(0, 0);  
	  
	for(int y = 0; y < 30; y++){  
		for(int x = 0; x < 40; x++){  
			if(Map[y][x] == S || Map[y][x] == E){  
				ofSetColor(150,0,0);  
				ofRect(x * 20, y * 20, 20, 20);				  
			}  
			if(Map[y][x] == W){  
				ofSetColor(193,154,87);  
				ofRect(x * 20, y * 20, 20, 20);				  
			}  
			if(Map[y][x] == T){  
				ofSetColor(0,0,0);  
				ofRect(x * 20, y * 20, 20, 20);				  
			}  
			if(Map[y][x] == R){  
				ofSetColor(100,100,100);  
				ofRect(x * 20, y * 20, 20, 20);				  
			}				  
		}  
	}  
}  
  

Ah, I see the issue now. In c++ you can’t assign to arrays. So, you could use a literal like that if you were declaring the array, but you can’t use the literal to assign to an existing array. Since you declared the array in the header (so it’d be available to all of your functions), you now can’t assign to it with the literal.

Since, in your case, it seems really important to use a literal (since you’re using the layout of the variables in the literal as a visual representation of your map), here’s what you can do:

Keep the declaration of Map in the header just as it is. Now, in your constructor, declare a new array using the literal notation. So instead of:

Map = {{…}};

You put this:

int mapData[30][40] = {{…}};

Where the right side of that assignment is exactly your array literal with your map in it. Then, after that, we have to take the values from mapData and put them into Map. We’ll do this using memcpy, which copies data from one place to another. After you’ve declared mapData the next line should be:

memcpy(Map, mapData, sizeof(int) * 30 * 40);

That will take all of the data you’ve just put into mapData and move it over into Map, where you want it. After that your nested array will be populated correctly and the rest of your code should work.

Thanks a lot, works great now. :smiley: