Why is this code not working correctly?

I'm trying to get an XP system working and for testing I want to be able to either set the players level, or give them XP and they will level up that way, so for example if they need 1 xp to level up, and I give them 40 XP, then they will automatically be at level 40, and this somewhat works however as I have it now, the max xp I can give to get to level 100 is 30,000, however if i give the player 29999 xp, they are still at level 100, why is that? I cant seem to figure out why that is. I posted the main snipped of where the issues are, but the project has too many lines of code to post entirely, but you can download the VS 2019 project here: http://www.mediafire.com/file/bfdcv8tqru9j3z1/Monster_Fight.7z/file

or just the source files here: http://www.mediafire.com/file/mlzl6yts1t49mdw/Monster_Fight_Source_Files.7z/file

I ran through it with the debugger, but I still cant seem to figure out what's going on. Its a logical error somewhere and i cant seem to figure out where.

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
// This is an independent project of an individual developer. Dear PVS-Studio, please check it.

// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
#include "Player.h"

void Player::GiveExperience(int amount)
{
    if (amount <= mMaxLevel * xpMultiplier) //Max level is 100, and xpMultiplier is set to 300
    {
        mExperience += amount;
    }
    else
    {
        mExperience = mMaxLevel * xpMultiplier; //Set to max experience if its higher than the max.
    }
}

void Player::LevelUp()
{
    if (mCurrentLevel >= mMaxLevel)
    {
        mCurrentLevel = mMaxLevel;
        cout << "Max Level Reached." << endl;
    }
    else if (mExperience >= CalculateExperience())
    {
        while (mExperience > CalculateExperience())
        {
            mCurrentLevel++;
        }
    }
}

int Player::CalculateExperience()
{
    return xpMultiplier * mCurrentLevel;
}

void Player::SetLevel(int setLevelTo)
{
    mCurrentLevel = setLevelTo;
}

void Player::TestLevelUp()
{
    Player test;
    test.SetLevel(1);

    int choice{ 0 };
    int amount{ 0 };

    while (choice != -1)
    {
        cout << "Type -1 to end testing" << endl;
        cout << "Give How much XP?" << endl;
        cout << ">";
        cin >> amount;

        if (cin.fail())
        {
            cout << "Invalid integral type entered." << endl;

            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }
        else
        {
            //Apply amount entered above
            test.LevelUp();
            test.GiveExperience(amount);

            while (choice != -1)
            {
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(), '\n');

                cout << "\nCurrent Experience: " << test.GetCurrentExperience() << "/" << test.CalculateExperience() << endl;
                cout << "Current Level: " << test.GetLevel() << endl;
                cout << "Give " << amount << " XP" << endl;
                test.GiveExperience(amount);
                cout << "Try Level Up" << endl;
                test.LevelUp();

                cin >> choice;
            }
        }
    }
}
GiveExperience:
Lets say that mExperience == amount == mMaxLevel * xpMultiplier
Therefore, amount <= mMaxLevel * xpMultiplier
and after function
mExperience == 2 * mMaxLevel * xpMultiplier

Don't you want to enforce mExperience <= mMaxLevel * xpMultiplier?


The first amount you apply:
1
2
            test.LevelUp();
            test.GiveExperience(amount);

All further amounts you apply:
1
2
            test.GiveExperience(amount);
            test.LevelUp();

Why the difference?


SetLevel:
You only set the level. Is it on purpose? Do you want that you can start a character at level N, but it has to collect same amount of experience as level 0 to reach level N+1?
Oops, the two functions not being in order was an accident, I fixed it. As for set level, its just there so i can set level to whatever i want for testing purposes, I just set it to 1 for this specific test.

Doing these kinds of checks in code really confuses me, its hard for me to follow for some reason even when the logic is perfect, i dont know why.

I still cant seem to get it to work, it still sets player to level 100 when i have 29,999 xp.
Last edited on
That question ...

Lets have
1
2
3
4
5
6
mCurrentLevel = 99;
mExperience = 29'999;
mCurrentLevel * xpMultiplier == 99 * 300 == 29'700

while (mExperience > CalculateExperience() ) // Yes, 29'999 > 29'700
 ++mCurrentLevel;

Yes, you get level 100, because you have more tha 29'700.

On the other hand:
mExperience / xpMultiplier == 29'999 / 300 == 99
You can thus calculate level from experience without a loop (because each level requires 300 exp).
Thank you, I got it working correctly now.

One more question. Now this code sets the experience and level to 30,000 and 100 respectively, but I was thinking maybe a better system would be to get the overflow and find a way to subtract from it to add the right amount of max level or max xp.

so for example if the players current level was 43 and i added 256 levels, the code would do:

mCurrentLevel = 256 - (100 - 43) + 143); //which is 56, then add 1?

Not sure that math is 100% correct, its missing 1 level but something like that. It took me longer than i'd like to admit just to come up with that formula.
I'm not sure if that way is better or if just setting it to the max level if it goes over is better or if it doesn't matter at all and is dependent upon what i need.
Last edited on
Topic archived. No new replies allowed.