5
\$\begingroup\$

I wanted to see how this code looks, what can be improved and how those improvements can be implemented. I'm still new to C++ so I hope it isn't too sloppy.

#include <iostream> #include <string> #include <time.h> #include <stdio.h> #include <stdlib.h> int main() { int warrior, mage, rogue, priest; int class1, classID; int HP, mana, manaCost, attack, abilitydmg; int hpPots, manaPots, potionInv; hpPots = 0; manaPots = 0; std::string abilityname; std::cout << " --Choose a Class--\n\n" "---[1] Warrior---\n" "The warrior uses mighty attacks and has a unique stun ability.\n\n" "---[2] Mage---\n" "The mage uses the arcane arts to fire magical bolts from his fingertips.\n\n" "---[3] Rogue---\n" "The rogue uses the arts of assassination and uses a powerful backstab move.\n\n" "---[4] Priest---\n" "The priest uses the holy arts and has a heal ability.\n"; std::cin >> class1; switch(class1) { case 1: classID=1; std::cout << "\nEquipped Rusty Sword!\n" "+7 Attack!\n" "Learned Slam!\n"; attack = 7; abilitydmg = 8; abilityname = "Slam"; manaCost = 20; std::cin.get(); break; case 2: classID=2; std::cout << "\nEquipped Wooden Staff!\n" "+2 Attack\n" "Learned Arcane Bolt!\n"; attack = 2; abilitydmg = 8; abilityname = "Arcane Bolt"; manaCost = 15; std::cin.get(); break; case 3: classID=3; std::cout << "\nEquipped Broken Dagger!\n" "+5 Attack!\n" "Learned Backstab!\n"; attack = 5; abilitydmg = 30; abilityname = "Backstab"; manaCost = 50; std::cin.get(); break; case 4: classID=4; std::cout << "\nEquipped Old Mace!\n" "+5 Attack!\n" "Learned Heal!\n"; attack = 5; abilitydmg = 10; abilityname = "Heal"; manaCost = 10; std::cin.get(); break; } tavern: int hunt; HP=100; mana=100; std::cout << "\n\nYou sit at the dim tavern, finishing a pint of ale.\n" "The bitter taste coats the inside of your mouth.\n" "You can hear the rowdy crowd behind you.\n" "You pay the bartender.\n"; std::cin.get(); std::cout << "\n--------------------------\n\n" "You see the owner post new hunts on the bounty board. You approach it\n" "and read the following:\n\n" "Need a strong and witful bounty hunter to rid of Farm Giant destroying\n" "crops and terrorizing town. Will pay in gold\n\n" "Which bounty do you take?\n" "[1] Farm Giant\n"; std::cin >> hunt; std::cout << "---------------------------------------------------------------------\n\n"; switch(hunt) { case 1: int trail, caveEnter; int fight1, fight2, giantFight, action1, action2, action3, riddleAnswer; int loot; int goblinAttack, goblinHP, giantAction; goblinAttack = 5; goblinHP = 10; int skeletonAttack, skeletonHP; skeletonAttack = 3; skeletonHP = 15; int giantAttack, giantHP; giantAttack = 15; giantHP = 50; std::cout << "You head down the northern trail that leads to the meadow.\n" "Villagers are spotted carrying their belongings and moving the\n" "opposite direction of the meadow. You hear whispers of the giant\n" "from the oncoming villagers.\n\n"; std::cin.get(); std::cout << "---------------------------------------------------------------------\n\n" "As you reach the edge of the road, you come across two more trails.\n\n" "One trail leads into a valley. Cliffs stand tall on both sides. It looks\n" "daunting, but dooable\n" "The other path runs across the side of a dirty river. The pathway leads\n" "down a hill, diverging at the end of a solemn graveyard.\n\n" "You recall both trails lead to the meadow eventually.\n\n" "Which do you take?\n" "[1] Valley Trail\n" "[2] River Trail\n" "---------------------------------------------------------------------\n\n"; std::cin >> trail; if(trail==1) { std::cout << "As you head down the valley you notice large spires\n" "made of jagged stone tower over you. Halfway down the path\n" "you spot a cave. The entrance is just narrow enough for you\n" "to fit in.\n" "Do you enter the cave or move on?\n" "[1] Enter\n" "[2] Move on\n" "---------------------------------------------------------------------\n\n"; std::cin >> caveEnter; if(caveEnter==1) { std::cout << "You croutch as you approach the entrance. Water drips\n" "deep in the cave, splashing into a larger puddle. Sunlight peers\n" "through a sky light in a large opening a couple feet in front of the\n" "entrance. At the other side of the room lies an old chest.\n\n" "Before you can react a goblin leaps off a nearby ledge in front of you\n"; std::cin.get(); std::cout << "Do you fight or flee?\n\n" "[1] Fight\n" "[2] Flee\n" "---------------------------------------------------------------------\n\n"; std::cin >> fight1; if(fight1==1) { goblinFight: loot = rand() % 3 + 1; srand(time(NULL)); std::cout << "\nYour HP: " << HP << std::endl; std::cout << "Your Mana: " << mana << std::endl; std::cout << "Your Attack: " << attack << std::endl; std::cout << "\nEnemy HP: " << goblinHP << std::endl; std::cout << "Enemy Attack: " << goblinAttack << std::endl; std::cout << "\nWhat do you do?\n" "[1] Attack [2] " << abilityname << " (" << manaCost << " Mana)" << " (" << abilitydmg << " Damage)" << std::endl; std::cout << "[3] Health Potion " << "(" << hpPots << ") " << "[4] Mana Potion " << "(" << manaPots << ")" << std::endl; std::cin >> action1; std::cout << "---------------------------------------------------------------------\n\n"; if(goblinHP<=0) { std::cout << "You have slain the goblin!\n" "You head towards the chest and take the spoils\n" "of battle!\n\n"; switch(loot) { case 1: std::cout << "---You find 1 Health Potion!---\n\n"; hpPots = hpPots + 1; goto endTrail; case 2: std::cout << "---You find 1 Mana Potion!---\n\n"; manaPots = manaPots + 1; goto endTrail; case 3: std::cout << "---You find 1 Health Potion and 1 Mana Potion!---\n\n"; manaPots = manaPots + 1; hpPots = hpPots + 1; goto endTrail; } } if(HP<=1) { std::cout << "\n\n---------- You have died! ----------\n\n"; std::cin.get(); goto tavern; } else if(mana<=0) { std::cout << "You do not have enough Mana! You attack instead.\n"; } if(action1==1) { std::cout << "You successfully hit the goblin for " << attack << std::endl; std::cout << "He strikes back for " << goblinAttack << std::endl; goblinHP = goblinHP - attack; HP = HP - goblinAttack; goto goblinFight; } else if(action1==2) { if(mana<=0) { std::cout << "\nYou do not have enough Mana!\n"; goto goblinFight; } if(classID==1) { std::cout << "You successfully stun the enemy and attack it for " << abilitydmg << std::endl; goblinHP = goblinHP - abilitydmg; mana = mana - manaCost; goto goblinFight; } if(classID==4) { std::cout << "The Holy Light infuses you. You successfully heal for " << abilitydmg << std::endl; HP = HP + abilitydmg; mana = mana - manaCost; goto goblinFight; } else std::cout << "You successfully hit the goblin for " << abilitydmg << std::endl; std::cout << "It strikes back for " << goblinAttack << std::endl; goblinHP = goblinHP - abilitydmg; HP = HP - goblinAttack; mana = mana - manaCost; goto goblinFight; } else if(action1==3) { if(hpPots<=0) { std::cout << "You have no potions!\n\n"; goto goblinFight; } else std::cout << "You drink the potion.\n" "+10 Health!"; HP = HP + 10; hpPots = hpPots - 1; goto goblinFight; } else if(action1==4) { if(manaPots<=0) { std::cout << "You have no potions!\n\n"; goto goblinFight; } else std::cout << "You drink the potion.\n" "+10 Mana!"; mana = mana + 10; manaPots = manaPots - 1; goto goblinFight; } else { std::cout << "You take the cowards way out and leave the cave.\n"; goto endTrail; } } } } if(trail==2) { std::cin.get(); std::cout << "You head down the sloped hill that leads down to the river\n" "The water is thick and murky as you examine it. A rotten\n" "smell plagues the air.\n\n"; std::cin.get(); std::cout << "---------------------------------------------------------------------\n\n" "Continuing down the trail, the wretched smell worsens. It is almost\n" "unbearable. The path starts to wind down a hill straight the the graveyard.\n" "You feel an eerie presence surround you.\n\n" "A skeleton emerges from a nearby grave!\n\n"; std::cin.get(); std::cout << "What do you do?\n" "[1] Fight\n" "[2] Flee\n" << "---------------------------------------------------------------------\n\n"; std::cin >> fight2; if(fight2==1) { skeletonFight: loot = rand() % 3 + 1; srand(time(NULL)); std::cout << "\nYour HP: " << HP << std::endl; std::cout << "Your Mana: " << mana << std::endl; std::cout << "Your Attack: " << attack << std::endl; std::cout << "\nEnemy HP: " << skeletonHP << std::endl; std::cout << "Enemy Attack: " << skeletonAttack << std::endl; std::cout << "\nWhat do you do?\n" << "[1] Attack [2] " << abilityname << " (" << manaCost << " Mana)" << " (" << abilitydmg << " Damage)" << std::endl; std::cout << "[3] Health Potion " << "(" << hpPots << ") " << "[4] Mana Potion " << "(" << manaPots << ")" << std::endl; std::cin >> action2; std::cout << "---------------------------------------------------------------------\n\n"; } if(skeletonHP<=0) { std::cout << "You have slain the skeleton!\n" "You scower his remains and take what you find useful.\n\n"; std::cin.get(); switch(loot) { case 1: std::cout << "---You find 1 Health Potion!---\n\n"; hpPots = hpPots + 1; goto endTrail; case 2: std::cout << "---You find 1 Mana Potion!---\n\n"; manaPots = manaPots + 1; goto endTrail; case 3: std::cout << "---You find 1 Health Potion and 1 Mana Potion!---\n\n"; manaPots = manaPots + 1; hpPots = hpPots + 1; goto endTrail; } } if(HP<=0) { std::cout << "\n\n---------- You have died! ----------\n\n"; std::cin.get(); goto tavern; } else if(mana<=0) { std::cout << "You do not have enough Mana! You attack instead.\n"; goto skeletonFight; } if(action2==1) { std::cout << "You successfully hit the skeleton for " << attack << std::endl; std::cout << "He strikes back for " << skeletonAttack << std::endl; skeletonHP = skeletonHP - attack; HP = HP - skeletonAttack; goto skeletonFight; } if(action2==2) { if(mana<=0) { std::cout << "\nYou do not have enough Mana!\n"; goto skeletonFight; } if(classID==1) { std::cout << "You successfully stun the enemy and attack it for " << abilitydmg << std::endl; skeletonHP = skeletonHP - abilitydmg; mana = mana - manaCost; goto skeletonFight; } if(classID==4) { std::cout << "The Holy Light infuses you. You successfully heal for " << abilitydmg << std::endl; HP = HP + abilitydmg; mana = mana - manaCost; goto skeletonFight; } else std::cout << "You successfully hit the skeleton for " << abilitydmg << std::endl; std::cout << "It strikes back for " << skeletonAttack << std::endl; skeletonHP = skeletonHP - abilitydmg; HP = HP - skeletonAttack; mana = mana - manaCost; goto skeletonFight; } if(action2==3) { if(hpPots<=0) { std::cout << "You have no potions!\n\n"; goto skeletonFight; } else std::cout << "You drink the potion.\n" << "+10 Health!"; HP = HP + 10; hpPots = hpPots - 1; goto skeletonFight; } if(action2==4) { if(manaPots<=0) { std::cout << "You have no potions!\n\n"; goto skeletonFight; } else std::cout << "You drink the potion.\n" << "+10 Mana!"; mana = mana + 10; manaPots = manaPots - 1; goto skeletonFight; } } endTrail: std::cin.get(); std::cout << "You head down the rest of the path as it opens up to wide\n" "farmland. Crops line up the fields and the tang of sweet root hits\n" "your nostrils.\n\n"; std::cin.get(); std::cout << "---------------------------------------------------------------------\n\n" "Peering out into the landscape, you spot a giant silouhette of a man lying down.\n" "The man is next to a house. You realize that this is no man, but a giant.\n" "You approach the monstrous being slowly and carefully, at this point you're probably\n" "20 meters away from him. It appears he is sleeping.\n\n"; std::cin.get(); std::cout << "What do you do?\n\n" "[1] Attack him while he's sleeping\n" "[2] Waken the giant\n" "[3] Run\n"; std::cin >> giantAction; switch(giantAction) { case 1: std::cout << "You leap forward and put all of your might into attacking\n" "the giants open throat. The earth shakes and pines roar as\n" "the giant awakens in a scream of pain. He immediately lunges at\n" "in your direction. You evade just in time to dodge his attack.\n\n" "What do you do?\n"; std::cin.get(); std::cout << "[1] Engage\n" "[2] Run\n"; std::cin >> giantFight; giantHP = giantHP - 7; if(giantFight==1) { giantFight: std::cout << "\nYour HP: " << HP << std::endl; std::cout << "Your Mana: " << mana << std::endl; std::cout << "Your Attack: " << attack << std::endl; std::cout << "\nEnemy HP: " << giantHP << std::endl; std::cout << "Enemy Attack: " << giantAttack << std::endl; std::cout << "\nWhat do you do?\n" "[1] Attack [2] " << abilityname << " (" << manaCost << " Mana)" << " (" << abilitydmg << " Damage)" << std::endl; std::cout << "[3] Health Potion " << "(" << hpPots << ") " << "[4] Mana Potion " << "(" << manaPots << ")" << std::endl; std::cin >> action3; std::cout << "---------------------------------------------------------------------\n\n"; } if(giantHP<=0) { if(HP<=0) { std::cout << "\n\n---------- You have died! ----------\n\n"; std::cin.get(); goto tavern; } std::cout << "You have slain the mighty giant!\n" "You loot his corpse and take the spoils\n" "of battle!" "\n\n---Congratulations! You have finished the Farm Giant Hunt!---\n\n"; switch(classID) { loot: loot = rand() % 4 + 1; srand(time(NULL)); case 1: switch(loot){ case 1: std::cout << "---You find the Giant Slayer!---\n" "+9 Attack!\n"; attack = attack + 9; std::cin.get(); goto tavern; case 2: std::cout << "---You find a Steel Sword!---\n" "+5 Attack!\n"; attack = attack + 5; std::cin.get(); goto tavern; case 3: std::cout << "---You find a Bastard Sword!---\n" "+6 Attack!\n"; attack = attack + 6; std::cin.get(); goto tavern; case 4: std::cout << "---You find a Tempered Blade!---\n" "+7 Attack!\n"; attack = attack + 7; std::cin.get(); goto tavern; } break; case 2: switch(loot){ case 1: std::cout << "---You find an Emerald Staff!---\n" "+5 Attack!\n" "+5 Magic Damage!\n"; attack = attack + 5; abilitydmg = abilitydmg + 5; std::cin.get(); goto tavern; case 2: std::cout << "---You find an Enchanted Scepter!---\n" "+6 Attack!\n" "+7 Magic Damage\n" "+10 Mana Cost!\n"; manaCost = manaCost + 10; attack = attack + 6; abilitydmg = abilitydmg + 7; std::cin.get(); goto tavern; case 3: std::cout << "---You find an Studded Scepter!---\n" "+6 Attack!\n" "+6 Magic Damage!\n"; attack = attack + 6; abilitydmg = abilitydmg + 6; std::cin.get(); goto tavern; case 4: std::cout << "---You find a Ruby Staff!---\n" "+7 Attack!\n" "+4 Magic Damage\n"; attack = attack + 7; abilitydmg = abilitydmg + 4; std::cin.get(); goto tavern; } break; case 3: switch(loot){ case 1: std::cout << "---You find a Broken Dagger!---\n" "+3 Attack!\n" "+5 Backstab Damage!\n"; attack = attack + 3; abilitydmg = abilitydmg + 5; std::cin.get(); goto tavern; case 2: std::cout << "---You find a Shortsword!---\n" "+6 Attack!\n" "+3 Backstab Damage!\n"; attack = attack + 6; abilitydmg = abilitydmg + 3; std::cin.get(); goto tavern; case 3: std::cout << "---You find an Glass Knife!---\n" "+5 Attack!\n" "+10 Backstab Damage!\n"; attack = attack + 5; abilitydmg = abilitydmg + 10; std::cin.get(); goto tavern; case 4: std::cout << "---You find a Ceremonial Dagger!---\n" "+7 Attack!\n" "+6 Backstab Damage!\n"; attack= attack + 7; abilitydmg = abilitydmg + 6; std::cin.get(); goto tavern; } break; case 4: switch(loot){ case 1: std::cout << "---You find a Cleric's Mace!---\n" "+5 Attack!\n"; attack = attack + 5; std::cin.get(); goto tavern; case 2: std::cout << "---You find a Warhammer!---\n" "+7 Attack!\n"; attack = attack + 7; std::cin.get(); goto tavern; case 3: std::cout << "---You find an Steel Hammer!---\n" "+6 Attack!\n"; attack = attack + 6; std::cin.get(); goto tavern; case 4: std::cout << "---You find a Giant's Club!---\n" "+10 Attack!\n"; attack = attack + 10; std::cin.get(); goto tavern; } break; } } if(action3==1) { std::cout << "You successfully hit the giant for " << attack << std::endl; std::cout << "He strikes back for " << giantAttack << std::endl; giantHP = giantHP - attack; HP = HP - giantAttack; goto giantFight; } else if(action3==2) { if(mana<=0) { std::cout << "\nYou do not have enough Mana!\n"; goto giantFight; } if(classID==1) { std::cout << "You successfully stun the enemy and attack it for " << abilitydmg << std::endl; giantHP = giantHP - abilitydmg; mana = mana - manaCost; goto giantFight; } if(classID==4) { std::cout << "The Holy Light infuses you. You successfully heal for " << abilitydmg << std::endl; HP = HP + abilitydmg; mana = mana - manaCost; goto giantFight; } else std::cout << "You successfully hit the giant for " << abilitydmg << std::endl; std::cout << "It strikes back for " << giantAttack << std::endl; giantHP = giantHP - abilitydmg; HP = HP - giantAttack; mana = mana - manaCost; goto giantFight; } else if(action3==3) { if(hpPots<=0) { std::cout << "You have no potions!\n\n"; goto giantFight; } else std::cout << "You drink the potion.\n" "+10 Health!"; HP = HP + 10; hpPots = hpPots - 1; goto giantFight; } else if(action3==4) { if(manaPots<=0) { std::cout << "You have no potions!\n\n"; goto giantFight; } else std::cout << "You drink the potion.\n" "+10 Mana!"; mana = mana + 10; manaPots = manaPots - 1; goto giantFight; } else { std::cout << "You take the cowards way out and run.\n"; std::cin.get(); goto tavern; } } case 2: std::cout << "---------------------------------------------------------------------\n\n" "You quietly approach the giant and awaken him from his slumber\n" "He quickly gets to his feet and assumes a defensive posture.\n" "After looking at his surroundings, the giant questions,\n\n" "'Who dares awaken me?!\n\n"; std::cin.get(); std::cout << "---------------------------------------------------------------------\n\n" "You introduce yourself, and inform him of the problem of the nearby villagers.\n" "After the conflict is talked about, he offers a compromise.\n\n" "'If you, measly man can answer my riddle, I shall return to where\n" "I came from and leave this place in peace.'\n" "The giant shifts where he stands and prepares his riddle.\n\n"; std::cin.get(); std::cout << "---------------------------------------------------------------------\n\n" "I have a heart that never beats, I have a home but I never sleep\n" "I can take a mans house and build another, And I love to play games\n" "with my many brothers. A King among fools.\n\n" "What am I?\n\n" "[1] A Jester\n" "[2] King of Hearts\n" "[3] A Trickster\n" "[4] -Do not answer-\n"; std::cin >> riddleAnswer; if(riddleAnswer==2) { std::cout << "You have correctly answered my riddle. I shall leave in peace\n" "You return on the path you walked and head back to the tavern.\n"; std::cin.get(); std::cout << "\n\n---Congratulations! You have finished the Farm Giant Hunt!---\n\n"; goto loot; } else { std::cout << "You have incorrectly answered my riddle, prepare to die puny man!\n"; goto giantFight; } } } 
\$\endgroup\$

    3 Answers 3

    3
    \$\begingroup\$

    Right off the bat, I would suggest learning about Object Oriented Programming. Each character type should be a separate class, each with its own set of attributes, probably inherited from a main character class.

    All that code in main, should be pared down to a bunch of functions. right now everything is so intricately dependant, that any changes you try to make will be nightmare

    \$\endgroup\$
      3
      \$\begingroup\$

      I see a number of things that may help you improve your program.

      Decompose your program into functions

      All of the logic here is in main in one rather long and dense chunk of code. It would be better to decompose this into separate functions.

      Fix your formatting

      There are inconsistent spaces at the beginning of lines, inconsistent indentation and inconsistent use and placement of curly braces {}. Being consistent helps others read and understand your code.

      Fix the bug(s)

      In a number of places in the code, the indentation suggests that there is a problem with your else clauses. For example, in this code:

      if(hpPots<=0) { std::cout << "You have no potions!\n\n"; goto giantFight; } else std::cout << "You drink the potion.\n" "+10 Health!"; HP = HP + 10; hpPots = hpPots - 1; goto giantFight; 

      The only thing that's executed by the else clause is the std::cout line. All lines following are executed no matter what. In other words, it's as though the code were written like this:

      if(hpPots<=0) { std::cout << "You have no potions!\n\n"; goto giantFight; } else { std::cout << "You drink the potion.\n" "+10 Health!"; } HP = HP + 10; hpPots = hpPots - 1; goto giantFight; 

      In this case it doesn't make much difference because of the goto line, but in general, it's wise to always use {} to make sure that both you and other readers of the code are clear about what's happening.

      Lather, rinse, repeat

      There's more, but it's all essentially the exact same things I told you a year and a half ago.

      \$\endgroup\$
      2
      • \$\begingroup\$Oh. Wow, I completely missed that old question. Well, I could have saved myself a my wall of text, you really said everything already.\$\endgroup\$
        – Zeta
        CommentedFeb 20, 2017 at 21:10
      • \$\begingroup\$@Zeta Your review is still valuable because you've provided some sample code that reinforces the message.\$\endgroup\$
        – Edward
        CommentedFeb 20, 2017 at 21:14
      1
      \$\begingroup\$

      When you write a program, you try to express your ideas in a way that the compiler under­stands it and builds you an executable, that works as you intended. However, the compiler is a second-hand consumer. They will gladly take any code that is valid C++ and create a binary. The human, however, might not.

      As humans, it comes naturally that we organize the material we work with. Clockmakers will have their screws and drivers sorted, plumbers their wrenches and helpers. Mechanics have their bolts, nuts and gears ready in bins and cans, just a handful away.

      And we programmers, coders, C++ magicians? We can do what they cannot do that easily: we order our work itself. We partition it with functions and methods, we bundle our variables into single structures, we split our code in files, each meaningful on its own. We model our ideas into the very code in such a way that their interesting, clear, and not too repeating.

      Now, let us delve head-first into your fantasy world and see how we can improve it.

      Enable compiler warnings

      I don't know which compiler you use, but the compiler already tells you what might be wrong with your code:

      $ g++ textadventure.cc -Wall -Wextra -pedantic textadventure.cc: In funtion »int main()«: textadventure.cc:387:33: Warning: this »else« clause does not guard... [-Wmisleading-indentation] else ^~~~ textadventure.cc:389:37: Remark: ...this statement, but the latter is misleadingly indented as if it is guarded by the »else« std::cout << "It strikes back for " << skeletonAttack << std::endl; ^~~ textadventure.cc:628:33: Warning: this »else« clause does not guard... [-Wmisleading-indentation] else ^~~~ textadventure.cc:630:37: Remark: ...this statement, but the latter is misleadingly indented as if it is guarded by the »else« std::cout << "It strikes back for " << giantAttack << std::endl; ^~~ textadventure.cc:10:13: Warnung: unused variable »warrior« [-Wunused-variable] int warrior, mage, rogue, priest; ^~~~~~~ textadventure.cc:10:22: Warnung: unused variable »mage« [-Wunused-variable] int warrior, mage, rogue, priest; ^~~~ textadventure.cc:10:28: Warning: unused variable »rogue« [-Wunused-variable] int warrior, mage, rogue, priest; ^~~~~ textadventure.cc:10:35: Warning: unused variable »priest« [-Wunused-variable] int warrior, mage, rogue, priest; ^~~~~~ textadventure.cc:13:31: Warnung: unused variable »potionInv« [-Wunused-variable] int hpPots, manaPots, potionInv; ^~~~~~~~~ 

      Proper #includes

      You're writing C++, therefore, you should include the appropriate headers. Instead of time.h, include ctime, instead of stdio.h include cstdio, and instead of stdlib.h include cstdlib:

      #include <iostream> #include <string> #include <ctime> #include <cstdio> #include <cstdlib> 

      Group values that shall be grouped

      Right of your main, we have

      int warrior, mage, rogue, priest; int class1, classID; int HP, mana, manaCost, attack, abilitydmg; int hpPots, manaPots, potionInv; 

      Your compiler should have told you that you never actually use warrior, mage, rogue or priest. But even then, you have all those values scattered around. Is HP always the player's HP? Is attack the amount of attacks the player has left?

      We shall group the values that make a character:

      struct Player { enum Class { Warrior, Mage, Rogue, Priest }; Class what_class; int health; int mana; int attack; int health_potions; int mana_potions; int mana_cost; int ability_effect; std::string ability_name; }; 

      There are several ways to structure your character, but should give you a first idea. That way, you can have your player defined right of the start:

      Player player = player_creation(); 

      Create functions

      You saw the example above already: player_creation. We can use functions to make the game easier to read and to extend. For example, all your prompts might not work at the moment. What happens if the user inputs a 6 at the start? Or even a letter?

      Instead of handling that error at every occasion, let's write a function that covers that:

      int prompt(const char * message, int lower_bound, int upper_bound) { int answer = 0; std::cout << message; while(!(std::cin >> answer) || answer < lower_bound || answer > upper_bound){ std::cin.clear(); // forget that there was an error std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); std::cout << "Try again!\n" << message; } return answer; } 

      Also, if we have a fight, we can "hand over" the player to our function with reference semantics*:

      bool goblinfight(Player & player) { // ... handle the goblin fight here } 

      We can use that to equip new weapons:

      void equip(Player & player, Weapon weapon) { std::cout << "Equipped " << weapon.name << "!\n"; << "Attack +" << weapon.damage << "\n"; player.attack += weapon.damage; } 

      or new abilities:

      void equip(Player & player, Weapon weapon) { std::cout << "Equipped " << weapon.name << "!\n"; << "Attack +" << weapon.damage << "\n"; player.attack += weapon.damage; } 

      We can even write a function to create the player at the start of our adventure:

      Player player_creation() { const int answer = prompt("--Choose a Class--\n\n" "---[1] Warrior---\n" "The warrior uses mighty attacks and has a unique stun ability.\n\n" "---[2] Mage---\n" "The mage uses the arcane arts to fire magical bolts from his fingertips.\n\n" "---[3] Rogue---\n" "The rogue uses the arts of assassination and uses a powerful backstab move.\n\n" "---[4] Priest---\n" "The priest uses the holy arts and has a heal ability.\n",1,4); Player player; switch(answer) { case 1: player.what_class = PClass::Warrior; equip(player, rusty_sword); learn(player, slam); break; ... } return player; } 

      * Please note that you would usually change Player into a class and use methods. I'm not sure whether you're ready for object oriented programming yet. This is basically the C-way of object orientation, which may or may not be easier for you as a first introduction.

      Read the documentation

      srand should be used only once in your program, and before the first rand call. Just use it as first thing in your main.

      This was a small intermission to get you ready for the next section, which is rather important.

      Don't use goto

      There's usually no need for goto if you've followed my second-to-last advice and split your game into several functions. You should always avoid goto. goto makes it hard to reason about the program flow.

      Think in scenes

      Your player has essentially one action. They have a choice, which either determines the next scene, or their action in the fight. A scene here can be thought just like a scene in a play.

      You do already think in scenes. It's those bits and parts where you use switch and case and the dreaded goto labels, for example the tavern:, so you're already on a good way.

      However, if you want to change those scenes without recompiling your program all the time, you probably want to move most of the text out of it. You could even specify the choices and the enemies in text files, but that's a little bit out of scope for this review.

      Further remarks

      You really need to structure your code into separate sections. Functions would provide a first way. However, when you start to do that, your code will probably get larger than it already is. Vertically that is. You have around 650 lines in a single file at the moment, and if you structure your code, you will probably have over 1000.

      At that point, you want to split your file into several ones. Maybe you want to put the fighting logic into another file. Or the character generation. The scene-handling? It's up to you.

      By the way, your lines are currently too long. But that will probably fix itself as soon as you use functions.

      \$\endgroup\$

        Start asking to get answers

        Find the answer to your question by asking.

        Ask question

        Explore related questions

        See similar questions with these tags.