C# 通过0';s和1';s

C# 通过0';s和1';s,c#,multidimensional-array,int,2d-games,C#,Multidimensional Array,Int,2d Games,草书文本:旧条目 普通文本:最新条目 好的,我有一个整数的2D数组,更具体地说,是0和1。 最初这是一个BMP文件(黑白),我把它转换成一个整数数组。 现在,矩阵表示一张地图,其中0是我可以站立的地方(如果你愿意的话是地板),1是深渊或墙(你不能站在1中)。 所以我需要遍历这个int的随机数组,但是我需要能够遍历映射的所有0。 如果我多次访问一个“像素”,这并不重要 这有什么意义?我有一个方法可以“隐藏”地图中的4个关键点,我的角色必须在地图中找到它们。 我的角色只能上下左右移动。对角线运动是不

草书文本:旧条目

普通文本:最新条目

好的,我有一个整数的2D数组,更具体地说,是0和1。 最初这是一个BMP文件(黑白),我把它转换成一个整数数组。 现在,矩阵表示一张地图,其中0是我可以站立的地方(如果你愿意的话是地板),1是深渊或墙(你不能站在1中)。 所以我需要遍历这个int的随机数组,但是我需要能够遍历映射的所有0。 如果我多次访问一个“像素”,这并不重要 这有什么意义?我有一个方法可以“隐藏”地图中的4个关键点,我的角色必须在地图中找到它们。 我的角色只能上下左右移动。对角线运动是不允许的,很明显,心灵运输也是不允许的。 到目前为止,我有以下代码:

    public void goThrough(int[,] map, int[] pos, bool[,] visited)
    {
        int x = pos[0];
        int y = pos[1];
        visited[x, y] = true;
        Console.WriteLine("Position -> Column: {0} || Row: {1}", x, y);
        // ShowAtPosition(x, y)
        if (y > 0 && map[x, y - 1] == 0 && !visited[x, y - 1])
        {
            goThrough(map, new[] { x, y + 1 },visited); // north
            // ShowAtPosition(x, y)
        }
        if (x < map.GetLength(0) - 1 && map[x + 1, y] == 0 && !visited[x + 1, y])
        {
            goThrough(map, new[] { x + 1, y }, visited); // east
            // ShowAtPosition(x, y)
        }
        if (y < map.GetLength(1) - 1 && map[x, y + 1] == 0 && !visited[x, y + 1])
        {
            goThrough(map, new[] { x, y - 1 }, visited); // south
            // ShowAtPosition(x, y)
        }
        if (x > 0 && map[x - 1, y] == 0 && !visited[x - 1, y])
        {
            goThrough(map, new[] { x - 1, y }, visited); // west
            // ShowAtPosition(x, y)
        }
        if (NoZeros(visited)) { Console.WriteLine("I went through everything!"); Console.ReadLine(); }


    }
因此,首先,这个方法没有通过所有的迷宫,甚至没有关闭(是的,0都是连接的)

其次,在最后一次迭代(输出的最后2行)中,浏览器从(25,30)远程传输到(1,30)

顺便说一下,这是图像:


起初,听起来你只是在寻找一个合适的人选;类似于左侧的墙跟随器

但是,您并不是在寻找走出迷宫的路径,而是要访问具有相同值的所有相邻位置。所以基本上你可以用一个


唯一的问题是,您可能有多个未连接的
0
s池(除非您的原始位图被构造为所有0都可以连接,在这种情况下,您可以确保所有密钥都可以通过将它们放在0个单元格上来访问)。因此,您可能需要从多个起点进行洪水填充,以确保覆盖所有内容。

您可以创建一个包含所有可能路径的树。每个节点表示地图中的某个点,所有子节点表示可以访问的有效点。已访问的每个点都会被标记,以便您不再尝试访问它。然后,如果执行深度优先树搜索,则可以四处走动,直到搜索完所有可能的位置。每当你遇到一个被访问的节点,你就不会再去那里了。下面将执行递归的深度优先搜索。对于大型映射,您将需要非递归解决方案,否则将得到StackOverflowException

private bool[,] visited; // needs to have same size as map
public void GoThrough(int[,] map, int[] pos) {
  int x = pos[0];
  int y = pos[1];
  visited[x, y] = true;
  // ShowAtPosition(x, y)
  if (y > 0 && map[x, y - 1] == 0 && !visited[x, y - 1]) {
    GoThrough(map, new [] {x, y - 1}); // north
    // ShowAtPosition(x, y)
  }
  if (x < map.GetLength(0) - 1 && map[x + 1, y] == 0 && !visited[x + 1, y]) {
    GoThrough(map, new [] {x + 1, y}); // east
    // ShowAtPosition(x, y)
  }
  if (y < map.GetLength(1) - 1 && map[x, y + 1] == 0 && !visited[x, y + 1]) {
    GoThrough(map, new [] {x, y + 1}); // south
    // ShowAtPosition(x, y)
  }
  if (x > 0 && map[x - 1, y] == 0 && !visited[x - 1, y]) {
    GoThrough(map, new [] {x - 1, y}); // west
    // ShowAtPosition(x, y)
  }
}
private bool[,]已访问;//需要与地图大小相同
公共空间穿越(内部[,]地图,内部[]位置){
int x=位置[0];
int y=位置[1];
访问[x,y]=真;
//显示位置(x,y)
如果(y>0&&map[x,y-1]==0&&map[x,y-1]){
GoThrough(地图,新[]{x,y-1});//北
//显示位置(x,y)
}
如果(x0&&map[x-1,y]==0&&!已访问[x-1,y]){
GoThrough(地图,新[]{x-1,y});//西部
//显示位置(x,y)
}
}
它将遍历整个地图和所有可到达的瓷砖,然后返回起点


本质上,这是马修·斯特劳布里奇(Matthew Strawbridge)提到的洪水填充算法(在我键入答案时)。

0都是相关的。总是。谢谢你的快速回复!哦,我的上帝,你们真是太棒了!我注意到洪水填充算法“关心”不再经过同一地点,但这对我来说不是问题。我可以随时查看地图的相同位置。代码中包含一些容易发现的错误,可能还包含一些其他错误。我从来没有在任何IDE中开发、编译或运行过它。你没有远程传送,但是当你从递归返回时,你没有输出任何反向移动。最后,您应该理解解决方案,而不是复制粘贴它。
Position -> Column: 1 || Row: 31
Position -> Column: 2 || Row: 31
Position -> Column: 3 || Row: 31
Position -> Column: 4 || Row: 31
Position -> Column: 5 || Row: 31
Position -> Column: 6 || Row: 31
Position -> Column: 7 || Row: 31
Position -> Column: 8 || Row: 31
Position -> Column: 9 || Row: 31
Position -> Column: 10 || Row: 31
Position -> Column: 10 || Row: 32
Position -> Column: 11 || Row: 31
Position -> Column: 12 || Row: 31
Position -> Column: 13 || Row: 31
Position -> Column: 13 || Row: 32
Position -> Column: 14 || Row: 31
Position -> Column: 15 || Row: 31
Position -> Column: 16 || Row: 31
Position -> Column: 16 || Row: 32
Position -> Column: 17 || Row: 31
Position -> Column: 18 || Row: 31
Position -> Column: 19 || Row: 31
Position -> Column: 20 || Row: 31
Position -> Column: 21 || Row: 31
Position -> Column: 22 || Row: 31
Position -> Column: 23 || Row: 31
Position -> Column: 24 || Row: 31
Position -> Column: 25 || Row: 31
Position -> Column: 25 || Row: 30
Position -> Column: 1 || Row: 30
private bool[,] visited; // needs to have same size as map
public void GoThrough(int[,] map, int[] pos) {
  int x = pos[0];
  int y = pos[1];
  visited[x, y] = true;
  // ShowAtPosition(x, y)
  if (y > 0 && map[x, y - 1] == 0 && !visited[x, y - 1]) {
    GoThrough(map, new [] {x, y - 1}); // north
    // ShowAtPosition(x, y)
  }
  if (x < map.GetLength(0) - 1 && map[x + 1, y] == 0 && !visited[x + 1, y]) {
    GoThrough(map, new [] {x + 1, y}); // east
    // ShowAtPosition(x, y)
  }
  if (y < map.GetLength(1) - 1 && map[x, y + 1] == 0 && !visited[x, y + 1]) {
    GoThrough(map, new [] {x, y + 1}); // south
    // ShowAtPosition(x, y)
  }
  if (x > 0 && map[x - 1, y] == 0 && !visited[x - 1, y]) {
    GoThrough(map, new [] {x - 1, y}); // west
    // ShowAtPosition(x, y)
  }
}