text games

Started by
14 comments, last by Aardvajk 17 years, 9 months ago
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.


I'm afraid that is just plain wrong.

Would you care to share where you got this information from? My concern is that a lot of beginners use this site and I would hate to see misinformation spread via these forums.

Paul
Advertisement
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&lt;std::string, std::string&gt; 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-&gt;second);  }  void display(); // to implement  // other stuff?};typedef std::map&lt;std::string, Room&gt; 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-&gt;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-&gt;neighbour(desiredExit);    if (!target) {      std::cout &lt;&lt; "Can't go that way." &lt;&lt; std::endl;    } else {      location = target;      location-&gt;display();    }  }}
I'm using Beginning c++ Game programing by Michael Dawson. I was wrong about the array thing, I was thinking of vectors.

This is what I was thinking of:
#include <iostream>#include <vector>using namespace std;int main(){vector<string>x(10,"akjasf;pjs");for (int i = 0; i < 10; i++)cout<<x<<endl;system("pause");}


Sorry about this misinformation.

The return thing works just fine. I'm going to read up on the map container, but for this program I think I will just loop through the rooms.

I started over and got it all to work. Thanks for all the help and examples. Is there any way to clear the screen of the text the program puts on it while it's still running?
Quote:Original post by 2122
The return thing works just fine.


Assuming you mean that "return x, y" works for returning both x and y, would you care to show me how you actually retrieve both those values?

int func(){    return 1, 2;}a, b = func(); // ?


Also, AFAIK, these is no standard way to clear the console, except by printing a lot of std::endl. You might try system("cls") though, that should work.
2122 - sorry to keep on but I should just clarify:

The return thing only APPEARS to work fine. What is actually happening is that the first value is being evaluted, then discarded then the second value is being evaluated and returned. This is due to C++'s comma operator.

Thus:

return 1,2;

is EXACTLY THE SAME AS

return 2;

This topic is closed to new replies.

Advertisement