My program loops forever and does only a half of what I told it to do

后端 未结 4 994
别那么骄傲
别那么骄傲 2020-12-07 06:28

I\'m new to programming and I started to make my own Fire Emblem level up calculator, but for some reason it loops infinitely. I can\'t find an answer. Could you look for an

相关标签:
4条回答
  • 2020-12-07 06:52

    You have two major problems which may cause compilation error.

    nr+1;
    level-1;
    

    You have to assign them into some variable. Try this:

    nr = nr+1;
    

    or

    nr++;
    

    and

    level = level -1;
    

    or

    level--;
    

    now the while loop is not going to loop infinite.

    Second problem is

    if (cha[6] = 'Dieck' )
    

    Note that, = is an assignment operator, not an equal operator. Equal operator looks like double equal ==. As you want to compare whether cha is equal to Dieck or not, try this:

    if (strcmp (cha, "Dieck") == 0)
    

    But you need to include #include<cstring> for that.

    Reference here.

    0 讨论(0)
  • 2020-12-07 06:54

    level-1; computes the value of level-1 and then throws it away, doing essentially nothing. As such, the value in level is never updated and you're stuck with an infinite loop (you are also doing this with all of your variable updates, be careful!)

    If you want to decrement the value of level (reduce it by one), you can do any of the following:

    level = level - 1;
    level -= 1;
    level--;
    

    Furthermore, if(cha[6] = 'Dieck') is not correct on several fronts. You could perhaps do

    if(strcmp(cha, "Dieck") == 0) { //...
    

    If you make sure to #include <cstring>

    0 讨论(0)
  • 2020-12-07 06:57

    One issue you have is cha[6] = 'Dieck'

    cha[6] is a single character such as 'D' or 'i' but not the whole thing. Also = sets cha[6] equal to 'Dieck' which can't happen because 'Dieck' is not a valid character. To compare them you'd need == but you can only compare one character at a time like cha[0] == 'D'

    Really you should make your input a string, and use the compare() method of the string.

    std::string input;
    // stuff
    cin >> input;
    
    if (input.compare("Dieck") == 0)
    {
       // more stuff
    }
    
    0 讨论(0)
  • 2020-12-07 07:02

    2011 version

    std::strings, std::binds initializer lists, modern random number generators, auto variable typing. Shucks, even a few oldies-but-goodies like classes and error checking the input.

    #include <iostream>
    #include <random>
    #include <functional>
    #include <map>
    
    // prep random number generator to simulate a 100 sided die
    std::default_random_engine engine; // not being fancy here. Just using default RNG
    std::uniform_int_distribution<int> uniform(1,100);// random from 1 to 100
    auto d100 = std::bind ( uniform, engine ); // Convenience wrapper
    
    void upstat(int & stat, // stat to increase
                int chance, // odds of increase
                int inc, // amount to increase
                const std::string & statname)
    {
        if (d100() <= chance)
        { //less than or equal because I decided to emulate a d100.
          // if the range was 0 - 99, only < would be necessary.
          // such is the cost of slavishly adhering to dice conventions.
    //        std::cout<< statname << " increased by " << inc << std::endl;
            stat += inc;
        }
    }
    
    class Character
    {
    public:
        Character(const std::string & name,
                  int level,
                  int HP,
                  int str,
                  int skl,
                  int spd,
                  int lck,
                  int def,
                  int res):
                      mName(name), mLevel(level), mStr(str), mSkl(skl), mLck(lck),
                      mDef(def), mRes(res), mHP(HP), mSpd(spd)
        {
    
        }
    
        void levelup()
        {
            upstat(mHP, 90, 1, "HP");
            upstat(mStr, 40, 1, "Strength/Magic");
            upstat(mSkl, 40, 1, "Skill");
            upstat(mSpd, 30, 1, "Speed");
            upstat(mLck, 35, 1, "Luck");
            upstat(mDef, 20, 1, "Defense");
            upstat(mRes, 15, 1, "Resistance");
            mLevel++;
        }
    
        // a couple useful getters
        const std::string & getName()
        {
            return mName;
        }
        unsigned int getLevel()
        {
            return mLevel;
        }
    
        // out stream operator
        friend std::ostream & operator<<(std::ostream & out,
                                         const Character & ch)
        {
            out << "Stats " << "HP/STR/SKL/SPD/LCK/DEF/RES " <<
                    ch.mHP << " " <<
                    ch.mStr << " " <<
                    ch.mSkl << " " <<
                    ch.mSpd << " " <<
                    ch.mLck << " " <<
                    ch.mDef << " " <<
                    ch.mRes << std::endl;
            return out;
        }
    
    private:
        std::string mName;
        unsigned int mLevel;
        int mStr;
        int mSkl;
        int mLck;
        int mDef;
        int mRes;
        int mHP;
        int mSpd;
    };
    
    // name-indexed list of characters. Currently only contains Dieck.
    std::map<std::string, Character> charlist{{"Dieck",{"Dieck",1, 26, 9, 12, 10, 4, 6, 1}}};
    
    int main()
    {
        unsigned int finalLevel;
        std::string cha; // using a string rather than a char array. Much less error prone.
        std::cout << "Which character?" <<std::endl;
        std::cin >> cha;
        auto found = charlist.find(cha); // look in charlist for selected character
        if (found != charlist.end()) // find returns end of list if not found
        {
            std::cout << "You chose " << found->second.getName() << "." << std::endl <<
                         found->second << std::endl; //optional. Print stats
            for ( ; ; ) // Stay a while. Stay FOREVER! Muhuhahahahaha!
            {
                std::cout << "What level do you want him/her to be?" << std::endl;
                if (std::cin >> finalLevel)
                {
                    while (found->second.getLevel() < finalLevel)
                    { // keep calling characer's level up routine until desired level reached
                      // or do nothing if the character is already a higher level.   
                        found->second.levelup();
                    }
                    std::cout << found->second << std::endl; //optional. Print new stats
                    break; // breaks the infinite loop if input was good
                }
                else
                { // bad user input. Call user names until they get it right.
                    std::cout << "Valid positive numbers only, please." << std::endl;
                    std::cin.clear();
                    std::cin.ignore(INT_MAX, '\n');
                }
            }
        }
        else
        { // didn't find character. Do nothing.
          // Should probably prompt to create new character here.
            std::cout << "Character " << cha << " not found." << std::endl;
        }
        return 0;
    }
    

    2020 Rethink

    Doesn't change much, but replaces std::bind with a Lambda expression.

    std::default_random_engine engine; 
    std::uniform_int_distribution<int> uniform(1,100);
    auto d100 = std::bind ( uniform, engine ); 
    

    is replaced with

    auto d100 = [](){
        // all bundled up inside the lambda. No globals leaking out
        static std::mt19937 gen{std::random_device{}()}; 
        // explicitly specified the generator. Fewer surprises.
        // this can be expensive, so it might be worth exposing gen and sharing it with 
        // other die-rolling lamdas
    
        static std::uniform_int_distribution<int> uniform(1,100); // random from 1 to 100
    
        return uniform(gen); // return result
    };
    
    0 讨论(0)
提交回复
热议问题