text games

Started by
14 comments, last by Aardvajk 17 years, 9 months ago
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.
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)
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]
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.
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
"Mommy, where do microprocessors come from?"
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.
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!
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++?
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!).
"Mommy, where do microprocessors come from?"
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 loopvoid end_game();   // end our gamevoid getInput();   // get user inputvoid wrongway();   // when the wrong direction is chosenvoid showRoom();   // display the room name and description#endif
"choices always were a problem for you......" Maynard James Keenan

This topic is closed to new replies.

Advertisement