Archived

This topic is now archived and is closed to further replies.

array of enum's? C++

This topic is 5012 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

high, why cant i make an array of enums? instead i have to do: const int WALLS[10] = {15,16,17,18,19,20,21,22,23,24}; why?im guessing its because enums are constants, but obviously i can initialize each element on declaration (with const int), so why not with enums? and is there any trick around it? or am i stuck having half my tiles in enum Tiles{} and WALLS[] outside of this enum? [edited by - graveyard filla on March 23, 2004 6:48:53 PM]

Share this post


Link to post
Share on other sites
An array of enums:

enum Days { monday, tuesday, wednesday, thursday, friday, saturday, sunday };

Days day_array[] = { monday, tuesday, monday, monday };

Share this post


Link to post
Share on other sites
si-crane, i dont want an array of enums. i want a enum of arrays. errr, heres what i wanted to do:


enum Tile_Types
{
OPEN_SPACE, //0


DOOR,

PLAYER,
RED_ENEMY, //5

PURPLE_ENEMY,
BLUE_ENEMY,
YELLOW_ENEMY,

WARP_INTERSECTIONS,
CHECK_GO_NORTH, //10

CHECK_GO_SOUTH,

FOOD,
GLOWING_FOOD,

BOMB,//14


WALLS[10]; /// <------- ARRAY OF ENUMS!!!!! OR ENUM ARRAY?


//walls would be 15-25?


OPEN_CK_NORTH,
OPEN_CK_SOUTH,
OPEN_WARP,

GREY,
WHITE
};



now this doesnt work, neither does initializing WALLS[] elements. this is what i had to do


      
enum Tile_Types
{
OPEN_SPACE, //0


DOOR,

PLAYER,
RED_ENEMY, //5

PURPLE_ENEMY,
BLUE_ENEMY,
YELLOW_ENEMY,

WARP_INTERSECTIONS,
CHECK_GO_NORTH,
CHECK_GO_SOUTH,

FOOD,
GLOWING_FOOD,

BOMB,//14


//now const int walls[10] takes up 15-24


OPEN_CK_NORTH = 25,
OPEN_CK_SOUTH = 26
OPEN_WARP = 27,

GREY = 28,
WHITE = 29
};



const int WALLS[10] = {15,16,17,18,19,20,21,22,23,24}; //array of walls




basically i didnt want to write out WALLS1,WALLS2,WALLS3 a million times in my program, so i needed an array of enums. this didnt work, so i had to make a const int WALLS[] outside of my enums. i hope you better understand my problem now. thanks for any help!!


[edited by - graveyard filla on March 23, 2004 7:28:48 PM]

[edited by - graveyard filla on March 23, 2004 7:35:10 PM]

Share this post


Link to post
Share on other sites
Well, I don''t know about anyone else, but that doesn''t clarify anything for me. Can you describe what it is you want to achieve without using code samples? Code samples can only describe intent when the code actually works.
In plain english, what do want to do?

Share this post


Link to post
Share on other sites
I think I got you graveyard filla. I dont know of a way to use the array in the enum, but youve provided a way yourself (with WALLS outside the enum which should suffice.

Share this post


Link to post
Share on other sites
heh, ok well, its hard to describe in english without giving a lot of details but ill try

my pacman clone is near complete. i just finished making the level editor. anyway, up untill now i only had 2 kinds of walls. each kind of tile would be represented in an enum, called Tile_Types. so in my enum Tile_Types() (coded above), i would have

PLAYER,
ENEMY,
WALL1,
WALL2,

well, after i made the map maker, i added a whole bunch more different looking walls. so now, theres 10 types of walls. i didnt want to have to write

PLAYER,
ENEMY,
WALL1,
WALL2,
WALL3,
etc....

so i thought i would make an array inside the enum. therefore doing

PLAYER,
ENEMY,
WALLS[10]

understand? i just needed 10 constants to represent my walls. they had to be distinct numbers, because each wall is a different image. that didnt work, so instead, i left out WALLS[] in my enum. and somewhere else, i did:

const int WALLS[10] = {15,16,17,18,19,20,......};

these numbers start at 15 because in my enum Tile_Types, i get to 14, then i want to start WALLS.

im sorry if this still doesnt make sence. its really not a huge deal, my way works, but it seems hacky and i thought there was a way around this. thanks for any help

Share this post


Link to post
Share on other sites
he wants to have an enum of tile types or something. there are 10 different wall types but he doesn''t want to type WALL1, WALL2, etc into his enum definition. personally i don''t see what the big deal is, you only have to type it once. but that''s what he wants. personally i don''t think you can do it, but a question like this tends to lie at the wierd funky edge of the language definition and there may be some obscure hack to get something like this to work.

-me

Share this post


Link to post
Share on other sites
Why would you try to use an enum if you don''t want to type the names? That''s the whole point of enums; to give names to values in a type safe way.
Besides, and correct me if I''m wrong, it seems to me that the best you can achieve here is to swap the name WALL4 with WALLS[4], which doesn''t offer any typing advantages, while losing the type safety of using only enums.

Share this post


Link to post
Share on other sites
the thing is guys, is that i use these walls in collision detection, and drawing. these enums represent sprites.
so i have to do:


//where map[][] is my array of 32x32 tiles

for(int i = 0; i < 10; i++)
{
if(map[x][y] == WALL[i])
DrawIMG(wall[i],x*32,y*32)
}


if i couldnt make an array, i would never be able to do this. i do this drawing in 2 places, AND collision detection works very similaraly. like i said, i would have to be writing out WALL1,WALL2,WALL3 ETC in many places. also, if you look at my example above ^^^ wall[] is my array of wall images (surfaces). so throughout my code i match wall with WALL[i]. so not only would i have to write out WALL1, WALL2, but id id have to write out wall1,wall2, etc. this makes life hell. i hope i cleared things up... but anyway, its all good. thanks guys for the help

Share this post


Link to post
Share on other sites
I think I get what you''re saying. Try this out...


enum Tile_Types
{
OPEN_SPACE, //0


DOOR,

PLAYER,
RED_ENEMY, //5

PURPLE_ENEMY,
BLUE_ENEMY,
YELLOW_ENEMY,

WARP_INTERSECTIONS,
CHECK_GO_NORTH,
CHECK_GO_SOUTH,

FOOD,
GLOWING_FOOD,

BOMB,//14


WALLS, //15

// WALLS+1 through WALLS+9 are not used


OPEN_CK_NORTH = 25,// Only one label is needed

OPEN_CK_SOUTH, // All others will increment as expected

OPEN_WARP,

GREY,
WHITE
};


Then, to specify a type of wall, use the expression WALLS+offset.

Ex.

if (map[x][y] == WALLS+0) ...

Share this post


Link to post
Share on other sites
Ahh, I see now. Well, I can suggest an alternative that will speed things up a little.
Try declaring your enum like this:

enum Tile_Types{
OPEN_SPACE, //0

DOOR,
PLAYER,
RED_ENEMY, //5

PURPLE_ENEMY,
BLUE_ENEMY,
YELLOW_ENEMY,
WARP_INTERSECTIONS,
CHECK_GO_NORTH,
CHECK_GO_SOUTH,
FOOD,
GLOWING_FOOD,
BOMB,
OPEN_CK_NORTH,
OPEN_CK_SOUTH,
OPEN_WARP,
GREY,
WHITE,
WALL1 = 128,
WALL2,
WALL3
//etc, but only walls after this point

};


Then, when you need to check to see if a given tile is a WALLx, you can just check a single bit, like this:

if( map[x][y] && 128 )
{
// tile is a WALL
}




[edited by - Plasmadog on March 23, 2004 11:18:44 PM]

Share this post


Link to post
Share on other sites
Here is one way to use an enum and a loop:

enum Tile_Types
{
OPEN_SPACE,
//...
WALL_FIRST = 15,
WALL_1 = WALL_FIRST,
WALL_2,
WALL_3,
//...
WALL_10,
WALL_LAST = WALL_10
//...
};

//...

for(int wall_id = WALL_FIRST; wall_id <= WALL_LAST; ++wall_id)
{
if(map[x][y] == wall_id)
DrawIMG(wall_id,x*32,y*32);
}

However, if you may add more wall types in the future, this is a poor solution, since you''ll have to recompile every time you add another type of wall. Why not give the wall tiles more info, eg. a single enum value WALL, as well as a wall tile index, so you can look up the appropriate tile image in an array, perhaps loaded from files named WALL_xx.png, or something similar.

Share this post


Link to post
Share on other sites
You might consider using bit-flags and preprcesor declarations instead. look at the responds to the first post in this thread of mine:

http://www.gamedev.net/community/forums/topic.asp?topic_id=215247

Share this post


Link to post
Share on other sites
quote:
Original post by Plasmadog

Then, when you need to check to see if a given tile is a WALLx, you can just check a single bit, like this:

if( map[x][y] && 128 )
{
// tile is a WALL
}




[edited by - Plasmadog on March 23, 2004 11:18:44 PM]



ive never worked with bit flags, or bits or whatever. to be honest, i dont even have a clue on what the hell a bit flag is or how to "bit shift" or any of that stuff. maybe someone could give me a brief explanation? your example reads to me as " if map[x][y] is true AND 128 is true) so reallly that doenst make sence to me. thanks for any help guys and ill check out that thread ^

Share this post


Link to post
Share on other sites
quote:
Original post by graveyard filla
ive never worked with bit flags, or bits or whatever. to be honest, i dont even have a clue on what the hell a bit flag is or how to "bit shift" or any of that stuff. maybe someone could give me a brief explanation? your example reads to me as " if map[x][y] is true AND 128 is true) so reallly that doenst make sence to me. thanks for any help guys and ill check out that thread ^



Sorry, that should have been & instead of &&. The first is a bitwise AND, the second is a logical AND. Your interpretation is quite correct, but it's not what I intended. My bad.
I could explain what it does and how it works, but first a question: what do you know about binary, and how numbers are represented in binary?

[edited by - Plasmadog on March 24, 2004 5:35:13 PM]

Share this post


Link to post
Share on other sites
I''m not sure about your specific situation, but it seems to me that if you''re going to be adding many more walls etc. in the future, you may want to redesign the "enum" idea now to something more dynamic (perhaps loaded at runtime from a resource file?). It really does depend on what you are going to do with this in the long run though

Share this post


Link to post
Share on other sites
quote:
Original post by Plasmadog
quote:
Original post by graveyard filla
ive never worked with bit flags, or bits or whatever. to be honest, i dont even have a clue on what the hell a bit flag is or how to "bit shift" or any of that stuff. maybe someone could give me a brief explanation? your example reads to me as " if map[x][y] is true AND 128 is true) so reallly that doenst make sence to me. thanks for any help guys and ill check out that thread ^



Sorry, that should have been & instead of &&. The first is a bitwise AND, the second is a logical AND. Your interpretation is quite correct, but it''s not what I intended. My bad.
I could explain what it does and how it works, but first a question: what do you know about binary, and how numbers are represented in binary?

[edited by - Plasmadog on March 24, 2004 5:35:13 PM]



hey, thanks for your help.
what i know about binary, is limited. i mean, i know that a bit is a single 1 or 0 and a byte is 8 binary digits. i know that you can only get numbers 0-256 with binary, and i also know how to convert numbers from decimal to binary example 00000000 is 0 1111111 is 256? and 00000010 is 2, etc. thanks for any help!

Share this post


Link to post
Share on other sites
OK, that's mostly right. Actually, an eight-bit byte can store 256 possible values, which is 0-255. An int with a value of 128 will be 10000000 in binary (in fact, an int is usually two bytes, but we can ignore that for now). In the enum declaration I listed earlier, I set WALL1 to 128, and the following WALL items would continue from there, 129, 130, 131, etc. In binary, they would look like this:
WALL1 -> 128 -> 10000000
WALL2 -> 129 -> 10000001
WALL3 -> 130 -> 10000010
WALL4 -> 131 -> 10000011
and so on. In fact, that first bit will be unchanged until it gets to 256 (which would be 00000001 00000000).
This statement:
foo & 128
takes the value of foo and does a bitwise AND with the constant value 128.
The AND operation takes two inputs and produces one output. The result table is like this:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
So, only when both inputs are true is the output true. A bitwise operation looks at each bit of the inputs one at a time, and produces the output one bit at a time. So, if foo has a value of, say, 131 (a WALL4), the operation looks like this:

131 10000011
& 128 10000000
----------------
result 10000000

The result is what it is because only in the first bit is there a true value in both inputs. Because this result is a non-zero value, it is considered to be a true result for the purposes of an if statement. So effectively, by saying:
if( foo & 128 )
you are simply checking to see if the eighth bit is set in the value of foo. Any value between 128 and 255 will have that bit set, so unless you have more than 127 different types of WALL, that should do the job.

Does that make any sense?

[edited by - Plasmadog on March 24, 2004 10:05:59 PM]

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites
quote:
Original post by AndyTX
I''m not sure about your specific situation, but it seems to me that if you''re going to be adding many more walls etc. in the future, you may want to redesign the "enum" idea now to something more dynamic (perhaps loaded at runtime from a resource file?). It really does depend on what you are going to do with this in the long run though



thats true. i do plan on re-using this code in my next games (this is a pretty decent tile based engine) . also, adding more walls is kind of a hassle, well, i have to change the code a bunch of different places, where as good-designed code should only have to be changed in one spot (at least IMO). so does anyone have any other suggestions? i dunno, man.

plasma- thanks for the lesson, im gunna keep re-reading your post untill it sinks in

Share this post


Link to post
Share on other sites
actually, i pretty much made it nice to work with. i just seperate Tile_Types{} from Walls[] completely. also i use a const value called MAX_WALLS. so really, if i want to add more walls, its not such a hassle. i just incease the value of MAX_WALLS and of course i have to hard-code the loading in of the images. but i would have to do that regardless. thanks for your guys help

Share this post


Link to post
Share on other sites
Here's the way I did my tile engine, if you're interested. You just tell your editor how many parts your tile should have, then have it automatically allocate enough "cells" to hold all of the tile's parts. Walls would be no different than floors. Each "cell" could have it's own properties (such as if drawn after objects). Anyway, this is how I have mine set up:
struct KTileCmp // "Cell"

{
LONG Img; // Image Index

LONG x,y; // Drawing Offset from tile origin

ULONG Flags; // Flags *like this comment?*

};

struct KTile // Actual Tile

{
KTileCmp *Cmp; // Tile Components in Drawing Order

LONG nCmp; // Number of Components allocated

LONG Ofy; // Main Tile Offset

LONG HMap; // Height Map Index

LONG Mat; // Material of the floor only

ULONG Flags; // Bitflags for Tile

};
Here's a snapshot of the editor. The image is kind of big.

[edited by - Jiia on March 26, 2004 5:13:30 AM]

Share this post


Link to post
Share on other sites