仅将非重复值添加到列表的循环?

时间:2019-02-02 21:16:09

标签: c# unity3d

编辑:OP在这里,它的答案。 2天不能接受我自己的答案吗?邓诺我是堆栈菜鸟。感谢帮助的人。

我想有产生一个随机坐标并将其添加到列表,只有当该坐标并不在列表中已经存在一个循环。

并不断循环直到列表中的坐标数正确为止。

    while (spawnPositions.Count < myPlayer.myPlayerUnits.Count)
    {
        Debug.Log("While");
        int[,] rnd = new int[UnityEngine.Random.Range(minX, maxX), UnityEngine.Random.Range(minZ, maxZ)];

        if (spawnPositions.Contains(rnd) == false)
        {
            Debug.Log("SpawnPos Added!");
            spawnPositions.Add(rnd);
        }
    }

问题是if语句始终为true。控制台输出显示循环X次,而if语句也为X次。

在while循环中这样做是不可能的吗?还是我做错了什么?谢谢!

编辑:哦,要清楚,是添加重复项。我正在尝试在3x3区域上生成5个唯一坐标,并且几乎总是重复!

2 个答案:

答案 0 :(得分:0)

如果我理解正确,那么您想比较多维数组的内容或仅比较它们的维数。但是.Contains()方法会查找引用相等,并且这始终是唯一的,因为您正在调用“ new”。 我定义了一个扩展方法。

    public static bool IsContentEqualTo(this int[,] array1, int[,] array2)
    {
        if (array1 == null) throw new ArgumentNullException(nameof(array1), "Array cannot be null");
        if (array2 == null) throw new ArgumentNullException(nameof(array2), "Array cannot be null");
        if (array1.GetLowerBound(0) != array2.GetLowerBound(0)) return false;
        if (array1.GetUpperBound(0) != array2.GetUpperBound(0)) return false;
        if (array1.GetLowerBound(1) != array2.GetLowerBound(1)) return false;
        if (array1.GetUpperBound(1) != array2.GetUpperBound(1)) return false;

        var xMin = array1.GetLowerBound(0);
        var xMax = array1.GetUpperBound(0);
        var yMin = array1.GetLowerBound(1);
        var yMax = array1.GetUpperBound(1);
        for (var x = xMin; x <= xMax; x++)
            for (var y = yMin; y <= yMax; y++)
            {
                if (array1[x, y] != array2[x, y]) return false;
            }

        return true;
    }

您可以这样称呼它。

    if (!spawnPositions.Any(array => array.IsContentEqualTo(rnd)))
    {
        Debug.Log("SpawnPos Added!");
        spawnPositions.Add(rnd);
    }

答案 1 :(得分:0)

编辑:OP在这里,它的答案。 2天不能接受我自己的答案吗?邓诺我是堆栈菜鸟。感谢帮助的人。

我修复了它,虽然不漂亮,但是可以工作。一个布尔数组,用于跟踪该值是否已被使用。而不是从while循环内实际从列表中添加/删除列表中的值(有一些无限循环正在尝试:S)。

    bool[,] tileOccupied = new bool[maxX, maxZ];

    for (int i = 0; i < myPlayer.myPlayerUnits.Count; i++)
    {
        int tileValue = UnityEngine.Random.Range(0, myPlayer.mySpawnArea.Count);
        int[,] spawnTile = myPlayer.mySpawnArea[tileValue];

        if (tileOccupied[spawnTile.GetLength(0), spawnTile.GetLength(1)] == true)
        {
            do
            {
                tileValue = UnityEngine.Random.Range(0, myPlayer.mySpawnArea.Count - 1);
                spawnTile = myPlayer.mySpawnArea[tileValue];
            } while (tileOccupied[spawnTile.GetLength(0), spawnTile.GetLength(1)] == true);
        }
        tileOccupied[spawnTile.GetLength(0), spawnTile.GetLength(1)] = true;
        spawnPositions.Add(spawnTile);
    }