7
\$\begingroup\$

I am not really having any problems with this. I'm just wondering if anybody has any ideas for a path for me to look down for bettering this little FF turn-based style of game in my free time.

I know somebody is going to complain about my global variables and the fact that I am not using object-oriented programming, but it will eventually get there. This is a boredom project that I'm plunking through.

Any advice or insight on any issues or ideas would be cool. And if somebody is looking into making a turn-based style of game, they can feel free to use up my code. Sorry about any bad formatting as well; I haven't really learned that yet.

// random.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<ctime>
using namespace std;
int main()
{
 int eHealth=100; //initial Enemy Health(based on enemy)
 int pHealth=100; //initial Player Health 
 int eAttack=0; //Enemy Attack Strength(based on enemy)
 int pAttack=0; //Player Attack Strength(based on level and items)
 int selection=0; //Selection Variable for Battle Menue
 int hPower=0; //Healing power Variable(random number)
 int eSelection=0; //Enemies battle menu selection variable
 int counter=0; //Counter to establish whos turn it is 
 int itemSelect=0; //Item inventory selection
 int eMagic=50; //Enemies magic meter
 int pMagic=50; //Players magic meter
 cout<<pHealth<<" "<<eHealth<<endl; //player and enemy health levels
 cout<<pMagic<<" "<<eMagic<<endl; //player and enemy magic levels
 cout<<endl;
 cout<<endl;
 cout<<"1.Attack"<<endl; //lines 31-33 are the battle menu appears frequently throught game
 cout<<"2.Heal"<<endl;
 cout<<"3.Item"<<endl;
 do //start of post test loop that runs the game until somebody is dead
 { 
 if(counter==0)// if the counter variable is 0 it is the players turn
 {
 cin>>selection;
 srand(static_cast<int>(time(0)));//randomize all the random variables
 switch(selection)
 { 
 case 1:// player chooses to ATTACK
 pAttack=1+rand()%(35-1+1);//attack power can be between 1-35
 cout<<"ATTACK "<<pAttack<<endl;
 system("pause");
 system("cls");
 eHealth=eHealth-pAttack;
 cout<<pHealth<<" "<<eHealth<<endl;
 cout<<pMagic<<" "<<eMagic<<endl;
 cout<<endl;
 cout<<endl;
 cout<<"1.Attack"<<endl;
 cout<<"2.Heal"<<endl;
 cout<<"3.Item"<<endl;
 break;
 case 2://Player chooses to heal, it costs 10 magic to heal so if you dont have enough magic you loose a turn
 if(pMagic>9)
 {
 hPower=1+rand()%(35-1+1);//healing power can be any number between 1-35
 cout<<"HEAL"<<hPower<<endl;
 system("pause");
 system("cls");
 pHealth=pHealth+hPower;
 pMagic=pMagic-10;
 cout<<pHealth<<" "<<eHealth<<endl;
 cout<<pMagic<<" "<<eMagic<<endl;
 cout<<endl;
 cout<<endl;
 cout<<"1.Attack"<<endl;
 cout<<"2.Heal"<<endl;
 cout<<"3.Item"<<endl;
 }//endIF
 break;
 case 3:// if player chooses to use item inventory system
 cout<<"ITEM INVENTORY"<<endl;
 cout<<"1.Potion Restores HP"<<endl;
 cout<<"2.Ether Restores MP"<<endl;
 cout<<"3.Bomb Causes Damage to all players"<<endl;
 cout<<"4.Big Purple Dildo ?????"<<endl;
 cout<<"5.Sticky Bomb Freezes oponent for 3 Truns"<<endl;
 cin>>itemSelect;
 switch(itemSelect)
 {
 case 1:
 pHealth=pHealth+75;
 system("cls");
 cout<<pHealth<<" "<<eHealth<<endl;
 cout<<pMagic<<" "<<eMagic<<endl;
 cout<<endl;
 cout<<endl;
 cout<<"1.Attack"<<endl;
 cout<<"2.Heal"<<endl;
 cout<<"3.Item"<<endl;
 break;
 case 2:
 break;
 }//endItemSwitch 
 }//endSelectionSwitch
 counter=1;// advances the counter to 1 to allow the enemies turn
 }//endif
 eSelection=rand() % 2+1;
 switch(eSelection)
 {
 case 1:
 eAttack=1+rand()%(35-1+1);
 cout<<"ATTACK "<<eAttack<<endl;
 system("pause");
 system("cls");
 pHealth=pHealth-eAttack;
 cout<<pHealth<<" "<<eHealth<<endl;
 cout<<pMagic<<" "<<eMagic<<endl;
 cout<<endl;
 cout<<endl;
 cout<<"1.Attack"<<endl;
 cout<<"2.Heal"<<endl;
 cout<<"3.Item"<<endl;
 break;
 case 2:
 if(eMagic>10)
 {
 hPower=1+rand()%(35-1+1);
 cout<<"HEAL"<<hPower<<endl;
 system("pause");
 system("cls");
 eMagic=eMagic-10;
 eHealth=eHealth+hPower;
 cout<<pHealth<<" "<<eHealth<<endl;
 cout<<pMagic<<" "<<eMagic<<endl;
 cout<<endl;
 cout<<endl;
 cout<<"1.Attack"<<endl;
 cout<<"2.Heal"<<endl;
 cout<<"3.Item"<<endl;
 }
 break;
 }//endeSelectionSwitch
 counter=0;
 }while(eHealth > 1 && pHealth > 1);//loops while both players life is over 1 ends postest loop when players life or enemies falls below 1
 system("pause");
 return 0;
 }
200_success
146k22 gold badges190 silver badges479 bronze badges
asked Jan 3, 2014 at 23:07
\$\endgroup\$
3
  • 5
    \$\begingroup\$ Learn how to write a function in C++! \$\endgroup\$ Commented Jan 3, 2014 at 23:14
  • \$\begingroup\$ Havent gotten that far yet but I assume that turning my menu into a function would clean this up quite a bit? \$\endgroup\$ Commented Jan 3, 2014 at 23:16
  • 1
    \$\begingroup\$ Those variables aren't actually global; they're just all at the top of main(). \$\endgroup\$ Commented Jan 3, 2014 at 23:17

3 Answers 3

7
\$\begingroup\$
  • system("PAUSE") is entirely unnecessary here. You could do the same thing by simply clearing out cin and then reading a char.

  • You should generally call srand once, at the beginning of the program. Once you've seeded the PRNG, it'll be good for a while -- probably much longer than this program will run. :) The way you're doing it, if the loop runs twice in the same second, and the user makes the same choices, the same outcome will occur.

  • You are doing an awful lot of similar I/O over and over -- particularly, outputting a menu and getting a response. You should look at creating a function to do that, and then just call it whenever you want the user to choose something.

  • using namespace std; is laziness. :) If you don't want to type std:: before that stuff, i'd recommend at least only using the names you actually use. Otherwise, you could run into interesting issues later when you decide to use the same names that the standard library used (which is not at all uncommon).

  • You have a bunch of magic numbers. You'd do better to make those constants; then you could use them by name, and wouldn't need comments telling people what they mean. :)

answered Jan 3, 2014 at 23:16
\$\endgroup\$
4
  • \$\begingroup\$ Thats what I figured I havent written functions yet just simple I/O stuff. I just learned about the rand function today so that was the inspiration that got me playing around. Im in between programming semesters so Im bored. \$\endgroup\$ Commented Jan 3, 2014 at 23:20
  • 1
    \$\begingroup\$ @cHao: Obligatory post regarding using namespace std: stackoverflow.com/questions/1452721/… \$\endgroup\$ Commented Jan 3, 2014 at 23:23
  • \$\begingroup\$ Did not know tht was bad practice thats the way C++ was broken down to me... Thanks for the link Jamal. Makes sense \$\endgroup\$ Commented Jan 3, 2014 at 23:29
  • \$\begingroup\$ @JohnSnow: Also see codereview.stackexchange.com/questions/27986/… (my advice to someone who was working on a project a bit like yours). Includes a bit about the benefits of OOP near the end. \$\endgroup\$ Commented Jan 3, 2014 at 23:41
7
\$\begingroup\$

Your code is repetitive; it looks like you are trying to "unroll" the entire storyline. Ideally, you should write each chunk of code just once. Figure out where the storyline rejoins itself — draw a flowchart. Then write a function for each action (e.g. attack).

Before you try to write the whole game, start small. Try to implement simple primitives first.

You need to be able to pass values to a function, and using global variables would be a bad idea. Instead, group related variables into a struct:

struct Character {
 int health;
 int attack;
 int magic;
};
void heal(Character &c) {
 int healingPower = 1 + rand() % 35;
 c.magic -= 10;
 c.health += healingPower;
}
void print(const Character &c, std::ostream &out) {
 // TODO
}
int main() {
 Character self, enemy;
 print(self, std::cout);
 heal(self);
 print(self, std::cout);
}

Verify that the healing process works. Debug that, and build from there!

answered Jan 3, 2014 at 23:47
\$\endgroup\$
1
  • \$\begingroup\$ Using self like that sent my snake-senses tingling... :) \$\endgroup\$ Commented Dec 12, 2014 at 21:31
5
\$\begingroup\$
  • Do not call std::srand() repeatedly in a program. This will reset the seed at each call, causing std::rand() to produce the same random number. It's best to put this at the top of main() where it'll be called only once. It's also easier to maintain this way.

    Also prefer to call it like this (assuming you receive "loss of data" warnings from not having a cast):

    std::srand(static_cast<unsigned int>(std::time(NULL)));
    

    If you're using C++11, use nullptr instead of NULL.

  • Prefer to use "\n" when outputting a newline without a buffer flush. std::endl does both, so using it quite often could slow down your program.

    Here's an example of how it's used:

    std::cout << "\nthis message contains two newlines\n";
    
answered Jan 3, 2014 at 23:29
\$\endgroup\$
1
  • \$\begingroup\$ Awesome tip fixed a problem that was in the back of my head every time I ran the program. \$\endgroup\$ Commented Jan 3, 2014 at 23:34

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.