unityscript 中列表和循环的逻辑问题
Logic issue with lists and loops in unityscript
我有 3 个列表:ListOfBoxes
、ListOfGoals
和 ListOfDoned
。
前 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);
}
}
我有 3 个列表:ListOfBoxes
、ListOfGoals
和 ListOfDoned
。
前 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);
}
}