Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
136 views
in Technique[技术] by (71.8m points)

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

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 any mistakes in my code, please?

#include<iostream>
#include<cstdlib>
#include<windows.h>
int main () {
using std::cout;
using std::cin;
using std::endl;
int level ,str , skl, lck, def, res, inc, hp, spd, nr ;
char cha[10];
nr=1;
cout<< "Which character?";
cin>> cha ;
cout<< "You chose" << cha << "." << endl << "What level do you want him/her to be?";
cin>> level ;
        if (cha[6] = 'Dieck' ) {
            hp = 26;
            str = 9;
            skl = 12;
            spd = 10;
            lck = 4;
            def = 6;
            res = 1;
            while (level > 0) {

            if (rand() % 100 < 90) {
                inc=1;
                //cout<< "HP increased by" << inc ;
                hp+1;

        }
            if (rand() % 100 < 40) {
                inc=1;
            //  cout<< "Strenght/Magic increased by" << inc ;
                str+1;  
        }
            if (rand() % 100 < 40) {
                inc=1;
                //cout<< "Skill increased by" << inc ;
                skl+1;  
        }
            if (rand() % 100 < 30) {
                inc=1;
            //  cout<< "Speed increased by" << inc ;
                spd+1;  
        }
            if (rand() % 100 < 35) {
                inc=1;
                //cout<< "Luck increased by" << inc ;
                lck+1;  
        }
            if (rand() % 100 < 20) {
                inc=1;
                //cout<< "Defense increased by" << inc ;
                def+1;  
        }
            if (rand() % 100 < 15) {
                inc=1;
                //cout<< "Resistance increased by" << inc ;
                res+1;

        }
        nr+1;
        level-1;
        //cout<<"NR."<< nr << " New stats (in order) HP/STR/SKL/SPD/LCK/DEF/RES " << hp <<" "<< str <<" "<< skl <<" "<< spd <<" "<< lck <<" "<< def <<" "<< res << endl; 
        Sleep(1);

        }
        cout<< "Stats "<< "HP/STR/SKL/SPD/LCK/DEF/RES " << hp <<" "<< str <<" "<< skl <<" "<< spd <<" "<< lck <<" "<< def <<" "<< res << endl;
        return 0 ;
}

}

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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, '
');
            }
        }
    }
    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
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...