Reputation: 594
I'm new at C# and I want to create a multidimensional array like this:
(source: parks.ca.gov)
But in 8x8x4 cells.
I want to store maze cells.
{
{1,1,1,0}, {1,0,0,0}, {1,1,1,1}, {1,0,0,0}, {1,1,0,1}, {1,1,0,1}, {0,1,0,0}, {1,0,0,1},
...
{0,1,1,0}, {1,0,1,0}, {0,0,1,1}, {1,0,1,0}, {1,0,0,1}, {0,1,0,1}, {1,1,1,0}, {1,1,0,1},
}
int[,,] table = new int[8,8,4]; // is this right?
table[0,0] = {0, 0, 1, 1}; // I want to fill it this way.
Upvotes: 2
Views: 3812
Reputation: 244777
With multidimensional arrays, you can either set them all at once (using basically the syntax you showed):
int[,,] table = {
{ { 1, 1, 1, 0 }, { 1, 0, 0, 0 } },
{ { 0, 1, 1, 0 }, { 1, 0, 1, 0 } }
};
or you can set the items one by one:
int[,,] table = new int[8,8,4];
table[0,0,0] = 0;
there is nothing in between. The best you could do is to write an extension method that would work something like this:
table.Set(0, 0, new int[] { 0, 0, 1, 1 });
As an alternative, you could use 2D array of arrays:
int[,][] table = {
{ new[] { 1, 1, 1, 0 }, new[] { 1, 0, 0, 0 } },
{ new[] { 0, 1, 1, 0 }, new[] { 1, 0, 1, 0 } }
};
or you could use almost the syntax you proposed:
int[,][] table = new int[8,8][];
table[0,0] = new[] { 0, 0, 1, 1 };
A disadvantage of this approach is that it doesn't force the inner arrays to be all the same length.
As proposed in comments, another option would be use a custom type like Cell
and have a 2D array of those. Doing that makes it clearer what the array actually means, table[0,0].Left
is certainly more readable than table[0,0,1]
.
If the wall can be there or not, you shouldn't use int
values 0
and 1
, you should use bool
values false
and true
. If you want to have more states, an enum
might be appropriate.
Your structure contains a lot of duplication, since bottom of a cell is the same as top of the cell below it (unless you want to have one way walls). This means the structure can get into an inconsistent state, which is often hard to debug (“The wall isn't there? But I just looked and it is there.”).
One way to avoid that would be store walls instead of cells. Instead of 8×8 cells, you would have 8×9 horizontal walls and 9×8 vertical walls. You could then have methods that would abstract this away, so you could easily look up walls of a particular cell.
Upvotes: 1
Reputation: 9201
I'm aware it does not explicitly answer the question, but in my opinion you're shooting yourself in the foot by working with 3D arrays. C# is an OO language, so it really helps if you think OO.
Instead of working with a multidimensional array representing cells for you 3d Maze (if it is really a 3d maze you want), why not create a List
of classes named Cell, each one containing their position and other stuff you need, like :
public class Cell
{
public Cell (int x, int y, int z)
{
X = x;
Y = y;
Z = z;
}
public int X { get; set; }
public int Y { get; set; }
public int Z { get; set; }
public bool IsExplored { get; set; }
}
Then you can have a simple List<Cell>
that you can iterate over.
You can also remove the x,y,z and create a Position
class.
For walls, you can create an Enum
and use bitwise operations, or store a list of Enum
. Since you're a beginner, I'd suggest you the list of enums. You would have to add this Enum in the code, and this property to the Cell
class :
public Enum WallPosition
{
Top,
Left,
Bottom,
Right
}
public List<WallPosition> walls { get; set;} //This goes into the Cell class
That way, every operation will be much much easier to do. For example, if you need to explore every cell at the column #3, you can do
foreach (Cell cell in yourCellList.Where(c => c.Y == 3))
{
cell.IsExplored = true;
}
Need to render every explored cell differently?
foreach (Cell cell in yourCellList.Where(c => c.IsExplored) { //Do stuff }
And so on.
No need for complicated for
loops with your 3 dimensions, and a simple foreach
is in my opinion far more readable than a
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
for (int k = 0; k < 4; k++)
every time you need to access your table.
The only ugly part would be to fill you list (By creating new Cell
instances), but it would still be far more readable than a huge wall of { { { 0, 1, 0, 1 }, {1, 1, 1, 0} [...]
I'd also suggest that you read an introduction to OO principles.
Upvotes: 6
Reputation: 22959
An array initializer for a 3D array would look like this:
int[,,] table = {
{ {1,1,1,0}, {1,0,0,0}, ... },
{ {0,1,1,0}, {1,0,1,0}, ... },
...
};
The first line is right. The second line won't work. The closest thing is to use a 2D array of arrays:
int[,][] table = new int[8,8][];
table[0,0] = new int[] {0, 0, 1, 1};
Like @tigrou and @Pierre-Luc Pineault suggested, it would be a lot cleaner to encapsulate each cell in an object instead of a plain array.
Consider storing the data in an external file and reading it in instead of hardcoding the 256 numbers.
Upvotes: 0