OP: Put your code in [source][/source] tags please. That will toss it into one of the little boxes, and preserve your indentation (you do have some of that, right?) And yeah, I have no idea where you got that idea about the string array syntax. Perhaps you are thinking of something like "std::vector<std::string>("", 10);"?
Dreq: The OP has one thing going for him that you don't: usage of std::string where appropriate. :
Rherm23: That's nice, but doesn't seem to be along quite the same lines. The OP seems to be looking for a bit more flexibility in terms of specifying directions.
Now then. It looks like the idea is:
- We have a bunch of room objects.
- Each room has a name, and a bunch of exits. Each exit has a name, and "connects to" a room.
- Given an exit name from the user, we want to find that exit in the current room, and then find the room that the exit connects to. We could do that by having a process that looks up a room by name, and then specifying the name as the exit target.
We don't need to model the actual exits - yet. However, we do need to model the process of finding an exit, and thereby an adjacent room.
We can do all of this without explicit pointers (of course, the standard library tools that we use will invoke lots of them behind the scenes on our behalf :) ). The idea is that we "look things up" by name, in an
associative container. The C++ standard library provides such a beast, called std::map.
This is basically a container which, instead of being sequential, has "keys" of arbitrary value. We can index in with a key, and, if there is an associated "value" is stored in the map, get the value.
The std::map allows us to do this indexing with the operator[], so that it looks like "natural" indexing syntax (such as you would use with an array or vector). If the key is not found, operator[] will insert a key/value pair with the provided key and a default-constructed value (for std::string, that's a blank string), and then return a reference to that default-constructed value. Otherwise, it returns a reference to the default-constructed value that was already there. That behaviour is sometimes desirable though often not. When it isn't (and we can't be sure about what keys are present), we can use lower-level access functions, as will be illustrated.
What we will do is build a global map of strings to Rooms, and in each Room, build a map of strings to strings. That per-Room map represents the exits, mapping an exit name into a Room name.
// Just relevant fragments of code are shown; this is not a complete or // working programclass Room { typedef exitmap; std::map<std::string, std::string> exits; public: // default constructor is fine so far. void connect(std::string exitname, std::string roomname) { exits[exitname] = roomname; } Room* neighbour(const std::string& exitname) { // If the exit name is found, look for the room with the room name. // If that room is found, return a pointer to it. The main loop will // hold a pointer to the current Room. // If there is no valid room to go to, return NULL. exitmap::iterator it = exits.find(roomname); return (it == exits.end()) ? 0 : findRoom(it->second); } void display(); // to implement // other stuff?};typedef std::map<std::string, Room> worldmap;worldmap world;// Add a room to the world.void add (const std::string& roomname) { world[roomname];}// Add a connection between rooms, both ways.// Add the rooms if they don't exist.void connect(const std::string& room1, const std::string& exit1, const std::string& room2, const std::string& exit2) { world[room1].connect(exit1, room2); world[room2].connect(exit2, room1);}// Get a pointer to the indicated Room.// Return NULL if it does not exist.Room* findRoom(const std::string& roomname) { worldmap::iterator it = world.find(roomname); return (it == world.end()) ? 0 : &(it->second);}// A sample main loop that handles movement between rooms, taking the user// input line as the exit name.void gameLoop() { Room* location = findRoom("start"); std::string desiredExit; while (getline(std::cin, desiredExit)) { Room* target = location->neighbour(desiredExit); if (!target) { std::cout << "Can't go that way." << std::endl; } else { location = target; location->display(); } }}