我是C#的新手,我想创建一个像这样的多维数组:
http://kids.parks.ca.gov/pages/22784/images/maze.gif
但是在8x8x4细胞中。
我想存储迷宫细胞。
{
{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.
答案 0 :(得分:5)
我知道它并没有明确地回答这个问题,但在我看来,你是通过使用3D阵列来拍摄自己的。 C#是一种OO语言,所以如果你想到OO,它确实很有用。
为什么不创建一个名为Cell的类List
,而不是使用表示单元格的多维数组3d Maze(如果它真的是一个3d迷宫),每个类都包含它们的位置和其他东西你需要,比如:
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; }
}
然后你可以拥有一个可以迭代的简单List<Cell>
。
您还可以删除x,y,z并创建Position
类。
对于墙,您可以创建Enum
并使用按位操作,或存储Enum
列表。由于你是初学者,我建议你使用枚举列表。您必须在代码中添加此枚举,并将此属性添加到Cell
类:
public Enum WallPosition
{
Top,
Left,
Bottom,
Right
}
public List<WallPosition> walls { get; set;} //This goes into the Cell class
这样,每次操作都会容易得多。例如,如果您需要探索第3列中的每个单元格,则可以执行
foreach (Cell cell in yourCellList.Where(c => c.Y == 3))
{
cell.IsExplored = true;
}
需要以不同的方式呈现每个被探索的细胞吗?
foreach (Cell cell in yourCellList.Where(c => c.IsExplored) { //Do stuff }
等等。
您的3个维度不需要复杂的for
循环,而我认为简单的foreach
比
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
for (int k = 0; k < 4; k++)
每次你需要访问你的桌子时。
唯一难看的部分就是填写你的列表(通过创建新的Cell
个实例),但它仍然比{ { { 0, 1, 0, 1 }, {1, 1, 1, 0} [...]
我还建议您阅读introduction to OO principles。
答案 1 :(得分:1)
使用多维数组,您可以一次性设置它们(基本上使用您显示的语法):
int[,,] table = {
{ { 1, 1, 1, 0 }, { 1, 0, 0, 0 } },
{ { 0, 1, 1, 0 }, { 1, 0, 1, 0 } }
};
或者您可以逐个设置项目:
int[,,] table = new int[8,8,4];
table[0,0,0] = 0;
之间没有任何东西。你能做的最好的事情是编写一个类似于这样的扩展方法:
table.Set(0, 0, new int[] { 0, 0, 1, 1 });
作为替代方案,您可以使用2D数组阵列:
int[,][] table = {
{ new[] { 1, 1, 1, 0 }, new[] { 1, 0, 0, 0 } },
{ new[] { 0, 1, 1, 0 }, new[] { 1, 0, 1, 0 } }
};
或者你几乎可以使用你提出的语法:
int[,][] table = new int[8,8][];
table[0,0] = new[] { 0, 0, 1, 1 };
这种方法的一个缺点是它不会强制内部数组的长度相同。
正如评论中所建议的那样,另一个选项是使用自定义类型,如Cell
,并有一个二维数组。这样做可以更清楚地了解数组的实际含义,table[0,0].Left
肯定比table[0,0,1]
更具可读性。
如果墙可以在那里,你不应该使用int
值0
和1
,你应该使用bool
值{{1 }和false
。如果您想拥有更多州,true
可能是合适的。
您的结构包含大量重复,因为单元格底部与其下方单元格的顶部相同(除非您想要单向墙)。这意味着结构可能会进入一个不一致的状态,这通常很难调试(“墙不在那里?但我只是看了看它 那里。”)。
避免这种情况的一种方法是存储墙而不是细胞。而不是8×8单元,你将有8×9水平墙和9×8垂直墙。然后,您可以使用方法将其抽象出去,这样您就可以轻松查找特定单元格的墙壁。
答案 2 :(得分:0)
3D阵列的数组初始值设定项如下所示:
int[,,] table = {
{ {1,1,1,0}, {1,0,0,0}, ... },
{ {0,1,1,0}, {1,0,1,0}, ... },
...
};
第一行是对的。第二行不起作用。最接近的是使用2D数组阵列:
int[,][] table = new int[8,8][];
table[0,0] = new int[] {0, 0, 1, 1};
像@tigrou和@Pierre-Luc Pineault建议的那样,将每个单元格封装在一个对象而不是普通数组中会更加清晰。
考虑将数据存储在外部文件中并将其读取,而不是对256个数字进行硬编码。