首先,我必须说明我在 Unity 5.3 中工作,而新的 MonoDevelop 不允许我进行调试。 Unity 崩溃了:(
所以我有一个“目标”列表,我需要根据 3 个标准对其进行排序:
- 首先应列出“事件”目标
- 然后按难度排序
- 最终随机获得相同级别的目标
这是我的代码:
public class Goal {
public int ID;
public int Level;
public bool Active;
}
...
List<Goal> goals;
goals.Sort((a, b) => {
// first chooses the Active ones (if any)
var sort = b.Active.CompareTo(a.Active);
if (sort == 0) {
// then sort by level
sort = (a.Level).CompareTo(b.Level);
// if same level, randomize. Returns -1, 0 or 1
return sort == 0 ? UnityEngine.Random.Range(-1, 2) : sort;
} else {
return sort;
}
});
当我运行这段代码时,有时我会在非事件目标之后获得一个或多个事件目标,但我不明白为什么。
最佳答案
要正确工作,排序算法不应依赖于变异 状态。解释为什么在比较值时使用随机生成器不是一个好主意 is given here .
问题可以通过两种方式解决:
选项 1:预先计算随机数
var tmp = goals.Select( g=> new {goal = g, weight = rnd.NextDouble()})
.OrderByDescending(t=>t.goal.Active) // Active first
.ThenBy(t=>t.goal.Level)
.ThenBy(t=>t.weight)
.Select(t=>t.goal)
.ToList();
goals.Clear();
goals.AddRange(tmp);
选项 2:排序然后打乱关系
Random rnd = new Random();
Comparison<Goal> comparison = (a, b) => {
// first chooses the Active ones (if any)
var sort = b.Active.CompareTo(a.Active);
if (sort == 0) {
// then sort by level
return sort = (a.Level).CompareTo(b.Level);
} else
{
return sort;
}
};
int startIndex = 0;
int endIndex = 0;
goals.Sort(comparison);
while (startIndex < goals.Count)
{
for (endIndex = startIndex + 1; endIndex < goals.Count; ++endIndex)
{
if (comparison(goals[startIndex], goals[endIndex]) != 0)
{
//End of tie
break;
}
}
if (endIndex - startIndex > 1)
{
// Shuffle goals of the same level
ShuffleRange(goals, startIndex, endIndex - startIndex, rnd);
}
startIndex = endIndex;
}
static void ShuffleRange<T>(List<T> list, int startIndex, int count, Random rnd)
{
int n = startIndex + count;
while (n > startIndex + 1)
{
int k = rnd.Next(startIndex, n--);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
Shuffle算法借鉴自here
关于c# - 我的排序有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35092917/