I am trying to create a text based adventure game in c++ for my school project. The roblem i am having is that my gameover() function needs to be able to goto my begin() function. The problem is begin must be declared before before the gameover() function to allow it to go to begin(), only i have other functions that also need to access gameover(. In short i need a way to be able to tell my program to goto the function gameover() or begin(), and know that it exists and is declared.
Thanks, Simon
void begin() {
int name;
int choice1;
system("cls");
cout << "To start your adventure, please enter your name." << endl;
cin >> name;
cin.ignore();
system("cls");
cout << "Hello " << name << " Your adventure now begins.... Who knows what's in store for you!" << endl;
system("pause");
system("cls");
cout << "You find yourself in a dark, cramp library. " << endl;
cout << "You don't know how you got here, or where you are." << endl;
cout << "Luckily there is a sword laying on the ground next to you \nand an open door in front.\n" << endl;
cout << "What will you do?" << endl;
cout << "1. Pick up the sword" << endl;
cout << "2. Walk forward through the door" << endl;
cout << "3. Use the sword to end your miserable existence!" << endl;
cin >> choice1;
cin.ignore();
system("cls");
if (choice1 == 1) {
cout << "You quickly pick up the sword and run through the door." << endl;
system("pause");
road();
}
else if (choice1 == 2) {
cout << "While you make you way to the door...." << endl;
cout << "You somehow managed to trip on the sword." << endl;
cout << "You fall on the hilt smashing your neck, and end your painfully short life. " << endl;
system("pause");
gameover();
}
else {
cout << "That wasn't an option....." << endl;
cout << "You have now broken the game. Good day Sir!!!" << endl;
}
}
void gameover() {
int choice_b;
cout << " Oops! You died.... Try Again." << endl;
cout << "\n1. Start Again!" << endl;
cout << "2. Exit" << endl;
cin >> choice_b;
cin.ignore();
system("cls");
if (choice_b == 1) {
begin();
}
else if (choice_b == 2) { std::exit; }
}
C++ require you to describe the function before its calling statement. if you are going to add definition at top of main() then its call statement will work anywhere and second option is to declaration of function before calling. Its up to you that where you want that function to accessible.
Basically if you add some declaration in header file or in top of main then these functions will work anywhere
#include headerfiles....
void begin(); //
void end(); // Function prototypes
int main()
{
.....
begin(); // Will work here
}
Add the header file containing the declaration of fucntion begin and gameover or add declaration by yourself by adding void begin(); and void gameover() before their first use.
You should just add a function declaration like this in the top of the file (or above the gameover() function):
void begin();
The solution is to decouple the gameover and begin functions. Consider this:
bool continueGame = true;
void gameover()
{
//your gameover code
if (userChoosesToExit) continueGame = false;
}
void begin()
{
//your begin code
if (playerDies) gameover();
}
void controllerFunction()
{
while (continueGame)
{
begin();
}//while
}//controller
This way, after gameover, the program control will exit the begin function and if continueGame is still true, the while loop will continue looping and begin will be called again. This way, you'll also be able to call the begin and gameover functions whenever you want, from the controllerFunction. It's just a matter of logic structuring. With this hint, you'll be able to come up with a logic that's smarter than what I posted.
Your code is unnecessarily recursive: begin() calling gameover() calling begin() calling...
It would be better to have an outer loop that calls the necessary functions, like
int gameover()
{ // ...
// if (choice_b == 1) {
// begin();
// }
// else if (choice_b == 2) { std::exit; }
return choice_b;
}
int i = 0;
while (i != 2)
{ begin();
// ...
i = gameover();
}
Related
I'm running the following code:
#include <iostream>
using namespace std;
string response(bool isMale, bool isTall)
{
if (isMale && isTall) {
cout << "MALE AND TALL" << endl;
}
else if (isMale || isTall) {
cout << "MALE OR NOT TALL" << endl;
}
else {
cout << "ELSE" << endl;
}
}
int main()
{
response(true, true);
response(false, true);
response(false, false);
return 0;
}
the output is the following:
MALE AND TALL
Process returned -1073740940 (0xC0000374) execution time : 1.460 s
Press any key to continue.
Why isn't the output?:
MALE AND TALL
MALE OR NOT TALL
ELSE
A different forum post hinted at a global value not being reset. I don't really know what to make of that.
I would appreciate any help
void response(bool isMale, bool isTall){
if (isMale && isTall) {
cout << "MALE AND TALL" << endl;
}
else if (isMale || isTall ){
cout << "MALE OR NOT TALL" << endl;
}
else {
cout << "ELSE" << endl;
}
}
You need to change function return type "string" to "void".
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);
#include <iostream>
using namespace std;
void show_menu ()
{
cout << "Welcome" << endl;
cout << "1) Match line-up" << endl;
cout << "2) Match result" << endl;
cout << "3) Quit program" << endl;
}
int selection ()
{
cout << "Select option" << endl;
int input;
cin >> input;
return input;
}
int process (int x)
{
switch(x)
{
case 1:
cout << "Line ups" << endl;
case 2:
cout << "Arsenal 3 - Crystal Palace 0" << endl;
case 3:
cout << "Quitting" << endl;
default:
cout << "Select Option1" << endl;
}
}
int main ()
{
show_menu();
int input2 = selection ();
process(input2);
return 0;
}
So this is a code for some menu and input option, i wrote it as a exercise on subroutins, but in the function below i had a problem that i solved throgh some trile and arror, but still i dont get it.
int process (int x)
{
switch(x)
{
case 1:
cout << "Line ups" << endl;
case 2:
cout << "Arsenal 3 - Crystal Palace 0" << endl;
case 3:
cout << "Quitting" << endl;
default:
cout << "Select Option1" << endl;
}
}
Why do i need the variable (int x) in order dor this function to work?
i have a feel that i dont understand something very basic. pls help)
OK , so the function name is process (meaning you need to process something)
NOW , in order for your function to process something you need to give it that thing to be processed , right?
and the x variable which is an int data type ( int data type because it reflect the same value that was assigned inside your main method "input") is your argument that will be matched with the proper switch case as specified inside your process function.
one more thing , since you are not returning anything through your function , you don't need to declare it as an int , you only need to declare a data type for a function when you return the same data type , so in this case your function could be void.
hope this will help :)
The switch part checks whether the value of int x is 1,2,3 or default(something other than 1,2 and 3) and take the appropriate action(the different cout for each case).
There is no way for it to check the value of int x if you don't pass int x to the process function. I hope this makes things clear.
So heres what im trying to do with my text based rpg now. I want to clean up my main.cpp so that it isnt so long and cluttered, so I am creating a few different cpp files that will hold related items.
I have a maketoon.cpp file that will go through some switch statements that will set all the modifiers(str, int, agl, maxhp) based on the class they choose(class being like lumberjack doctor etc not classes in the object sense of things).
when setting the variables in the maketoon.cpp(within a function called makeMainPlayer() ) i use setters that i made within my createcharacter.h file.
So before you look at my code below, i have a few questions.
1)Where should i create the object(main.cpp, maketoon.cpp). Currently i was creating the object Player in the maketoon.cpp file but im getting these errors:
||=== Build: Debug in 6_days_to_escape (compiler: GNU GCC Compiler) ===|
C:\...\maketoon.cpp||In function 'int makeMainPlayer()':|
C:\...\maketoon.cpp|5|error: 'startChoices' was not declared in this scope|
C:\...\maketoon.cpp|6|error: 'name' was not declared in this scope|
C:\...\main.cpp||In function 'int main()':|
C:\...\main.cpp|39|error: 'Player' was not declared in this scope|
||=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
2)Should i capitalize the first letting in my object name?
3)how do i call makeMainPlayer in my main.cpp so set that specific objects values to then start the game?
4)Lastly, when i was testing to see if the setters and getters were working, i was getting another Player not declared in this scope error, so i tried just banging out another CreateCharacter Player;at the start of my int main, but i feel that will overwrite all the values set in the later functions, with the default null values.
Also. I know nothing about pointers, but if that is the best way to go(some google searches popped up with this as a fix to similar scenarios)
Seriosly thanks a ton! Im trying to teach myself OOc++ and it is proving difficult. Getting lost in the online tuts and youtube tuts.
//main.cpp
//game rpg
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <conio.h>
#include "createcharacter.h"
#include "maketoon.cpp"
using namespace std;
//is running check
bool running = 1;
//int healedHP(int x, int y);
//int attackedHP(int x, int y);
//user input var+
int userInput = 0;
int startChoices[4] = {0, 0, 0, 0};
string name;
//function declarations
void theStart();
void newGame();
int main (){
void makeMainPlayer();
cout << "Enter your name." << endl;
cin >> name;
cout << "Welcome " << name << "." << endl;
cout << "Strike any key....if you dare......";
getch();
system("cls");
theStart();
makeMainPlayer();
cout << "Name: " << Player.getplayerName() << endl;
cout << "Health: " << Player.getplayerHealth() << endl;
cout << "Strength: " << Player.getStr() << endl;
cout << "Int: " << Player.getInt() << endl;
cout << "Agility: " << Player.getAgl() << endl;
cout << "Difficulty: " << Player.getDifficulty() << endl;
system("pause");
return EXIT_SUCCESS;
}
void theStart()
{
cout << "\n\n";
cout << "\t6 Days to Escape!\n"; //title
cout << "\t\t 1: Play\n"; //main menu options. The first thing the user sees.
cout << "\t\t\t 2: Exit\n";
cin >> userInput;
system("cls");
if(userInput == 1)
{
// Create a new game
newGame();
}
else
{
//bool then false causeing program to exit
running = 0;
}
return;
}
void newGame(){
// there are 4 addresses in this array for the following:
//0. Difficulty
//1. Class
//2. Starting Wep
//3. Boost not implimented yet TODO
//enum class difficulty{simple, easy, hard, impossible};
do{
cout << "Choose Your difficulty: " << endl;
cout << "\t1. Simple - Game practically plays itself." << endl;
cout << "\t2. Easy - Not that easy." << endl;
cout << "\t3. Hard - Zombies do more than crave flesh." << endl;
cout << "\t4. Impossible - You will not make it." << endl;
cin >> startChoices[0];
cout << endl;
system("cls");
if(startChoices[0] < 1 || startChoices[0] > 4){
cout << "Invalid Difficulty Choice. Try again." << endl;}
}while(startChoices[0] < 1 || startChoices[0] > 4);
do{
cout << "Choose your class:" << endl;
cout << "\t1. Lumber Jack - Stong, hard to kill, but slow." << endl;
cout << "\t2. Doctor - Healer, weak but fast. Favors health." << endl;
cout << "\t3. Theif - FAST, Cunning but weak attacks." << endl;
cout << "\t4. Everydayer - Balenced everything." << endl;
cin >> startChoices[1];
cout << endl;
system("cls");
if(startChoices[1] < 1 || startChoices[1] > 4){
cout << "Invalid Class Choice. Try again." << endl;}
}while(startChoices[1] < 1 || startChoices[1] > 4);
do{
cout << "Choose your starting Weapon:" << endl;
cout << "\t1. Axe" << endl;
cout << "\t2. Crowbar" << endl;
cout << "\t3. Swiss army knife" << endl;
cout << "\t4. Ice pick" << endl;
cin >> startChoices[2];
cout << endl;
if(startChoices[0] < 1 || startChoices[0] > 4){
cout << "Invalid Weapon Choice. Try again." << endl;}
}while(startChoices[2] < 1 || startChoices[2] > 4);
}
//----------------------------------------------------------------------------------------
//createcharacter.h
#ifndef CREATECHARACTER_H
#define CREATECHARACTER_H
class CreateCharacter{
public:
//setter
void setplayerName(std::string x){
playerName = x;}
void setwepSpeed(int v){
wepSpeed = v;}
void setplayerHealth(int h){
playerHealth = h;}
void setplayerMaxHealth(int mh){
playerMaxHealth = mh;}
void setplayerStr(int s){
playerStr = s;}
void setplayerAgl(int a){
playerAgl = a;}
void setplayerInt(int i){
playerInt = i;}
void setplayerDifficulty(int d){
playerDifficulty = d;}
void setwepbaseDmg(int j){
wepbaseDmg = j;}
//getters
std::string getplayerName(){
return playerName;}
int getplayerHealth(){
return playerHealth;}
int getMaxHealth(){
return playerMaxHealth;}
int getStr(){
return playerStr;}
int getAgl(){
return playerAgl;}
int getInt(){
return playerInt;}
int getDifficulty(){
return playerDifficulty;}
private:
std::string playerName;
int playerHealth;
int playerMaxHealth; //absolute max = 200
int playerStr; // absolute max = 20
int playerAgl;// absolute max = 20
int playerInt;// absolute max = 20
int playerDifficulty; // absolute max = 4
//items
int wepbaseDmg;
int wepSpeed;
};
#endif
//------------------------------------------------------------------------------
//maketoon.cpp
//This was my attempt based off google....
//int* startChoices[4]={getDifficulty(), get};
int makeMainPlayer(){
CreateCharacter Player;
Player.setplayerDifficulty(startChoices[0]);
Player.setplayerName(name);
switch(startChoices[1]){
case 1:
Player.setplayerMaxHealth(175);
Player.setplayerStr(18);
Player.setplayerAgl(10);
Player.setplayerInt(6);
break;
case 2:
Player.setplayerMaxHealth(200);
Player.setplayerStr(9);
Player.setplayerAgl(13);
Player.setplayerInt(15);
break;
case 3:
Player.setplayerMaxHealth(100);
Player.setplayerStr(11);
Player.setplayerAgl(20);
Player.setplayerInt(10);
break;
case 4:
Player.setplayerMaxHealth(150);
Player.setplayerStr(12);
Player.setplayerAgl(12);
Player.setplayerInt(13);
break;
}
switch(startChoices[2]){
case 1:
Player.setwepbaseDmg(40);
Player.setwepSpeed(4);
break;
case 2:
Player.setwepbaseDmg(30);
Player.setwepSpeed(5);
break;
case 3:
Player.setwepbaseDmg(25);
Player.setwepSpeed(8);
break;
case 4:
Player.setwepbaseDmg(20);
Player.setwepSpeed(10);
break;
}
return 0;
}
I am having an issue getting a vector-based inventory system to work. I am able to list the items in the inventory, but not able to allow a user-selected item to be accessed. Here is the code:
struct aItem
{
string itemName;
int damage;
bool operator==(aItem other)
{
if (itemName == other.itemName)
return true;
else
return false;
}
};
int main()
{
int selection = 0;
aItem healingPotion;
healingPotion.itemName = "Healing Potion";
healingPotion.damage= 6;
aItem fireballPotion;
fireballPotion.itemName = "Potion of Fiery Balls";
fireballPotion.damage = -2;
aItem testPotion;
testPotion.itemName = "I R NOT HERE";
testPotion.damage = 9001;
int choice = 0;
vector<aItem> inventory;
inventory.push_back(healingPotion);
inventory.push_back(healingPotion);
inventory.push_back(healingPotion);
inventory.push_back(fireballPotion);
cout << "This is a test game to use inventory items. Woo!" << endl;
cout << "You're an injured fighter in a fight- real original, I know." << endl;
cout << "1) Use an Item. 2) ...USE AN ITEM." << endl;
switch (selection)
{
case 1:
cout << "Which item would you like to use?" << endl;
int a = 1;
for( vector<aItem>::size_type index = 0; index < inventory.size(); index++ )
{
cout << "Item " << a << ": " << inventory[index].itemName << endl;
a+= 1;
}
cout << "MAKE YOUR CHOICE." << endl << "Choice: ";
cin >> choice;
^^^^
Everything above this line, works. I assume that my problem is the if statement, but I cannot figure out where I am going wrong in my syntax, or if there is a better way to do what I am doing.
if (find(inventory.begin(), inventory.at(choice), healingPotion.itemName) != inventory.end())
cout << "You used a healing potion!";
else
cout << "FIERY BALLS OF JOY!";
break;
case 2:
cout << "Such a jerk, you are." << endl;
break;
}
EDIT: I think I'm not representing this correctly. I need for the player's choice to affect the message displayed. Here's a sample output of the 1st snippet:
Item 1: Healing Potion
Item 2: Healing Potion
Item 3: Healing Potion
Item 4: Potion of Fiery Balls
MAKE YOUR CHOICE.
Choice:
From there, the player can type 1-4, and what I would like is for the number (minus 1, to reflect the vector starting at zero) to be passed to the find, which would then determine (in this small example) if the item at inventory[choice - 1] is a healing potion. If so, display "You used a healing potion!" and if it is not, to display "Fiery balls of joy".
Three problems.
One, Your operator should be declared as:
bool operator==(const aItem& other) const
Two, in this code:
find(inventory.begin(), inventory.at(choice), healingPotion) != inventory.end())
you aren't searching the whole vector from begin() to end() -- you're only searching from begin() to at(choice) where at(choice) points to one-past-the-end of your search set. So you either should do this:
find(&inventory.at(0), &inventory.at(choice), healingPotion) != &inventory.at(choice))
or this...
find(inventory.begin(), inventory.end(), healingPotion.itemName) != inventory.end())
Edit Three, you are trying to compare apples to oranges. You are searching a vector of aItem objects to find a matching aItem object, but the parameter you send to find isn't an aItem object, it is one of the aItem data members.
You should either search for a matching item, like this:
find( inventory.begin(), inventory.end(), healingPotion ) != inventory.end() )
^^^^^^^^
In C++03 you can provide a functor:
#include <functional>
struct match_name : public std::unary_function<aItem, bool>
{
match_name(const string& test) : test_(test) {}
bool operator()(const aItem& rhs) const
{
return rhs.itemName == test_;
}
private:
std::string test_;
};
... and then search for a match using find_if:
find_if( inventory.begin(), inventory.end(), match_name(healingPotion.itemName) ) // ...
In C++11 you can simplify this mess using a closure:
string test = healingPotion.itemName;
if( find_if( inventory.begin(), inventory.end(), [&test](const aItem& rhs)
{
return test == rhs.itemName;
}) == inventory.end() )
{
// not found
}
To add onto John Dibling's answer, the last part is that you are looking for a name, not an aItem.
So it either needs to be:
find(inventory.begin(), inventory.end(), healingPotion) != inventory.end();
where the operator== is defined as:
bool operator==(const aItem& other) const
{
return itemName == other.itemName;
}
Or you need to have your operator== take a string:
find(inventory.begin(), inventory.end(), healingPotion.itemName) != inventory.end();
where the operator== is defined as:
bool operator==(const std::string& name) const
{
return itemName == name;
}
Instead of:
case 1:
cout << "Which item would you like to use?" << endl;
int a = 1;
for( vector<aItem>::size_type index = 0; index < inventory.size(); index++ )
{
cout << "Item " << a << ": " << inventory[index].itemName << endl;
a+= 1;
}
cout << "MAKE YOUR CHOICE." << endl << "Choice: ";
cin >> choice;
if (find(inventory.begin(), inventory.at(choice), healingPotion.itemName) != inventory.end())
cout << "You used a healing potion!";
else
cout << "FIERY BALLS OF JOY!";
break;
case 2:
cout << "Such a jerk, you are." << endl;
break;
}
I neglected to realize that one of the wonders of vectors is the ability to access the value directly- Ryan Guthrie mentioned this in his comment, but I found a simpler "answer". Namely:
case 1:
cout << "Which item would you like to use?" << endl;
//TODO: Learn what the hell the following line actually means.
for( vector<aItem>::size_type index = 0; index < inventory.size(); index++ )
{
//Makes a numerical list.
cout << "Item " << index + 1 << ": " << inventory[index].itemName << endl;
a+= 1;
}
cout << "MAKE YOUR CHOICE." << endl << "Choice: ";
cin >> choice;
//Cannot define this outside of the statement, or it'll initialize to -1
invVecPos = (choice - 1);
//This checks for an invalid response. TODO: Add in non-int checks.
if ((invVecPos) >= inventory.size())
{
cout << "Choice out of bounds. Stop being a dick." << endl;
}
//If the choice is valid, proceed.
else
{
//checking for a certain item type.
if(inventory[invVecPos].itemType == "ITEM_HEALTHPOT")
{
cout << "You used a healing potion!" << endl;
//this erases the potion, and automagically moves everything up a tick.
inventory.erase (inventory.begin() + (invVecPos));
}
else if(inventory[invVecPos].itemType == "ITEM_FIREPOT")
{
cout << "FIERY BALLS OF JOY!" << endl;
}
else
{
//error-handling! Whee!
cout << "Invalid Item type" << endl;
}
}
break;
case 2:
cout << "Why do you have to be so difficult? Pick 1!" << endl;
break;
Thank you, Ryan- with your prodding, I was able to look elsewhere and find the code I needed! The "fixed" code is commented heavily, so anyone else who runs into issues should be able to glean what they need!