unityscript 中列表和循环的逻辑问题

Logic issue with lists and loops in unityscript

我有 3 个列表:ListOfBoxesListOfGoalsListOfDoned

前 2 个列表包含转换,第 3 个是空的。

ListOfBoxes x 和 z 位置的框与 ListOfGoals 中的目标相同时,我将该框移动到 ListOfDoned

接下来我想要发生的是;如果 ListOfDoned 中的一个盒子不再位于 ListOfGoals 中的目标,则移回 ListOfBoxes

这是我的代码:

for(var n = 0; n < ListOfGoals.Count; n++)
{
   for (var p = 0; p < ListOfBoxes.Count; p++)
   {
     if (Mathf.Abs(ListOfBoxes[p].position.x - ListOfGoals[n].position.x) < epsilon)
     {
         if (Mathf.Abs(ListOfBoxes[p].position.z - ListOfGoals[n].position.z) < epsilon)
         {
         Debug.Log("Box" + p + " has been placed at " + n);
         ListOfDoned.Add(ListOfBoxes[p]);
         ListOfBoxes.RemoveAt (p);
         break;
         }
     }
    } 
}

for (var q = 0; q < ListOfDoned.Count; q++)
{
    for (r = 0; r < ListOfGoals.Count; r++)
    {
     if (Mathf.Abs(ListOfDoned[q].position.x - ListOfGoals[r].position.x) < epsilon)
     {
         if (Mathf.Abs(ListOfDoned[q].position.z - ListOfGoals[r].position.z) < epsilon)
         {
             break;
         }
         else
         {
            if (r == ListOfGoals.Count)
            {
            ListOfBoxes.Add(ListOfDoned[q]);
            ListOfDoned.RemoveAt (q);
            }

         }
     }
    }
}

我可以看到正在发生的事情是它正在检查列表中的所有目标,而不是在找到一个目标后退出,但我不确定正确的逻辑是什么。

提前致谢。

[编辑以尝试增加清晰度] - 假设我在 ListOfBoxes 中有 2 个框,在 listofgoals 中有 2 个目标。当 1 个框移动到与其中一个目标相同的位置时(只有 x 和 z 轴,不是 y),我希望将该框从 ListOfBoxes 删除到 ListOfDoned。这是第一个嵌套的 for 循环,它似乎工作正常。但是,如果该框后来从与这些目标之一相同的位置移动,我需要在 ListOfBoxes 中将其放回原处。这就是我希望第二个嵌套 for 循环执行的操作。

似乎正在发生的是,它正在将 listOfDoned 中的框与 listofgoals 中的所有目标进行比较,并且(即使它与其中一个目标具有相同的位置)它与另一个位置不相同,所以在 else 情况下将框放入列表 listofboxes.

我需要检查所有目标的位置,只要它的位置与其中一个相同,什么都不做,否则return listOfBoxes.

[编辑:这个答案解决了我认为是您的代码中的问题,但我不认为它修复了您在评论中描述的行为。让我修改这个等待更多的澄清。]

我认为您描述的问题是由于您在第二个嵌套循环中的 if 语句造成的:

if (r == ListOfGoals.Count)
{
    ListOfBoxes.Add(ListOfDoned[q]);
    ListOfDoned.RemoveAt (q);
}

您需要记住,只有当您在 for 循环中指定的条件为真时,循环的内容才会执行。在这种情况下,即

r < ListOfGoals.Count

这意味着您的 if 条件 r == ListOfGoals.Count 永远不会发生,因为循环将在 r 达到 ListOfGoals.Count 之前终止。由于条件永远不会评估为 true,因此项目永远不会从 ListOfDoned 移动到 ListOfBoxes,即使它们应该是。

要解决此问题,我建议将您的 if 语句更改为:

if (r == ListOfGoals.Count - 1)
{
    ListOfBoxes.Add(ListOfDoned[q]);
    ListOfDoned.RemoveAt (q);
}

这将对应于循环的最后一次执行。希望这可以帮助!如果您有任何问题,请告诉我。

感谢推特上的 PipsqueakGames 帮助我找到这个解决方案。

for(var n = 0; n < ListOfGoals.Count; n++)
{
   for (var p = 0; p < ListOfBoxes.Count; p++)
   {
     if (Mathf.Abs(ListOfBoxes[p].position.x - ListOfGoals[n].position.x) < epsilon)
     {
         if (Mathf.Abs(ListOfBoxes[p].position.z - ListOfGoals[n].position.z) < epsilon)
         {
         Debug.Log("Box" + p + " has been placed at " + n);
         ListOfDoned.Add(ListOfBoxes[p]);
         ListOfBoxes.RemoveAt (p);
         break;
         }
     }
    } 
}

for (q = 0; q < ListOfDoned.Count; q++)
{
    var matched:boolean = false;
    for (r = 0; r < ListOfGoals.Count; r++)
    {
        if (Mathf.Abs(ListOfDoned[q].position.x - ListOfGoals[r].position.x) < epsilon)
        {
            if (Mathf.Abs(ListOfDoned[q].position.z - ListOfGoals[r].position.z) < epsilon)
            {
                matched = true;
                Debug.Log("Box" + q + " is still at " + r);
                break;
            }
        }
    }
    if (!matched)
    {
        ListOfBoxes.Add(ListOfDoned[q]);
        ListOfDoned.RemoveAt (q);
    }
}