Jump to content
  • Advertisement
Sign in to follow this  
2122

text games

This topic is 4427 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to make one of those old text based games, but i'm have some problems moving the player from room to room. I can't figure out how to transition to the next room object. Also, one of my variables is being changed and I can't figure out why. The description of the room the player starts in changes when you tell it you want to go north. You can't actually go anywhere yet because I can't figure out how to get the next room. Sorry if this seems vague, but it the best way I can think of to phrase it. I'm going to post the code, sorry it's so long. //main.cpp //main file #include <iostream> #include "room.h" #include "player.h" using namespace std; int main() { //SETUP //create 3 rooms room r1("A Room.",1); r1.setexit(1,"n","r2"); room r2("A big room.",2); r2.setexit(1,"n","r3"); r2.setexit(2,"s","r1"); room r3("A bigger room.",3); r3.setexit(1,"s","r2"); //create a player and put the player in room 1 player p1; p1.setrnum(r1); // //intro (*p1.getroom()).getdesc(); (*p1.getroom()).dispexits(); //main loop while(true) { string in; cin>>in; if (in == "quit") break; if (in == "look") { (*p1.getroom()).getdesc(); (*p1.getroom()).dispexits(); } if (in == "n") { if ((*p1.getroom()).checkexit("n")) { int num = (*p1.getroom()).checkexit("n"); string t = (*p1.getroom()).getexitto(num); cout<<t<<endl; } else cout<<"There is no way to go that way.\n"; } } system("pause"); } //room.h //room object class #ifndef ROOM_H #define ROOM_H #include <iostream> #include <vector> #include <string> using namespace std; class room { public: room(string d, int i): desc(d), num(i) {} void getdesc() { cout<<desc<<endl; } int getnum() { return num; } void setexit(int index, string s, string toroom) { if (index <= 10) { exit[index] = s; exitto[index] = toroom; } } string getexit(int index) { return exit[index]; } string getexitto(int index) { return exitto[index]; } void dispexits() { for (int i = 0; i < 10; i++) { if (exit != "") cout<<"Direction: "<<exit<<endl; } } bool checkexit(string t) { bool check = false; int num = 0; for (int i = 0; i < 10; i++) { num++; if (exit == t) cout<<exit<<" : "<<i<<endl; check = true; } return check, num; } private: string desc; int num; string exit["",10]; string exitto["",10]; }; #endif //player.h //player header file #ifndef PLAYER_H #define PLAYER_H #include <iostream> using namespace std; class player { public: player(string n = "unknown"): name(n) {} void setname(string n) { name = n; } string getname() { return name; } void setrnum(room n) { rin = &n; rnum = n.getnum(); } int getrnum() { return rnum; } room* getroom() { return rin; } private: string name; room* rin; int rnum; }; #endif Thanks again for all the help.

Share this post


Link to post
Share on other sites
Advertisement
I only looked at a fraction of your code, but one thing that jumped out is

void setrnum(room n) { rin = &n; rnum = n.getnum(); }
which is a mistake. You're passing the room by value, after which you take the address of the argument. You can't do that.

The arguments are always placed on the stack, which is a temporary piece of memory which only exists until the moment you return from the function. By taking the address of the argument and saving it in a data member, you're storing a pointer to no-man's-land.

If you need to keep a pointer to the room, use

void setrnum(room* n) { rin = n; rnum = n->getnum(); }


(I'd suggest you use the code or source tags to make your code more readable.)
(And what do you think
return check, num;

does?)
(Also, what does

string exit["",10];
string exitto["",10];

do? I'm unfamiliar with that syntax)

Share this post


Link to post
Share on other sites
I'm pretty sure that string exit["",10] would be the same as string exit[10], since the bit in the brackets would be interpreted as the comma operator, evaluate both expressions and return the right hand one. If this is not correct, I would also be fascinated to know what it does [smile].

2122 - I'm not being funny but you seem to be inventing syntax. I'd suggest you perhaps spend a bit more time with a good C++ text book then post back when you have more specific questions.

[Edited by - EasilyConfused on July 6, 2006 4:42:51 AM]

Share this post


Link to post
Share on other sites
Not to belittle what you are doing, but if you just want to make a text adventure, there are quite a few tools out there that do all the framework stuff for you already. I recommend TADS. That will save you a lot of work and get you right to the creation of the story.

Unless on the other hand the work of creating the framework is what you are interested in, continue.

Share this post


Link to post
Share on other sites
You could always "class it up". C# would be awsome for this but C++ would work too. Basically, you have something like:

struct CRoomExit
{
char* ExitCommand; // Command that takes you there, your engine should
// automatically change "N" to "NORTH", etc..
int RoomID; // The numeric value of the room this goes to
char* ExitDescription; // When describing exits, this is displayed for
// each of the actuial exits.
}
struct CRoom
{
char* Name; // The actuial name of the room
char* ShortDescription; // What they normally see when they enter
char* LongDescription; // First time entered, or "look"
int* Items; // Items in this room
CRoomExit* Exits; // Exits valid for this room
bool Visited; // If this is false, show full desc
}


Then you can have the actuial player struct:

struct CPlayer
{
char* Name; // If this is a 3rd person game and they can choose
int CurrentRoom; // Numeric value of the current room
int* Items; // The character's inventory
int Score // The current score
}


Basically, when you are in a room you can say:

cout << Rooms[Player.CurrentRoom]->Name << endl;
if ( !Rooms[Player.CurrentRoom]->Visited )
{
cout << Rooms[Player.CurrentRoom]->LongDescription << endl;
Rooms[Player.CurrentRoom->Visited = true;
} else
{
cout << Rooms[Player.CurrentRoom]->ShortDescription << endl;
}


Now,lets say they have typed in their input, and you have decided they chose "north". You have a function that loops through the room exits. If you see north is valid, you get the room ID. Then you simply set Player.CurrentRoom to the new room, and loop back to the room description thing.

The only other thing to watch for, is if you have scripts. Like locking and unlocking a door.. For that you may have to do some additional checks before an exit can be performed.

For example, if RoomA has a north exit to RoomB, in the function where you would set the current player room, you can say something like:

if ((Player.CurrentRoom == RID_ROOMA) && (TargetRoom == RID_ROOMB))
{
if (Conditions[CID_ROOMBUNLOCKED])
{
// go to room now
} else
if (PlayerHasItem(IID_ROOMBKEY))
{
cout << "You unlook the door with your key!" << endl;
Conditions[CID_ROOMBUNLOCKED] = true;
RemovedInventoryFromPlayer(IID_ROOMBKEY);
// go to the room now
} else
{
cout << "You must have the key first!" << endl;
}
}



Just some ideas :p

Share this post


Link to post
Share on other sites
Creating the framework is interesting, I'm doing this to see if I can.

About the syntax, string exit["",10] makes an array with ten indexes, and initializes them with and empty string variable, if you put something between the quotes it initializes the array with whatever is between the quotes in all ten "slots" of the array.

return check, num;
does just that it returns both variables. I was going to use the num variable to tell wich room to pick next, thats the step I haven't figured out yet.

How do I use code tags?

I'll try Dreq's idea, but I think that leaves me with one of the same problems as before. How do I use the the room number, instead of whatever name I gave the room object when it was instantiated to work with the room?

Thanks for the responses.

Share this post


Link to post
Share on other sites
Quote:
Original post by 2122
About the syntax, string exit["",10] makes an array with ten indexes, and initializes them with and empty string variable, if you put something between the quotes it initializes the array with whatever is between the quotes in all ten "slots" of the array.

return check, num;
does just that it returns both variables. I was going to use the num variable to tell wich room to pick next, thats the step I haven't figured out yet.


Not in C++ it doesn't. I would suggest learning the lanbguage a lttle more. Good Luck!

Share this post


Link to post
Share on other sites
Quote:
Original post by 2122
Creating the framework is interesting, I'm doing this to see if I can.

About the syntax, string exit["",10] makes an array with ten indexes, and initializes them with and empty string variable, if you put something between the quotes it initializes the array with whatever is between the quotes in all ten "slots" of the array.

return check, num;
does just that it returns both variables. I was going to use the num variable to tell wich room to pick next, thats the step I haven't figured out yet.

How do I use code tags?

I'll try Dreq's idea, but I think that leaves me with one of the same problems as before. How do I use the the room number, instead of whatever name I gave the room object when it was instantiated to work with the room?

Thanks for the responses.


You can see the code tags by clicking "edit" on the posts containing code (it does indeed work on other people's posts).

Can I know which source (book/site/...) you use for learning C++?

Share this post


Link to post
Share on other sites
Quote:
I'll try Dreq's idea, but I think that leaves me with one of the same problems as before. How do I use the the room number, instead of whatever name I gave the room object when it was instantiated to work with the room?


Pretty simple, you can either A: Create a funciton called:
int GetRoomIDByName( char* RoomName )


And have it loop through all the rooms, until you find the name that matches, and simply return the index you're on.

- or (what I would do) -
Define constants. Assuming you create the rooms dynamically, instead of just having a constant array, you could have like:

int RID_STARTINGROOM = CreateNewRoom();


Ans simply reference that value whenver you want to access that room. Though if you are going to be dynamically adding AND removing rooms, for whatever reason, you would most likely have to stick to RoomName (but make sure the names are all unique!).

Share this post


Link to post
Share on other sites
here is something i did a few months ago. its simple and uses the w a s d keys to move around. i was just messing around with structers when i did it. hope it helps.

main.cpp



#include <iostream>
#include <stdlib.h>

#include "textgame.h"

using namespace std;

int main(int argc, char *argv[])
{
init_game();
run_game();
end_game();
system("PAUSE");
return 0;
}

void init_game()
{
// init person
person.health = 100;
person.position = 0;
person.alive = 1;

// init house
house[0].name = "Entrance";
house[0].description = "entryway";
house[0].north = 4;
house[0].east = 2;
house[0].west = 1;
house[0].south = -1;

house[1].name = "Den";
house[1].description = "den";
house[1].west = -1;
house[1].south = -1;
house[1].east = 0;
house[1].north = 3;

house[2].name = "Foyer";
house[2].description = "foyer";
house[2].east = -1;
house[2].west = 0;
house[2].north = 5;
house[2].south = -1;

house[3].name = "Hallway";
house[3].description = "hallway";
house[3].east = -1;
house[3].west = -1;
house[3].south = 1;
house[3].north = 6;

house[4].name = "RecRoom";
house[4].description = "RecRoom";
house[4].south = 0;
house[4].north = -1;
house[4].west = -1;
house[4].east = 5;

house[5].name = "Hall";
house[5].description = "hall";
house[5].east = -1;
house[5].west = 4;
house[5].north = 8;
house[5].south = 2;

house[6].name = "Kitchen";
house[6].description = "kitchen";
house[6].east = 7;
house[6].north = -1;
house[6].south = 3;
house[6].west = -1;

house[7].name = "Bathroom";
house[7].description = "A small bathroom";
house[7].east = 8;
house[7].north = -1;
house[7].south = -1;
house[7].west = 6;

house[8].name = "Bedroom";
house[8].description = "bedroom";
house[8].east = -1;
house[8].north = -1;
house[8].south = 5;
house[8].west = 7;

};

////////////////////////////////////////////

void run_game()
{
while(person.alive) // while the person is alive
{
system("CLS"); // clear screen
showRoom(); // show what room we are in
getInput(); // get which way they want to go
}
}

///////////////////////////////////////////

void end_game()
{
cout << "Game Over!!!" << endl;
}

///////////////////////////////////////////

void getInput()
{
char choice;

cout << " choose your direction ..." << endl;
cin >> choice;

switch(choice)
{
case 'w': // use lower and uppercase incase of caps lock
case 'W':
if(house[person.position].north != -1) // make sure the room to the north is accessable
{
person.position = house[person.position].north; // if it is person is now in that room
}
else
{
wrongway(); // else they are going the wrong way
}
break;

case 's':
case 'S':
if(house[person.position].south != -1)
{
person.position = house[person.position].south;
}
else
{
wrongway();
}
break;

case 'd':
case 'D':
if(house[person.position].east != -1)
{
person.position = house[person.position].east;
}
else
{
wrongway();
}
break;

case 'a':
case 'A':
if(house[person.position].west != -1)
{
person.position = house[person.position].west;
}
else
{
wrongway();
}
break;

default:
cout << "Invalid Entry" << endl;
break;
}

}

///////////////////////

void wrongway()
{
cout << "There is no path in that direction." <<endl;
}

///////////////////////

void showRoom()
{
cout << house[person.position].description << endl;
}








textgame.h



#ifndef _TEXT_GAME_H
#define _TEXT_GAME_H

#include <cstring>


/*
[6]-[7]-[8]
| |
[3] [4]-[5]
| | |
[1]-[0]-[2]

*/


struct ROOM
{
std :: string name;
std :: string description;
int north; // holds the element or id # of the room to the north
int south; // holds the element or id # of the room to the south
int west; // west
int east; // east
};

struct PLAYER
{
int position; // should always be the same as current_room
int health;
int alive;
};

ROOM house[9];
PLAYER person;

void init_game(); // initialize all our data
void run_game(); // run our game loop
void end_game(); // end our game
void getInput(); // get user input
void wrongway(); // when the wrong direction is chosen
void showRoom(); // display the room name and description


#endif



Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!