如何检查3d数组中的空格是否为空/空

时间:2016-09-15 03:53:21

标签: c# multidimensional-array enums

我现在正在努力解决我的代码问题,我在Unity中制作它但是因为它不是Unity相关的,而是一般的编码更多,我认为把它放在这里是个更好的主意。

背景信息

无论如何,让我解释一下背景信息。我有一个名为BlockType的枚举数组,BlockType枚举包含Air或Stone。我的数组是一个3d数组,我称之为块,并且声明为blocks = new BlockType[50,50,50](注意:所有块都被初始化为空)

我也有功能,目前功能只是基本的房间,它们有一个大小,只是放置以其位置为原点的块。最后,PosDirObj只是包含位置(Vect3)和方向(Vect2,它是(1,0),(0,1),(-1,0),(0,-1))的对象。我使用它们来存储特征的位置和方向,因为放置它们后我就不需要它们了,所以没有必要把它放在特征内。

问题

无论如何,我的问题是,我试图找出房间是否适合我的阵列,这意味着在房间的每个位置,只有空气块,我还添加1块检查实际房间尺寸周围的填充,以便以后留出空间。现在它要么告诉我它是正确的,有时它不是,而且大多数时候,它告诉我它是错的,当它是正确的,我认为方向系统搞砸了,但我不知道如何解决它。 / p>

这是我的代码:

  public bool FeatureFitsInWorld (Feature feature, MathDR.PosDirObj wall)
  {
        // Get required parameters
        Vect3 pos = new Vect3(wall.position.x + Mathf.Abs(wall.direction.x),
                              wall.position.y,
                              wall.position.z + Mathf.Abs(wall.direction.y)); // Gets the position where the starting point will be (adding wall.direction.x/y because there's a padding)
        Vect3 size = feature.size; // The size the room will be
        Vector2 dir = ConvertDirToFitDir(wall.direction); // The direction, btw, this function just changes all 0s to 0.5f, Vector2s are using floats, Vect2s are using ints
        //Vect2 dir = wall.direction; //Using this for testing... Useless for now

        // Checks if the feature doesn't go out of bounds
        if (pos.x + (size.x * (int)dir.x) > worldSize.x ||
            pos.x + (size.x * (int)dir.x) < 0 ||
            pos.y + size.y > worldSize.y ||
            pos.y < 0 ||
            pos.z + (size.z * (int)dir.y) > worldSize.z ||
            pos.z + (size.z * (int)dir.y) < 0)
        {
            Debug.Log("Feature goes out of bounds! at pos " + pos + " with size " + size + " and direction " + dir);
            return false;
        }

        // Checks if all blocks are Air
        for (int x = -1; x < size.x + 1; x++)
        {
            for (int y = 0; y < size.y; y++)
            {
                for (int z = -1; z < size.z + 1; z++)
                {
                    // Checks if the block we are looking at is air,
                    // add some coordinates because else it would just search for an absolute position if the room was placed at 0,0,0, which we are not
                    if (blocks[pos.x + (int)(x * dir.x),
                               pos.y + y,
                               pos.z + (int)(z * dir.y)] != BlockType.Air)
                    {
                        Debug.Log("Found that block isn't air at " + (pos.x + (int)(x * dir.x)) + " " + (pos.y + y) + " " + (pos.z + (int)(z * dir.y)) + " ");
                        return false;
                    }

                }
            }
        }

        return true;
    }

有谁知道我的代码出了什么问题?什么似乎是问题?我现在已经两次重写这个功能,但我仍然不知道为什么它不起作用。

谢谢!

1 个答案:

答案 0 :(得分:0)

好的,能够解决这个问题,感谢Chris在PM。

以下是可能需要它的人的代码,无论如何非常感谢!

public bool FeatureFits(Feature feature, MathDR.PosDirObj wall)
    {
        // Get required parameters
        Vect3 dir = wall.direction;
        Vect3 pos = wall.position;
        Vect3 size = feature.size;

        if (dir.x == 0)
            dir.x = 1;
        if (dir.y == 0)
            dir.y = 1;
        if (dir.z == 0)
            dir.z = 1;

        int padding = 1;

        int x1 = pos.x - padding;
        int x2 = pos.x + (size.x * dir.x) + padding;

        int y1 = pos.y - padding;
        int y2 = pos.y + (size.y * dir.y) + padding;

        int z1 = pos.z - padding;
        int z2 = pos.z + (size.z * dir.z) + padding;

        // Check if outside bounds
        if (x1 < 0 ||
            x2 < 0 ||
            y1 < 0 ||
            y2 < 0 ||
            z1 < 0 ||
            z2 < 0 ||
            x1 > worldSize.x ||
            x2 > worldSize.x ||
            y1 > worldSize.y ||
            y2 > worldSize.y ||
            z1 > worldSize.z ||
            z2 > worldSize.z) {
            return false;
        }

        // Checks for every block that the feature will take + 1 padding
        for (int x = System.Math.Min(x1, x2); x <= System.Math.Max(x1, x2); x++)
        {
            for (int y = System.Math.Min(y1, y2); y <= System.Math.Max(y1, y2); y++)
            {
                for (int z = System.Math.Min(z1, z2); z <= System.Math.Max(z1, z2); z++)
                {
                    if (blocks[x, y, z] != BlockType.Air)
                    {
                        return false;
                    }
                }
            }
        }

        return true;
    }

顺便说一句,我把像dir这样的代码改为Vect3只是为了让它更灵活。