I have WAY to many if statements

I want to shorten the amount of if statements in my code. I am currently writing a text based adventure game in C, I am loosely basing this on my knowledge of the original D&D games by TSR. So I have the standard stats and their bonuses. What I want to do is if it is possible to remove the many lines of 'if' statements that I have.
As you can see I have many of them. I have thought of using some type of for loop that can check the score and give the bonuses accordingly without needing 5-6 if statements for each score. Any thoughts will help.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  if (STR <= 10)
                    {
                        Sword_DB = 0;
                        SwordHit_Bonus = 0;
                    }
                    if (STR >= 11 && STR <= 15)
                    {
                        Sword_DB = 2;
                        SwordHit_Bonus = 1;
                    }
                    if (STR >= 16 && STR <= 19)
                    {
                        Sword_DB = 5;
                        SwordHit_Bonus = 3;
                    }
                    if (STR >= 20)
                    {
                        Sword_DB = 8;
                        SwordHit_Bonus = 5;
                    }
                    //DEX
                    if (DEX <= 5)
                    {
                        SkillHit = -1;
                        ArmorC = 0;
                    }
                    if (DEX >= 6 && DEX <=10)
                    {
                        SkillHit = 0;
                        ArmorC = 1;
                    }
                    if (DEX >= 11 && DEX <= 14)
                    {
                        SkillHit = 1;
                        ArmorC = 4;
                    }
                    if (DEX >= 15 && DEX <= 17)
                    {
                        SkillHit = 2;
                        ArmorC = 8;
                    }
                    if (DEX >= 18 && DEX <= 19)
                    {
                        SkillHit = 4;
                        ArmorC = 10;
                    }
                    if (DEX >= 20)
                    {
                        SkillHit = 6;
                        ArmorC = 15;
                    }
                    //CON
                    if (CON <= 5)
                    {
                        HPBonus = -3;
                    }
                    if (CON >= 6 && CON <= 10)
                    {
                        HPBonus = 0;
                    }
                    if (CON >= 11 && CON <= 13)
                    {
                        HPBonus = 1;
                    }
                    if (CON >= 14 && CON <= 16)
                    {
                        HPBonus = 3;
                    }
                    if (CON >= 17 && CON <= 19)
                    {
                        HPBonus = 5;
                    }
                    if (CON >= 20)
                    {
                        HPBonus = 7;
                    }
                    //INT
                    if (INT <= 10)
                    {
                        MPBonus = -1;
                        MPDmgBonus = -1;
                    }
                    if (INT >= 11 && INT <= 13)
                    {
                        MPBonus = 0;
                        MPDmgBonus = 1;
                    }
                    if (INT >=14 && INT <= 16)
                    {
    MPBonus = 5;
    MPDmgBonus = 3;
}
if (INT >= 17 && INT <= 19)
{
    MPBonus = 8;
    MPDmgBonus = 6;
}
if (INT >= 20)
{
    MPBonus = 12;
    MPDmgBonus = 10;
}
//WIS
if (WIS <= 5)
{
    FaithMagBonus = -2;
}
if (WIS >= 6 && WIS <= 10)
{
    FaithMagBonus = 0;
}
if (WIS >= 11 && WIS <= 13)
{
    FaithMagBonus = 3;
}
if (WIS >= 14 && WIS <= 17)
{
    FaithMagBonus = 5;
}
if (WIS >= 18 && WIS <= 19)
{
    FaithMagBonus = 8;
}
if (WIS >= 20)
{
    FaithMagBonus = 12;
}
//CHA
if (CHA <= 10)
{
    CureBonus = 0;
}
if (CHA >= 11 && CHA <= 13)
{
    CureBonus = 1;
}
if (CHA >=14 && CHA <= 16)
{
    CureBonus = 3;
}
if (CHA >= 17 && CHA <= 19)
{
    CureBonus = 5;
}
if (CHA >= 20)
{
    CureBonus = 8;
}
Are you sure with numbers? I do not remember any edition which have such bonuses. Your bonus distribution cannot be expressed in short mathematic formula. So chain of if/elseif is yout best bet.
1
2
3
4
5
6
7
8
9
10
11
12
13
if (STR <= 10) {
    Sword_DB = 0;
    SwordHit_Bonus = 0;
} else if (STR <= 15)   {
    Sword_DB = 2;
    SwordHit_Bonus = 1;
} else if (STR <= 19) {
    Sword_DB = 5;
    SwordHit_Bonus = 3;
} else{
    Sword_DB = 8;
    SwordHit_Bonus = 5;
}
Or you can use fall-through switch technique:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Sword_DB = 0;
SwordHit_Bonus = 0;
checked_str = std::min(20, STR);
switch(STR) {
    case 20:
        Sword_DB += 3;
        SwordHit_Bonus += 2;
    case 19: case 18: case 17: case 16:
        Sword_DB += 3;
        SwordHit_Bonus += 2;
    case 15: case 14: case 13: case 12: case 11:
        Sword_DB += 2;
        SwordHit_Bonus += 1;
}
When you have a lot of if statements, you might want to look into a switch statements. http://www.cprogramming.com/tutorial/lesson5.html

When you do if statements testing the same variable, you should probably use else if i.e
1
2
3
4
5
6
7
8
9
10
11
12
13
int bla = 1;
if(bla == 1){
    // do stuff
}
else if (bla == 2){
    // do other stuff
}
else if (bla == 3){
    // do other stuff
}
else{
    // any other case do this stuff
}


In this case however I don't know if a switch statement is good either. Perhaps you should just try making an algorithm to determine these bonus effects.
Actually, your if statements might be just fine. You basically have several arbitrary piecewise functions -- that pretty much warrants a bunch of if statements.

The ternary operator might help you out: result = (condition) ? (true_outcome) : (false_outcome)

You might identify some patterns that would enable you to generalize, like (random example) "the hit bonus starts at zero and increases by 1 with every 3rd point of strength after 6," so:
hitbonus = str > 6 ? (str - 6) / 3 : 0 ;

You could also populate a look-up table.

But whilst that could be shorter, it isn't necessarily any clearer or easier. I'd just suggest keeping the calculations in a tidy place. Perhaps create an object CharacterSheet to manage this scorekeeping. Just make sure the calculations are the job of one specific part of your code, and don't duplicate the implementation of that functionality.
Last edited on
Topic archived. No new replies allowed.