views:

49

answers:

2

What is the best way to implement a rank system:

here is the code i will use

public class MyRank
{
    private int LevelOneMaxPoints = 100;
    private int LevelTwoMinPoints = 200;
    private int LevelTwoMaxPoints = 299;
    private int LevelThreeMinPoints = 300;
    private int LevelThreeMaxPoints = 399;
    private int LevelFourMinPoints = 400;
    private int LevelFourMaxPoints = 599;
    private int LevelFourPlusMinPoints = 600;
    private int LevelFourPlusMaxPoints = 999;
    private int LevelFiveMinPoints = 1000;
    private int LevelFiveMaxPoints = 1299;
    private int LevelSixMinPoints = 1300;
    private int LevelSixMaxPoints = 2699;
    private int LevelSevenMinPoints = 2700;
    private int LevelSevenMaxPoints = 3999;
    private int LevelEightMinPoints = 4000;
    private int LevelEightMaxPoints = 5499;
    private int LevelEightPlusMinPoints = 5500;
    private int LevelEightPlusMaxPoints = 7499;
    private int LevelNineMinPoints = 7500;
    private int LevelNineMaxPoints = 9999;
    private int LevelTenMinPoints = 10000;

    private string LevelOneName = "Private";
    private string LevelTwoName = "PV2";
    private string LevelThreeName = "Private Fist Class";
    private string LevelFourName = "Specialist";
    private string LevelFourPlusName = "Corporal";
    private string LevelFiveName = "Sergeant";
    //private string LevelSixName = "Staff Sergeant";
    private string LevelSevenName = "Sergeant First Class";
    private string LevelEightName = "Master Sergeant";
    private string LevelEightPlusName = "First Sergeant";
    private string LevelNineName = "Sergeant Major";
    //private string LevelTenName = "Sergeant Major of the Answers";
    private int points = 0;

    public string RankName { get; private set; }
    public MyRank(int points)
    {
        this.points = points;
        RankName = GetRankName();
    }

    private string GetRankName()
    {
        if (points >= Int32.MinValue && points <= LevelOneMaxPoints)
            return LevelOneName;
        else if (points >= LevelTwoMinPoints && points <= LevelTwoMaxPoints)
            return LevelTwoName;
        else if (points >= LevelThreeMinPoints && points <= LevelThreeMaxPoints)
            return LevelThreeName;
        else if (points >= LevelFourMinPoints && points <= LevelFourMaxPoints)
            return LevelFourName;
        else if (points >= LevelFourPlusMinPoints && points <= LevelFourPlusMaxPoints)
            return LevelFourPlusName;
        else if (points >= LevelFiveMinPoints && points <= LevelFiveMaxPoints)
            return LevelFiveName;
        else if (points >= LevelSixMinPoints && points <= LevelSixMaxPoints)
            return LevelFiveName;
        else if (points >= LevelSevenMinPoints && points <= LevelSevenMaxPoints)
            return LevelSevenName;
        else if (points >= LevelEightMinPoints && points <= LevelEightMaxPoints)
            return LevelEightName;
        else if (points >= LevelEightPlusMinPoints && points <= LevelEightPlusMaxPoints)
            return LevelEightPlusName;
        else if (points >= LevelNineMinPoints && points <= LevelNineMaxPoints)
            return LevelNineName;
        else if (points >= LevelNineMinPoints && points <= LevelNineMaxPoints)
            return LevelNineName;
        else if (points >= LevelTenMinPoints)
            return LevelFourName;
        else
            return "No Rank";
    }
}

Do you think this is the most efficient way to do this?

+3  A: 

I would start by converting your Levels to a single enum. The value of each Enum can be the minimum value, there's no need to keep track of maximum as you'll see below.

public enum Level
{
    [Description("Private")]
    One = 0,
    [Description("PV2")]
    Two = 200,
    [Description("Private Fist Class")]
    Three = 300,
    ...
    ...
    [Description("Sergeant Major of the Answers")]
    Ten = 10000
}

Then you can write this to get the name:

string GetRankName(Level level)
{
    FieldInfo fieldInfo = level.GetType().GetField(level.ToString());
    DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
    return (attributes.Length > 0) ? attributes[0].Description : level.ToString();        
}

and this to get the Level

Level GetLevel(int points)
{
    Level level = Level.One;
    foreach(int i in Enum.GetValues(typeof(Level)))
    {
        if (points < i) break;
        level = (Level)i;
    }
    return level;
} 

then your object members would be:

public Level Level { get; set; }
public string RankName { get; set; }
public MyRank(int points)
{
    Level = GetLevel(points);
    RankName = GetRankName(Level);
}
hunter
I get a syntax error - the type or namespace "description" could not be found. Am I doing something wrong with the attributes?
Luke101
OK..I have figured it out
Luke101
Great! Does this solution seem more manageable?
hunter
Yes it does..I have it working now. it is much more manageable. Thanks alot for your help
Luke101
+1  A: 

You can use an array:

private int[] levelPoints = new int[]{
    99, 299, 399, 599, 999, 1299, 2699, 3999, 5499, 7499, 9999
};

private string[] levelNames = new string[]{
    "Private", "PV2", "Private First Class", "Specialist", "Corporal",
    "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant",
    "First Sergeant", "Sergeant Major", "Sergeant Major of the Answers"
};

private int GetMinPointsOfLevel( int level ) {
    // I think, the levels starts from 1

    if ( level <= 1 ) { return 0; }
    else if ( level >= levelPoints.Lengtht ) { return levelPoints.Last(); }
    else { return levelPoints[level - 2] + 1; }
}
private int GetMaxPointsOfLevel( int level ) {
    if ( level <= 1 ) { return levelPoints[level - 1]; }
    else if ( level >= levelPoints ) { return int.MaxValue; }
    else { return levelPoints[level - 1]; }
}
private inte GetNameOfLevel( int level ) {
    if ( level < 1 ) { return levelNames[0]; }
    else if ( level >= levelPoints - 1 ) { return levelNames.Last(); }
    else { return levelNames[level - 1]; }
}
TcKs