3
\$\begingroup\$

I struggle with efficiency in code, and I want to start my game off on the right foot.

I have a game that I'm making a 4 x 4 map of 'tiles' that a user can build their 'town' on. To keep track of the tiles, I'm planning on simply having a size-16 array of the type of my 'mapTile' enum. EX:

enum MapTiles { defaultTile, homeBase, farm1, farm2 /*...and so on...*/ };
static MapTiles playerMap[] = MapTiles[16] { /* ... default map setup ... */ };

Is there a way that is more efficient or more easy-to-extend way to implement such a map?

I'm using Unity and C# mostly, though i'm willing to work with any Unity-capable language if you have a clever answer.

\$\endgroup\$
0

2 Answers 2

3
\$\begingroup\$

enum is actually a good idea here, but what you want is for the enum to be:

enum MapTileBuilding { defaultTile, homeBase, farm1, farm2 /*...and so on...*/ };

and a class

class MapTile
{
   MapTileBuilding building;
   ... //other members e.g.
   //structuralStrength
   //isOnFire
   //troopCount
   //incomeGenerated
   //etc.
}

...which gives you the ability to support your initial building type property, as well as other properties you may wish to add to each tile later.

Finally, your array:

MapTile[,] map = new MapTiles[4, 4];

Do not inherit when composition will do (i.e. what you are already doing), otherwise you end up restricting yourself into narrowly-defined class hierarchies as you continue to try to extend the system. You want your tiles to be composable and inheritance is at odds with that idea. You'll begin adding new components as other concepts come into play (see examples above), and you don't want inheritance chains in your way at that point.

Re array dimensionality, the only time you will ever use a 1D array for a 2D concept is when you want precise control over memory access in low-level code (say in C or ASM), that is, in your case and in C# in general, just use the conceptually simpler 2D array.

P.S. Sorry if syntax is slightly off, C# isn't my first language these days.

\$\endgroup\$
4
  • \$\begingroup\$ Sounds alright. The only problem I see with this approach is when different tiles have different options available. Maybe in one tile you can build soldiers and in others you can trade something. You see where this is going. Differing mouseOver menus/tooltips would be easier to implement with different classes. If you want to do this with an enum you'd need long switches. But it depends on taste I'd say. \$\endgroup\$
    – LukeG
    Oct 16, 2015 at 15:16
  • 1
    \$\begingroup\$ Informative and extendable! +1 sir! You've also given me something new to research. \$\endgroup\$ Oct 16, 2015 at 15:17
  • 1
    \$\begingroup\$ @LukeG That's how Component-Based Entity Systems (CBES) work. The idea is that you support all possible properties on all entities, but don't use a given property on an entity (MapTile) that doesn't have the capacity for it. For example, on a water square, you would never use isOnFire. It leads to far greater flexibility at negligible cost. In game engines you will see that for this reason, we often have multiple "super-categories" of objects, hence why e.g. Particles are distinct from GameObjects - particles must be fast and never use most properties that a gameobject needs. Switches? No. \$\endgroup\$
    – Engineer
    Oct 16, 2015 at 15:21
  • 1
    \$\begingroup\$ Re: 2D vs 1D array. I think it also bears mentioning that there is actually a pretty significant performance difference between 1D and 2D (non-jagged) arrays in C#, with 1D arrays being significantly faster to access and write to. Now, for this particular application it likely doesn't matter and so the 2D should be preferred for clarity. I only mention this as I have certainly come up against these performance issues in real C# code and it wasn't about precisely controlling the memory access. \$\endgroup\$
    – Kyle
    Oct 16, 2015 at 19:00
3
\$\begingroup\$

Maybe enum is not the best choice in this case. You could try building a "tile" class and derive several subclasses from it (farm from your example). This way you could implement some sort of levelling system (instead of having to create a value for each level (farm1, farm2 etc)) inside the class and give the several kinds of tiles unique abilities in form of functions.

What you could also do is replacing the one-dimensional array with a two dimensional one. MapTiles[,] playerMap = new MapTiles[4, 4]

Long story short: Try to stay objectoriented and use classes, makes expansion of functionalities much easier.

\$\endgroup\$
2
  • \$\begingroup\$ I was considering an array of class objects rather than an enum. At first I couldn't wrap my head around what additional functionality that I would want that such a thing would allow me, but after seeing another person pointing that direction I am reconsidering. I think there's a lot of flexibility in that idea. I don't get the argument for a 2-d array other than making it more 'visually' clear. Does it have a functional benefit over a simple 16-slot array? \$\endgroup\$ Oct 16, 2015 at 14:33
  • \$\begingroup\$ On second thought - Considering there will be location-based constraints, i think a 2-dimensional array will make those calculations easier! \$\endgroup\$ Oct 16, 2015 at 14:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .