LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Problems with my game in C++ (https://www.linuxquestions.org/questions/programming-9/problems-with-my-game-in-c-374092/)

twirl 10-17-2005 08:04 PM

Problems with my game in C++
 
Hi,

I have started writing a game in C++, my problems are what is happening below

1. The menu is very messy and i do not know how to center the text.

2. y or n dont work the way they should do (how do i fix it so user can enter y/Y/YES/yes and n/N/NO/No Please?

3. If user starts the game it will ask for there handle they wish to use, the problem is once asked if they wish to use that handle yes or no will appear the only option that will work is n for no. As the user should get some text output for when they press y. Please help me fix

Also i know about the ostream files that i can't do it that way, i will fix that after i get this problem solved first. Also note this game is incomplete as i am still working on it.

Thankyou

Andy

My code is below :-

------------------------------------------------------------------------------

Code:

// Space Empires BBS Door By Andrew WIlkie

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

using namespace std;

int main() {
  char choice='\0';//NULL;      // set choice to zero         
 bool finished=false;         

 std::string p;
 std::string n;
 std::string r;
 std::string f;
 std::string y;
 std::string d;
 std::string h;

 p="Play Space Empires";
 n="Space Empire News";
 r="Space Empire Rankings";
 f="Space Empires Hall Of Fame";
 y="y";
 d="n?";
 h="What name shall the galaxy know you by?";

ofstream outfile("player.dat,news.dat,names.dat,ranks.dat,hof.dat,ios::app");//create data files
std::ifstream infile;

// exit program if unable to create program

 if ( !outfile ) { // overloaded ! operator
  cerr << "File could not be opened" << endl;
 exit( 1 );

 } // end if

int i=0;

 while (finished != true)      // keep program to run till users wishes to exit 
  {

// Start main menu
 

    cout << "Welcome To Space Empires";
    cout << "  By Andrew Wilkie 2005";
    cout << "  \n\n";
    cout << ".1"  << p; 
    cout << ".2"  << n;               
    cout << ".3"  << r;
    cout << ".4"  << f;
    cin>>choice;
    cout<<"\n\n";     
 
 switch(choice)
  {
  case '1':cout << p << endl;
            cout << y << d << endl; // ask user yes/no?
            cin >> y >> d; // get user input
   
  if(choice =='d') // check choice = d then return to main menu
    { 
    cout <<"Welcome To Space Empires";
    cout <<"By Andrew Wilkie 2005";
    cout << "1." << p; 
    cout << "2." << n;
    cout << "3." << r;
    cout << "4." << h;
    cout <<"\n";     
    cin>>choice;
    cout<<"\n\n";
    }

// Playing Of Space Empire's Begins Here

    else if(choice=='1') {       
    cout << "Hello, You must be new in the galaxy.";
    cout << h << endl;
    cin >> h;
    outfile << h << "names.dat"; // store name into names.dat
    cout << h;
    cout <<"Use this name yes/no?" << endl;
    cin >> h >> d; // ask user yes or no?
    }
 
    if(choice =='y') // check choice = y then start game
    { 
    cout << "Well...Here you are. Just another new" << endl;
    cout << "emperor with a hoard of cash, some" << endl;
    cout << "food, and the massive population" << endl;
    cout << "your father left you on these three" << endl;
    cout << "measly planets, what are you waiting for?" << endl;
    cout << "Start buying some weapons! Do what" << endl;
    cout << "nobody in your family has done before!" << endl;
    cout << "CONQUER! DESTROY! YOU can rule" << endl;
    cout << "the universe if you TRY!" << endl;
 
    cout << "Please press enter to continue:" << endl;     

    }
    } 

  }
  }


rsheridan6 10-18-2005 01:32 AM

The problem is your switch statement. It isn't doing what you think it is. Here it is with comments explaining what it really does in capitals.

Code:

switch(choice)
  {
  case '1':cout << p << endl;
            cout << y << d << endl; // ask user yes/no?
            cin >> y >> d; // get user input WHICH YOU NEVER DO ANYTHING WITH
   
  if(choice =='d') // check choice = d then return to main menu
//CHOICE NEVER = 'd' BECAUSE THIS IS INSIDE "case '1'" ABOVE: A GOOD COMPILER WILL SIMPLY DISCARD THIS BECAUSE IT's IMPOSSIBLE TO REACH
    { 
    cout <<"Welcome To Space Empires";
    cout <<"By Andrew Wilkie 2005";
    cout << "1." << p; 
    cout << "2." << n;
    cout << "3." << r;
    cout << "4." << h;
    cout <<"\n";     
    cin>>choice;
    cout<<"\n\n";
    }

// Playing Of Space Empire's Begins Here

// CHOICE IS ALREADY '1' OR YOU WOULDN'T BE IN CASE '1'.  THIS WILL ALWAYS BE EXECUTED
    else if(choice=='1') {       
    cout << "Hello, You must be new in the galaxy.";
    cout << h << endl;
    cin >> h;
    outfile << h << "names.dat"; // store name into names.dat
    cout << h;
    cout <<"Use this name yes/no?" << endl;
// I THINK YOU MEAN cin >> choice
    cin >> h >> d; // ask user yes or no? BECAUSE NOTHING IS EVER DONE WITH h OR d AFTER THIS
    }
 
//CHOICE IS STILL '1' SO THIS WILL NEVER HAPPEN
    if(choice =='y') // check choice = y then start game
    { 
    cout << "Well...Here you are. Just another new" << endl;
<snip> 

    }
    } 

  }
  }

Also, be wary of repetition in your code. You repeat your main menu from the beginning of your code in your switch statement. The right thing would be to 'break' which would take you back to the top of the while loop and display the menu again. In general, you should write the same thing once and only once.

Orkie 10-18-2005 12:00 PM

I'm not sure if there is another easier way of doing centred text in C++ but certainly one way of doing it would be to use the ncurses library: http://www.gnu.org/software/ncurses/

EDIT: I found this website which gives a breif overview of using the ncurses menu library: http://dickey.his.com/ncurses/ncurses-intro.html#menu

Matir 10-18-2005 01:03 PM

Also, your variable names (c,d,n,y,h,etc.) make your code very hard to understand. Not to mention I'm not sure what this code is supposed to do:
Code:

ofstream outfile("player.dat,news.dat,names.dat,ranks.dat,hof.dat,ios::app");
That would create some weird "player.dat,news.dat,names.dat,ranks.dat,hof.dat,ios::app" file.

If you wanted to open each file for append, did you consider:
Code:

ofstream playerFile ("player.dat",ios::app);
ofstream newsFile ("news.dat",ios::app);
ofstream namesFile ("names.dat",ios::app);
...


somnium 10-18-2005 01:48 PM

As was mentioned before, case statements in switch "loops" have to be terminated or will run through every case. This is done with a break statement or return. EX

switch (var)
{
case '1':
{
statement;
statement;
break;
}
case '2':
{
etc;
}
}

also, you're code could really use some cleaning up. single letter variables are never really ok to use even though you can get away with them in small scope loops but for strings?!? A lot of little problems, quirks, and bugs can be easily never implemented with a practice of writing clean code. Just something to think about...

twirl 10-20-2005 09:24 PM

Hi,

Thankyou for your reply, i have changed my code and have got it working, but i now have another little glitch if the user presses no in my program after being asked if they wish to use that name, it outputs the text that should only been seen if the user pressed yes. Please help me fix and also how would i change my code so it will take the user back to the main menu? Thankyou


Note: this is not complete so dont expect anything to happen after the yes part apart from the output text.

twirl

My Code :-
-----------------------------------------------------------------------

Code:

// Space Empires BBS Door By Andrew WIlkie

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

using namespace std;

int main() {
  char choice='\0';//NULL;      // set choice to zero         
  bool finished=false;         

  std::string play;
  std::string news;
  std::string rankings;
  std::string hof;
  std::string yes;
  std::string no;
  std::string name;

  play="Play Space Empires";
  news="Space Empire News";
  rankings="Space Empire Rankings";
  hof="Space Empires Hall Of Fame";
  yes="yes";
  no="no";
  name="What name shall the galaxy know you by?";

  ofstream outfile("player.dat,news.dat,names.dat,ranks.dat,hof.dat,ios::app");//create data files
  std::ifstream infile;

// exit program if unable to create program

  if ( !outfile ) { // overloaded ! operator
  cerr << "File could not be opened" << endl;
    exit( 1 );

    } // end if

int i=0;

while (finished != true)      // keep program to run till users wishes to exit 
{

// Start main menu
 
  cout << "Welcome To Space Empires By Andrew Wilkie 2005";
  cout << "  \n\n";
  cout << "\n 1 --> "  << play; 
  cout << "\n 2 --> "  << news;               
  cout << "\n 3 --> "  << rankings;
  cout << "\n 4 --> "  << hof;
  cout <<" \n 5 --> Exit \n";
  cin >> choice;
  cout<<"\n\n";     
 
switch(choice)
 {
 case '1':cout << play << endl;
          cout << ".1" << play;
          cin >> choice; // get answer from user
         
 if(choice=='1')
  { 
  cout << "Play Space Empires YES/NO?" << endl;
  cout << "\n 1 --> " << yes;
  cout << "\n 2 --> " << no;
  cin >> choice;
 
 if(choice=='1')
  {
  cout << name << endl;
  cin >> name;
  cout << "do you wish to use --> " << name << endl; // ask user yes/no?
  cout << "\n 1 --> Yes" << endl;
  cout << "\n 2 --> No"  << endl;
  cin >> choice;
 

 if(choice=='1')
  outfile << name << "names.dat"; // store name into names.dat
  cout <<"Welcome to Space Empire --> " << name << endl;
   
  cout << "Well...Here you are. Just another new" << endl;
  cout << "emperor with a hoard of cash, some" << endl;
  cout << "food, and the massive population" << endl;
  cout << "your father left you on these three" << endl;
  cout << "measly planets, what are you waiting for?" << endl;
  cout << "Start buying some weapons! Do what" << endl;
  cout << "nobody in your family has done before!" << endl;
  cout << "CONQUER! DESTROY! YOU can rule" << endl;
  cout << "the universe if you TRY!" << endl;
 
 

case '5': //Finished so set finished 'true' to break out ofloop
            finished=true;
            cout<<"Exiting....\n";
            break;
  default:  //If choice !=1/2/3 then do what it says here
            break;

            //  end functions
          }
  choice='\0'; //NULL
 }
 return 1;
 
     
  }
 }
}


somnium 10-20-2005 09:54 PM

First of all, it's way more complicated than it should be. Just like what I said before, you're just looking to introduce bugs this way (unclean/overly complicated code).

Why is choice a char? make it an int since it doesn't matter, and you don't have to screw with escape characters, etc.

I don't exactly get what you're doing here. You're printing out menus, one after the other and only checking if they ever pick the `1` option?

In the default, it's could be 2 or 3 because you never checked for those.

I'm having a hard time keeping everything straight. Tried to help you but i think there's got to be huge parts missing because, honestly, it doesn't really make too much sense as a whole...

rsheridan6 10-20-2005 10:24 PM

You forgot to use braces with your if statements.

The syntax is :
if(condition) {
do_stuff...
}

You can omit the braces if and only if do_stuff... is a single line. So the line if(choice=='1') followed by statements not wrapped around braces checks whether choice=='1', does nothing with the result, and goes on and executes the following statements as if the 'if' statement had never been there in the first place.

You haven't noticed this bug yet, but you also forgot to put "break;" at the end of your case statement.

Some advice - try to find and read other people's code to get an idea of how to structure your programs and name your variables. This code looks really weird, and as was mentioned, that's a formula for bugs and code that you can't understand.

nadroj 10-20-2005 11:10 PM

this doesnt really solve anything, but should probably be used instead:
after you check for 'y', in the list of output you produce, you dont need to have a cout at every line. you can have all of that output in one cout command.
ie:
Code:

cout << "Well...Here you are. Just another new" << endl
<< "emperor with a hoard of cash, some" << endl
<< "food, and the massive population" << endl
<< "your father left you on these three" << endl
<< "measly planets, what are you waiting for?" << endl
<< "Start buying some weapons! Do what" << endl
<< "nobody in your family has done before!" << endl
<< "CONQUER! DESTROY! YOU can rule" << endl
<< "the universe if you TRY!" << endl;


dmail 10-21-2005 03:31 PM

Code:

  std::string play;
  std::string news;
  std::string rankings;
  std::string hof;
  std::string yes;
  std::string no;
  std::string name;

you have included the whole namespace by saying "using namespace std;" so there is no need to use std::string;

Code:

// Start main menu
 
  cout << "Welcome To Space Empires By Andrew Wilkie 2005";
  cout << "  \n\n";
  cout << "\n 1 --> "  << play; 
  cout << "\n 2 --> "  << news;               
  cout << "\n 3 --> "  << rankings;
  cout << "\n 4 --> "  << hof;
  cout <<" \n 5 --> Exit \n";
  cin >> choice;
  cout<<"\n\n";

ok you have ask it they want to play and got the answer.

Code:

switch(choice)
 {
 case '1':cout << play << endl;
          cout << ".1" << play;
          cin >> choice; // get answer from user

you entered the above case statement because they wanted to play, yet you have asked them again??

Code:

       
 if(choice=='1')
  { 
  cout << "Play Space Empires YES/NO?" << endl;
  cout << "\n 1 --> " << yes;
  cout << "\n 2 --> " << no;
  cin >> choice;

now you have just asked for the third time if they want to play?? if it was me i would answer no at this point.

Code:

if(choice=='1')
  {
  cout << name << endl;
  cin >> name;
  cout << "do you wish to use --> " << name << endl; // ask user yes/no?
  cout << "\n 1 --> Yes" << endl;
  cout << "\n 2 --> No"  << endl;
  cin >> choice;

here you have overwritten the string name. what if the player does not want to use this name?? if you ever do
cout <<name <<endl;
cin >>name;
it will not output the sentence you filled name with in the start.

Code:

return 1;
 
     
  }
 }
}

you really need to look at your placing of brackets, here the return 1 in main is inside your while statement(or from what i can tell it looks like).
heres a tip(use it or dont, its up to you) to make code more readable with conditional statements etc i indent code like this:
Code:

int func()
{//note i put this on the next line ;)
        if(! close)
        {
                //do something here
                ;
        }
        //nested if
        if (foo)
        {
              //something here
              ;
              if(bar)
              {
                    //do something
                    ;
                }
          }
        return 1;
}

this way it makes it easier to see where the scope is etc,
happy coding;)

twirl 10-21-2005 03:59 PM

Hi,

Thankyou very much for your reply's i have fixed the code and i am now working on the logical part :( the fun part hehe) .

twirl

:-)

segin 10-21-2005 05:18 PM

Maybe you should try writing it in strict C. I m not joking. Just try.

Orkie 10-22-2005 05:26 AM

If I'm right in assuming that this is going to be a text adventure, then I think that C is going to be a pain. C++ streams make reading individual words easy whereas in C, scanf is a function which requires some thinking about before using it.


All times are GMT -5. The time now is 03:44 AM.