嵌套if ... else流的更简单/更有效的方法?

时间:2010-06-01 19:47:57

标签: c# .net

我目前正在为基于Flash客户端的游戏开发仿真服务器,该游戏有一个“宠物系统”,我想知道是否有更简单的方法来检查指定宠物的等级。

当前代码:

public int Level
{
    get
    {
        if (Expirience > 100) // Level 2
        {
            if (Expirience > 200) // Level 3
            {
                if (Expirience > 400) // Level 4 - Unsure of Goal
                {
                    if (Expirience > 600) // Level 5 - Unsure of Goal
                    {
                        if (Expirience > 1000) // Level 6
                        {
                            if (Expirience > 1300) // Level 7
                            {
                                if (Expirience > 1800) // Level 8
                                {
                                    if (Expirience > 2400) // Level 9
                                    {
                                        if (Expirience > 3200) // Level 10
                                        {
                                            if (Expirience > 4300) // Level 11
                                            {
                                                if (Expirience > 7200) // Level 12 - Unsure of Goal
                                                {
                                                    if (Expirience > 8500) // Level 13 - Unsure of Goal
                                                    {
                                                        if (Expirience > 10100) // Level 14
                                                        {
                                                            if (Expirience > 13300) // Level 15
                                                            {
                                                                if (Expirience > 17500) // Level 16
                                                                {
                                                                    if (Expirience > 23000) // Level 17
                                                                    {
                                                                        return 17; // Bored
                                                                    }
                                                                    return 16;
                                                                }
                                                                return 15;
                                                            }
                                                            return 14;
                                                        }
                                                        return 13;
                                                    }
                                                    return 12;
                                                }
                                                return 11;
                                            }
                                            return 10;
                                        }
                                        return 9;
                                    }
                                    return 8;
                                }
                                return 7;
                            }
                            return 6;
                        }
                        return 5;
                    }
                    return 4;
                }
                return 3;
            }
            return 2;
        } 
        return 1;
    }
}

是的,我知道我错过了经验,我在之前的一个功能中犯了错误,并且没有更新所有内容。

7 个答案:

答案 0 :(得分:22)

使用SortedList<int, int>并对其进行迭代,直到找到高于您要搜索的值的值。你可以使用一个简单的迭代来完成它,就像你已经接受的答案一样。或者它可以使用LINQ优雅地完成(性能成本很低):

SortedList<int, int> levels = new SortedList<int, int>
    {
        {0, 1},
        {100, 2},
        {200, 3},
        {400, 4},
        {600, 5},
    };

public int Experience;
public int Level
{
    get
    {
        return levels.Last(kvp => Experience >= kvp.Key).Value;
    }
}

请注意,存储“级别”实际上并非绝对必要,因为您可以从列表中项目的索引派生它。使用简单的List<int>代替它可能是有利的,以防止您意外错过某个级别的错误,就像您已经接受的解决方案一样。

如果你想获得更好的性能,你可以使用List.BinarySearch,但我认为额外的复杂性是不值得的,除非你有性能分析并发现这是瓶颈。

List<int> levels = new List<int> { 0, 100, 200, 400, 600 /* etc... */ };

int index = levels.BinarySearch(Experience);
int level;
if (index < 0)
{
    level = ~index;
}
else
{
    level = index + 1;
}
return level;

答案 1 :(得分:13)

int[] levelCutoffs = new int[] {0, 100, 200, 400, 600 /*...*/};

for (int level = 0; level < levelCuttoffs.size; ++level) {
    if (Experience < levelCuttofs[level])
        return level;
}
return levelCuttoffs.size;

编辑:改为使用Bradley Mountford的建议。

答案 2 :(得分:4)

@Mark的建议是合理的。您还可以颠倒评估体验以取消嵌套ifs的顺序:

if (Expirience > 23000) return 17; 
if (Expirience > 17500) return 16;
//... and so on.

但我可能只使用常规的C#数组和BinarySearch方法,它可以返回匹配项的索引或最小项的2的补码,它比您搜索的值大为:

int[] levelThresholds = new[] { 100, 200, 400, 600, 1000, ..., 23000 };

int experience = 11403;
int index = Array.BinarySearch( levelThresholds, experience );
// returns either the index, or the 2's complement of the 
// first index greater than the value being sought
int level = index < 0 ? ~index : index+1;

答案 3 :(得分:3)

基于对数函数的简单公式怎么样?

这样的东西
return Math.Floor(LinearScale * Math.Log(Expirience, LogBase));

答案 4 :(得分:2)

你将从最具包容性到最独特。如果你走向另一个方向,你不需要所有的嵌套。

if (Expirience > 23000) // Level 17
  {
    return 17; // Bored
  }
  else if (Expirience > 17500) // Level 16
  {
    return 16;
  }
  else if (Expirience > 13300) // Level 15
  {
    return 15;
  }
  ...

答案 5 :(得分:2)

我会让Mark Byers更进一步。因为有点混乱(我忘了哪个是哪个)而是制作一个

的排序列表
SortedList<UserLevel>

通过这种方式,您可以为每个级别定义更多的经验值。您还可以指定一个名称,即“Uber Elite Super Level”,甚至可以在每个级别分配一个自定义欢迎信息。

答案 6 :(得分:2)

如果经验算法可以简化为函数,则应使用函数计算,即:

return (Expirience/200); // if each level was 200 xp etc

但是你的嵌套if如果上面似乎不适用于任何函数曲线,那么?操作者:

return
 (Expirience > 23000) ? 17 :
 (Expirience > 17500) ? 16 :
 (Expirience > 13300) ? 15 : 
 .. etc ..
 (Expirience > 100) ? 2 : 1;