I am new to c++ and am trying to make a simple text based game. The code below is supposed
to welcome the user to the game and ask whether or not the user wants to start the game. I don't get any build errors, but when I run it all it shows is a blank screen. What exactly am I doing wrong?
Code below:
string D1(string Original)
{
cin >> Original;
return Original;
}
int main ()
{
string Decision1;
cout << "Welcome to [game name]" << endl;
cout << "Would you like to start the game?" << endl;
cout << "Yes/No" << endl;
string D1(Decision1);
system("cls");
if (Decision1 == "Yes")
{
cout << "this happens" << endl;
}
else if (Decision1 == "No")
{
cout << "that happens" << endl;
}
}
You have to call D1, not create a new variable named D1:
std::string D1()
{
std::string Original;
std::cin >> Original;
return Original;
}
int main ()
{
std::cout << "Welcome to [game name]" << std::endl;
std::cout << "Would you like to start the game?" << std::endl;
std::cout << "Yes/No" << std::endl;
auto Decision1 = D1();
system("cls");
if (Decision1 == "Yes")
{
std::cout << "this happens" << std::endl;
}
else if (Decision1 == "No")
{
std::cout << "that happens" << std::endl;
}
}
string D1(string Original) should be string D1(string& Original) (ie: passing with reference)
and
string D1(Decision1); in main should be
D1(Decision1); because
string D1(Decision1); actually declares a new string variable, called D1 (same name as the function) and initializes it with the value of Decision1
This statement
string D1(Decision1);
is a definitiom of an object of type std::string with name D1 that initialized by object Decision1. As the object Decision1 is empty then and object D1 is empty.
What you meant is the following
void D1( string &Original )
{
cin >> Original;
}
//...
D1( Decision1 );
or the following
string D1()
{
string Original;
cin >> Original;
return Original;
}
//...
Decision1 = D1();
Take into account that if you use two if statements
if (Decision1 == "Yes")
{
cout << "this happens" << endl;
}
else if (Decision1 == "No")
{
cout << "that happens" << endl;
}
then you have to add a third statement with else because the user can enter neither "Yes" nor "No". Also you should compare strings independently of their case (upper case or lower case). So you have to convert strings to some common case.
For example
#include <cctype>
//...
for ( char &c : Decision1 ) c = std::toupper( c );
if ( Decision1 == "YES" )
{
cout << "this happens" << endl;
}
else if ( Decision1 == "NO" )
{
cout << "that happens" << endl;
}
else
{
//...
}
P.S. And here in comments there was suggested book "Programming -- Principles and Practice Using C++. " I do not advice this book for beginners. In fact it is a bad book for beginners. You will spend much time reading the book but your knowledge of C++ will be close to zero.
string D1(string Original)
Right now, the program will make a copy of the string you pass and place it into Original, so when you come out of the function, nothing will have happened to Decision1.
What you want it to do is pass the variable by reference.
Passing a variable by reference means the function isn't receiving a copy of what was passed, but the actual variable you passed (imagine a voodoo doll). Anything you do to the variable in the function will take effect on the variable passed.
Change the function header to:
string D1(string &Original)
Related
question: every time I run the program and I input who are you it says Error Value of a is not matching what is going on? (yes I am a noob to c++)
code:
#include <iostream>
using namespace std;
int main () {
// local variable declaration:
string a;
cin >> a;
// check the boolean condition
if( a == "hello" ) {
// if condition is true then print the following
cout << "hi" << endl;
} else if( a == "who are you" ) {
// if else if condition is true
cout << "a better question is who are you?" << endl;
} else if( a == "what am i doing" ) {
// if else if condition is true
cout << "reading this output " << endl;
}else {
// if none of the conditions is true
cout << "Error Value of a is not matching" << endl;
}
return 0;
}
The operator >> for streams and strings inputs words separated by white spaces. You should use a function that can read at once several words up to the Enter key will be pressed. For example you can use standard function std::getline
Also you need to include header <string>.
Here you are
#include <iostream>
#include <string>
int main()
{
std::string s;
if ( std::getline( std::cin, s ) )
{
// check the boolean condition
if ( s == "hello" )
{
// if condition is true then print the following
std::cout << "hi" << std::endl;
}
else if ( s == "who are you" )
{
// if else if condition is true
std::cout << "a better question is who are you?" << std::endl;
}
else if ( s == "what am i doing" )
{
// if else if condition is true
std::cout << "reading this output " << std::endl;
}
else
{
// if none of the conditions is true
std::cout << "Error Value of a is not matching" << std::endl;
}
}
return 0;
}
I have made a "computer". My conctructor looks like this:
PC::PC()
{
cout << "Would you like to turn the pc on? type y for yes." << endl;
a = getchar();
while (a != 'y')
{
cout << "If you dont turn it on, then nothing will happen. Loser." << endl;
a = getchar();
}
}
Then if you press y you will be sent to the next step which is the function PC::pcOn which looks like this:
void PC::pcOn()
{
for (auto i = 0; i < 3; i++)
{
cout << "----------------------------------------" << endl;
}
cout << "--------- What is your name? -----------" << endl;
changeName();
for (auto i = 0; i < 3; i++)
{
cout << "----------------------------------------" << endl;
}
for (auto i = 0; i < 5; i++)
{
cout << "**" << endl;
Sleep(100);
}
cout << "Welcome " << name << " to the future of computing." << endl << endl;
cout << "This computer program can do a lot of things for you" << endl << "it is a good calculator, try to type \"calculater\"" << endl;
}
However when i have the while loop in the contructor to get the y to go on, the changeName(); wont work, but if i remove that, the changeName function works just fine, and it takes my input just fine.
The code for the changeName() looks like this:
void PC::changeName()
{
string _name;
getline(cin, _name);
name = _name;
}
I have tried using the Visual Studio's debugger to see why i wont call it correctly, but alas to no hope.
The weird thing is, that the function works fine if the while loop in the constructor is not there.
It is because in getline(cin, _name), it always inputs the "/n" character as it is feeded when you type enter.
To correct it, put a getchar();
void PC::changeName()
{
string _name;
getchar();
getline(cin, _name);
name = _name;
}
You need to flush cin before calling changeName(), this can be done using
int c;
while ((c = getchar()) != '\n' && c != EOF);
My biggest problems are all stated above, the inability to jump to label fin (error on line 27), the error: from here (error on lines 12 and 14) and the crosses initialization error (error on line 20) Please help!
#include <iostream>
#include <string>
int main()
{
std::string name;
std::cout << "Please comply. y/n: ";
std::string answer;
std::cin >> answer;
if (answer == "y"){std::cout << "You were spared." << std::endl; goto fin;}
if (answer == "Miche"){std::cout << "The killers understood that you understood the prophecy, so they took you to their master" << std::endl; goto secret;}
if (answer == "n"){std::cout << "You were brutally killed." << std::endl; goto fin;}
else {std::cout << "You randomly babled " << answer << ", getting yourself killed."; goto fin;}
secret:
std::cout << "In order to fully find out if you are the legendary Miche, they took you to their leader."
<< " The master looked you over, and asked you one final question. The master asks you, fish?" << std::endl;
std::string fish; fish = "none";
std::cin >> fish;
if (fish == "fish."){std::cout << "You were put in the throne of the king, where you ruled your near killers and their species for eternity."
<< std::endl; goto fin;}
else {std::cout << "You failed and were immediately killed." << std::endl; goto fin;}
goto fin;
fin:
return 0;
}
The problem is, essentially this:
int main() {
if (whatever)
goto fin;
std::string fish;
fin:
return 0;
}
If whatever is true, the goto jumps past the construction of fish. That's not allowed, because the compiler can't generate sensible code to destroy fish or not, depending on whether the goto was executed.
Solution: don't use goto.
Possibilities:
int main() {
if (whatever)
goto fin;
{
std::string fish;
}
fin:
return 0;
Here, fish gets destroyed at the end of the block, so the goto doesn't cause a problem (aside from its inherent unstructured nature).
Better:
int main() {
if (!whatever) {
std::string fish;
}
return 0;
}
You can duplicate the problem using a much simpler function.
void foo()
{
goto fin;
std::string fish = "none";
std::cin >> fish;
fin:
}
Why is that a problem? When the execution jumps to fin:, the code to initialize fish is not executed. Its destructor will be called when the function returns. Since the destructor will be called on an uninitialized object, the program will exhibit undefined behavior.
The simplest fix for your problem is to put almost everything in main in another function, and then use return instead of goto.
void do_stuff()
{
std::string name;
std::cout << "Please comply. y/n: ";
std::string answer;
std::cin >> answer;
if (answer == "y")
{
std::cout << "You were spared." << std::endl;
return;
}
if (answer == "n")
{
std::cout << "You were brutally killed." << std::endl;
return;
}
if (answer == "Miche")
{
std::cout << "The killers understood that you understood the prophecy, so they took you to their master" << std::endl;
}
else
{
std::cout << "You randomly babled " << answer << ", getting yourself killed.";
return;
}
std::cout << "In order to fully find out if you are the legendary Miche, they took you to their leader."
<< " The master looked you over, and asked you one final question. The master asks you, fish?" << std::endl;
std::string fish = "none";
std::cin >> fish;
if (fish == "fish")
{
std::cout << "You were put in the throne of the king, where you ruled your near killers and their species for eternity." << std::endl;
}
else
{
std::cout << "You failed and were immediately killed." << std::endl;
}
}
int main()
{
do_stuff();
}
I have this (I've just started to learn btw):
#include <iostream>
#include <string>
using namespace std;
int main()
{
string mystr;
cout << "Welcome, what is your name? ";
getline(cin, mystr);
cout << "Nice to meet you, " << mystr << endl;
cout << "May i call you 1 for short? (y/n)" << endl;
getline(cin, mystr);
}
I want to next say;
cout << "Thank you, 1" << endl;
OR:
cout << "Well ok, " << mystr << endl;
... based on whether or not the user has typed y or n. How would i go about this? I've had a look around but i don't really know how to word it. I'm using Visual Studio Express and it is a console application.
For a very simple way:
if (mystr == "1") {
// ...
}
But you should accustom yourself to more error checking, so check the state of the stream after getline:
getline(cin, mystr);
if (cin) {
if (mystr == "1") {
// ...
}
} else {
// error
}
And of course, you may want to support any number in the future, not just 1. Then you need to convert the input string to a number. See std::stoi if you use C++11, or look at the thousands of past Stackoverflow questions about string-to-number conversions :)
Edit: Just noticed that you actually wanted to check for "y". Well, that's the same then:
if (mystr == "y") {
// ...
}
You should use if-else statement. For example
#include <cctype>
//...
std::string name = mystr;
std::cout << "May i call you 1 for short? (y/n)" << std::endl;
std::getline( std::cin, mystr );
for ( char &c : mystr ) c = std::tolower( c );
if ( mystr == "y" )
{
name = "1";
std::cout << "Thank you, " << name << std::endl;
}
else
{
std::cout << "Well ok, " << name << std::endl;
}
Im new to programming and C++ and I started making a little string type game for fun, which gives the user two options through out the program, but in the final part of the program i cant get it to output a unique option for the final input(makeCure) - which i only want to output at the end not through out the program. Hope Im making sense :/ .Iv tried and tried and tried and the more i try the more probloms I create. Iv shown below in my code where Im sure the problom lies. Any advice would much appreciated.
#include<iostream>
#include<string>
using std::string;
bool intro(void);
void room(bool enemy, bool data, bool cure, string description);
//player stats
string Name = "";
//enemy states
string enemyName = "";
//data stats
string dataName = "";
//Cure - Option in room7 only
string makeCure = "";
//room descriptions(string constructs)
const string room1 = "You enter the first town of infected Zombies.";
const string room2 = "You are overwelmed by Zombies, and plunder into the sewers to escape.";
const string room3 = "You make your way to safety and find yourself in the Central Town Hall.";
const string room4 = "You decide to venture into the local forest to find the finalingrediants";
const string room5 = "You venture further for the final ingrediant, into a nearby Cave.";
const string room6 = "Its time for you to face the Zombie General!!!";
const string room7 = "You work day and Night in the Labs to make the Cure.";
int main(void)
{
if(intro())
return 0;
dataName = "First Ingrediant- Zombie Rags with infected DNA";
enemyName = "Zombie Soldior";
room(true, true, false, room1);
enemyName = "Massive Zombie Rat";
room(true, false, false, room2);
dataName = "Seconed Ingrediant- StemCells";
enemyName = "Mutated Scientists";
room(true, true, false, room3);
dataName = "Third Magic-Mushrooms";
room(false, true, false, room4);
dataName = "Fourth Final Ingrediant - Coffee Beans";
enemyName = "Commander Zombie";
room(true, true, false, room5);
enemyName = "Zombie General";
room(false, true, false, room6);
return 0;
makeCure = "Elixier to Save the World";
room(false, false, true, room7);
return 0;
}
bool intro(void)
{
using std::cout;
using std::cin;
cout << "Brave Soul!!! What is your name?\n";
cin >> Name;
cout << "Ahh... " << Name << " You say.." << "How about Zombie Slayer?.. Good, glad we agree!\n";
cout << "Humanity is in need of your Help, "
<< "The world is being infected by the\n"
<< "ZD1678 ZOMBIE VIRUS \n"
<< "And we need to send you to Cape Town to stop the central spread.\n"
<< "Your task will be tough, but we know you can do it \n"
<< "Will you accept the challenge?\n\n";
cout << "1)Yes. \n"
<< "2)No. \n\n";
int response;
cin >> response;
return !(response ==1);
}
void room(bool enemy, bool data, bool cure, string description)
{
using std::cout;
using std:: cin;
while(true)
{
cout << description.c_str() << "\n\n";
int response = 0;
do
{
cout << "Shall Our Hero continue his Quest?\n";
if(enemy)
cout << "1) Attack the "
<< enemyName.c_str() << "\n";
else if(!enemy)
cout << "1) venture further....";
if(data)
cout << "2)Pick up the "
<< dataName.c_str() << "\n";
cin >> response;
/* Trying to create the last if that only kicks in at room7( string makeCure )
* that displays the option to make the cure
* This is where my Problem is.
* Iv tried anouther if
* and else
* and while and nothing works, its just messes up everything..
* badly
*/
} while(response < 1 || response > 2);
switch(response)
{
case 1:
if(enemy)
{
enemy = !enemy;
cout << "You slay the deadly "
<< enemyName.c_str() << "\n";
}
else if(!enemy)
return;
break;
case 2:
data = !data;
cout << "You pick up the "
<< dataName.c_str() << "\n";
break;
}
}
}
what you probably want to do is dynamically generate a list of possible events each time you write out the list and present it to the user, then you can match the response to the list to get what the user wants to do. like this:
enum EventType
{
ET_Enemy,
ET_Item,
ET_Cure,
ET_Continue,
ET_MAX
};
void room(bool enemy, bool data, bool cure, string description)
{
using std::cout;
using std:: cin;
int currentEventChoices[ET_MAX];
int numEventChoices;
while(true)
{
cout << description.c_str() << "\n\n";
int response = 0;
do
{
numEventChoices = 0;
cout << "Shall Our Hero continue his Quest?\n";
if(enemy)
{
cout << (numEventChoices+1) << ") Attack the "
<< enemyName.c_str() << "\n";
currentEventChoices[numEventChoices] = ET_Enemy;
numEventChoices++;
}
if(data)
{
cout << (numEventChoices+1) << ") Pick up the "
<< dataName.c_str() << "\n";
currentEventChoices[numEventChoices] = ET_Item;
numEventChoices++;
}
if(cure)
{
cout << (numEventChoices+1) << ") cure related string "
<< makeCure.c_str() << "\n";
currentEventChoices[numEventChoices] = ET_Cure;
numEventChoices++;
}
cout << (numEventChoices+1) << ") venture further....\n"; // note if this is only meant to be an option if there is no enemy, put it in an else after the if(enemy)
numEventChoices++;
cin >> response;
} while(response < 1 || response > numEventChoices);
switch(currentEventChoices[response-1])
{
case ET_Enemy:
enemy = !enemy;
cout << "You slay the deadly "
<< enemyName.c_str() << "\n";
break;
case ET_Item:
data = !data;
cout << "You pick up the "
<< dataName.c_str() << "\n";
break;
case ET_Cure:
//do cure stuff
break;
case ET_Continue:
return;
}
}
}
the trouble you are having is that by just using a very static next of if/else statements each time you want to match the option number to the event, it gets very complex and messy, it was fine when there was just the 4 cases of there being an enemy or not, or data or not. but now you are adding another branch with cure, its just got really complex to do it that way.
It's a bit hard to understand what you need, so tell me if it's not what you wanted.
Using braces and indenting consistently can really help with this:
do {
cout << "Shall Our Hero continue his Quest?\n";
if (enemy) {
cout << "1) Attack the " << enemyName << "\n";
} else {
cout << "1) venture further....";
}
if (data) {
cout << "2) Pick up the " << dataName << "\n";
}
if (cure) {
cout << "2) take the " << makeCure << "\n";
}
cin >> response;
} while (response < 1 || response > 2);
and fix "case 2" in the switch part:
case 2:
if (data) {
data = false;
cout << "You pick up the " << dataName << "\n";
} else if (cure) {
// fill in ...
}
break;
Notes:
You can use endl (from std) instead of '\n'. cout << "hello" << endl;
You can pass many of your global variables as arguments, so you won't need them to be global (global is bad, in general).
Much of your game can be be squeeszed into arrays and structs - being "data driven" and "table driven". I don't know if you got there already, but you can try and identify these parts.
if(enemy) ... else if(!enemy) you don't need the !enemy part. it is implied by the else.