Hi there. I recently tried to program a short text-based version of your generic point and click adventure. I thought I had everything running smoothly, but unfortunately I lost all my code due to a drive dying
However, I have re-written most of the code, and now I have a strange problem I can't seem to figure out. I know my code is horrible thus far, I'm yet to clean it all up and take out all the system("pause") instances (as I have been advised against using them), but before I do this I want to make sure I have everything working well enough for me to be happy with it.
If you look at this code, however, you'll see that there is a relatively large problem.
When the option arrives for the player to either examine the current room or leave it, the loop is either skipped entirely, or it will change the room the player is in to the hallway
#include <iostream>
#include <string>
struct Enemy
{
std::string m_name;
int m_health;
int m_inRoom;
};
struct Room
{
std::string name;
int height;
int width;
};
struct House
{
Room rooms[6];
};
struct Player
{
std::string m_playerName;
bool m_hasWeapon;
int m_playerRoom;
int m_health;
};
int main()
{
House theHouse;
theHouse.rooms[0].name = "Dark room";
theHouse.rooms[1].name = "Hallway";
theHouse.rooms[2].name = "Kitchen";
theHouse.rooms[3].name = "Bedroom";
theHouse.rooms[4].name = "Bathroom";
theHouse.rooms[5].name = "Living room";
std::cout << "Welcome, friend.. TO GENERICO!\n\n";
system("pause");
std::cout << "You wake up in a dark room, the only thing you can make out is a door, and you\nhave no idea where you are\n\n";
Enemy killer;
killer.m_name = "Masked man";
killer.m_health = 10;
killer.m_inRoom = 3;
Player player1;
player1.m_health = 10;
player1.m_playerRoom = 4;
player1.m_hasWeapon = false;
std::cout << "What is your name?\n";
std::cin >> player1.m_playerName;
std::cout <<"\nWelcome, " << player1.m_playerName << "\n";
std::cout << "You are in the " << theHouse.rooms[player1.m_playerRoom].name << "\n";
if(killer.m_inRoom != player1.m_playerRoom)
{
std::cout << "You appear to be alone, but can hear someone moving around the house\n";
}
elseif(killer.m_inRoom = player1.m_playerRoom)
{
std::cout << "You come face to face with a masked man, brandishing a knife\n";
}
std::cout << "You may examine the room(examine), or move to another(move)\n\n";
std::string Choice;
while (true)
{
std::cin >> Choice;
if (Choice == "examine")
{
if (player1.m_playerRoom = 0)
{
std::cout << "You are barely able to make out what is around you, but you see nothing of interest\n";
}
elseif (player1.m_playerRoom = 1)
{
std::cout << "You are in a long hallway. You can make out a few doors, but nothing more of interest\n";
}
elseif (player1.m_playerRoom = 2)
{
std::cout << "You are in the kitchen. You notice many useful objects laying around, but the most obvious"
<< "is the knife sitting on the counter. Do you take the knife? (yes or no)\n";
std::string takeKnife;
{
std::cin >> takeKnife;
if (takeKnife == "yes" || takeKnife == "Yes")
{
player1.m_hasWeapon = true;
}
elseif (takeKnife == "no" || takeKnife == "No")
{
player1.m_hasWeapon = false;
}
else
{
std::cout << "You may want to consider whether or not you want this knife..\n";
}
}
}
elseif (player1.m_playerRoom = 3)
{
std::cout << "You are in the bedroom.\n";
}
elseif (player1.m_playerRoom = 4)
{
std::cout << "You are in the bathroom. I don't know what you were expecting, but there isn't anything worth while in here\n";
}
else
{
std::cout << "You are in the living room. Ironically, you're standing over a body. Maybe you should leave here\n";
}
}
elseif (Choice == "move")
{
std::cout << "Pick a room to move to\n";
}
std::cout << "You are in the " << theHouse.rooms[player1.m_playerRoom].name << "\n";
}
system("pause");
}
Any help you can give me with this would be much appreciate, but once again, please ignore the current sloppiness of the code
Rather than std::cin for the name you might want to use getline(cin, player1.m_playerName). This retrieves a whole line from the screen to assign to string name and let's people have names with space. This (not clearing stream) is also causing problems later on (I put in name 'Tony F'):
Fyou are in the bathroom.
Perhaps you should clear cin?
Here you ask what room...
1 2 3 4
elseif (Choice == "move")
{
std::cout << "Pick a room to move to\n";
}
But you do not prompt for any input?
std::cout << "You may examine the room(examine), or move to another(move)\n\n";p
That needs to go inside your while loop at the top, to tell us each time we can do something.
The program isn't fully finished currently, so there will be a prompt for an input there, I was just trying to iron out the other flaws before I moved on again
Thanks for the getline tip though :)
Bit of a nooby question, but how would I clear cin?
EDIT: Also, any suggestions to cleaning up my code? The goal is to go the kitchen, get the knife, then go to the bedroom and slay the enemy, but I don't want to have to have all these options every time you enter a new room. Is there a way to loop back to a certain line?
cin.clear() will clear the input buffer. It can take any status bits as a parameter to clear that bit, and if you want to clear multiple status bits you can use the | bitwise operator to combine them. If you pass it no parameters it will clear all of eofbit, failbit and badbit for you.
While we're on the topic of clearing buffers, you should use std::endl instead of '\n' because std::endl will clear the output buffer for you so if your program suddenly crashes things don't go to hell. If you're determined to use '\n' you should at least include std::flush at the end of all of your inputs.
As for cleaning up your code, I would recommend removing most of the curly braces your program. All of the blocks that are just one statement don't need braces, removing them will make your code easier to read and fewer lines. Also, placing braces on the same line as the keyword usually looks a lot better (but it is personal preference).
if your program suddenly crashes things don't go to hell. If you're determined to use '\n' you should at least include std::flush at the end of all of your inputs.
I don't get it. Your program crashed ¿what are you worry about?
Flushing every time kind of defeats the purpose of the buffer.
Your program crashed ¿what are you worry about?
Flushing every time kind of defeats the purpose of the buffer.
You have to worry about the fact that your program crashed. Flushing the buffer after every output statement ensures that you don't have anything left in the buffer ,and that everything gets printed out. This is incredibly useful in locating bugs so you're not staring at code for hours thinking something didn't execute, when the buffer was just never written.
Use a debugger and perform a backtrace. Then you will know the place where the program crashed (not what caused it though)
However outputting alusive messages with relevant information can be helpful
In that case I suggest to use cerr, which is unbuffered.
It is a separated streams so you can use redirection to observe only the debug messages
$ ./a.out 1>/dev/null
It makes it easier to locate and eliminate them for the release. Wonder if there is a way with macros, so you don't have to touch the code.