Thread: Simple Text Adventure: Need Help

  1. #1
    Unregistered
    Guest

    Simple Text Adventure: Need Help

    I've been playing around wiht c and c++ for a little while now and i wanted to try and make a game and a text adventure sounds like the easiest type. So i started to make on first i use the cin input and if than statements to descifer which choice you picked but then i would have needed goto statements to go backwards then i tryed function statements, but then the program was getting large and confusing. Could someone please give the basic program to start off with, i've been working on this for a while and i'm not getting anywhere, if someone could give me the basic program with just one or two working directions i probably could understand it then so i could continue.

  2. #2
    Registered User
    Join Date
    Sep 2001
    Posts
    412
    Well, sentence parsing is the real trick. Read an entire line of text in, send it to a parser, and have the parser return a struct that tells what the user tried.

    One method is to think of sentences like this:

    Verb * Direct Object * Indirect Object

    where * can be any number of words, and the direct object and indirect object are optional.

    So, this command:

    throw the blue rock at the evil monster

    should be recognized as:

    "throw" * "blue rock" * "monster".

    Each of these strings would translate to a numeric value, and a struct with these numbers would be returned.

  3. #3
    Ethereal Raccoon Procyon's Avatar
    Join Date
    Aug 2001
    Posts
    189
    Someone else asked a similar question a while back. You may want to look at the old thread at http://www.cprogramming.com/cboard/s...&threadid=1025 for more information (mostly in regards to the 'field' system; i.e. how you implement the different locations in the game).

  4. #4
    Unregistered
    Guest
    yeah i found that post last night after lookin for an hour. I tryed it out, i havn't gotten it to work yet though.

  5. #5
    Unregistered
    Guest
    Sorry, i looked that the stuff you told me and i'm still having trouble, i cna shot wou what i've come up wiht before but i need an actuall sample like the one i'm showing you so i cna figure it out.

    **** Try #1 ****
    #include <iostream.h>

    main()
    {
    char action[50];
    cout<<"Your standing at the intersection of two patsh east and west\n";
    cout<<"Enter Action: ";
    cin.getline(action, 50, '\n');
    if(!strcmpi("east", action) || !strcmpi("e", action))
    {
    cout<<"You goto the east";
    }
    else if(!strcmpi("east", action) || !strcmpi("e", action))
    {
    cout<<"You goto the west";
    }
    else
    {
    cout<<"Thats not an option";
    }
    }
    **** End of Try #1 ****

    **** Try # 2 ****
    #include <iostream.h>

    void START(void)
    {
    cout<<"Your standing where the path splits to the east and the west.";
    }
    void E1(void)
    {
    cout<<"You walk down the east path, you can go west.";
    }
    void W1(void)
    {
    cout<<"You walk down the west path, you can go east.";
    }

    main()
    {
    char action[50];
    START();
    cout<<"\nEnter your action: ";
    cin.getline(action, 50, '\n');
    if(!strcmpi("east", action) || !strcmpi("e", action))
    {
    E1();
    }
    else if(!strcmpi("west", action) || !strcmpi("w", action))
    {
    W1();
    }
    }
    **** End of try #2 ****

  6. #6
    Registered User EvenFlow's Avatar
    Join Date
    Oct 2001
    Posts
    422
    I tried to write a text adventure once...nearly drove me nuts
    Ramble on...

  7. #7
    Ethereal Raccoon Procyon's Avatar
    Join Date
    Aug 2001
    Posts
    189
    You're relying on functions when you should be relying on objects: structs or classes. Try this:

    Code:
    #include <iostream.h>
    #include <string.h>
    
    class area
    {
      private:
      char description[20];
      
      public:
      area(char * initdescription) {strcpy(description, initdescription);};
      void describe()              {cout << description;};
    };
    
    
    int main(void)
    {
      area house("Your house.");
      area pond("A pond.");
      area river("A gentle river.");
      area forest("A shady forest.");
      area field("A grassy field.");
    
      area * currentarea;
      
      char command[20];
      
      currentarea = &house;
      while (strcmp(command, "exit"))
      {
        currentarea->describe();
        cout << endl << "Enter command: ";
        scanf("%s", &command);
        if (!strcmp(command, "north")) currentarea = &pond;
        if (!strcmp(command, "west")) currentarea = &river;
        if (!strcmp(command, "south")) currentarea = &forest;
        if (!strcmp(command, "east")) currentarea = &field;
      }
    
      return 0;
    }
    Just add in area linking (put four area pointers in the area class, one for each direction) and objects to interact with and that's all you need for your engine.

    Do you know about pointers, structs/classes, and other relatively advanced C/C++ techniques? If not, you should definitely learn them before starting this project.

  8. #8
    I can't figure pointers out. They are weird. I also forget what the -> thing does. Also, you called that class just like a structure, is a class just like a structure with private areas in it?

  9. #9
    Unregistered
    Guest
    thankx that helped me out.

  10. #10
    Ethereal Raccoon Procyon's Avatar
    Join Date
    Aug 2001
    Posts
    189
    Pointers take a lot of practice to master, especially considering all they can be used for.

    A struct is an envelope data type containing a bunch of other data types.

    A class contains not only several data types but also a number of member functions associated specifically with the class. It also can be given access limitations (private/protected/public). The class is the foundation of most of the core C++ language.

    The -> operator is the structure pointer dereference operator: dereference combined with member access. a->b is equivalent to (*a).b

  11. #11
    Former Member
    Join Date
    Oct 2001
    Posts
    955
    try without parsing, it would make your job a lot easier, like this


    cout << "You walk to an intersection, you can go left or right" << endl << "1. Go Left" << endl << "2. Go Right" << endl << "3. Stay here";

    and then do an "if" block, or a "switch"

    Oskilian

  12. #12
    Registered User
    Join Date
    Oct 2001
    Posts
    81
    I just tryed this example, but when i want to add another direction, such as east for a second time it automatically falls through to the second east description, i use an if than block saying if the current location = field then gave them more options like east to field # 2. any suggestions on wha ti do here?

  13. #13
    Unregistered
    Guest
    My 2 cents. (I've made dozens of these.)

    I think the important thing about text adventures is to try not to code anything repetitively. Otherwise your going to end up with millions of lines of code, and it will be ugly.

    To do this, don't think of a text adventure as a linear set of "if this then thats". It isn't a book, it is a game. In a game, the player chooses their path. It will help to imagine it as an overhead Zelda type game that is described with text instead of graphics.

    Here is a simplified design document that should be sufficient for most text adventures.

    A room must contain only that which is unique to that room:
    ROOM CLASS:
    Text descriptions (maybe several if room can change looks).
    X coordinate for finding it (and adjacent rooms) in an array.
    Y coordinate for finding it (and adjacent rooms) in an array.
    Methods (functions) that are specific to this room. (ie. in room 5 you can pick up the key, which sets the value of key from 0 to 1 - see next section.)

    Public items, often of type bool (yes or no) can be kept together and accessed by room methods as appropriate. (If they pick up the key, then the item.key value is a 1. Because item.key value is a 1, you can no longer find it under the rug, because you already have taken it, and you can now open the locked door.....)
    ITEMS OBJECT:
    Keys.
    Puzzles.
    Monsters.
    Items.
    Anything that can be used all over the map.

    Finally, you want a main game loop:
    1. Output current surroundings for player. This is done by calling a room specific method that will display the appropriate description (if there are more than 1 possible).

    2. Get player input. You should probably start with simple instructions: N for North, E, S, W, H for help, and A for action will do just fine. Eventually this can be replaced with a parser.

    3. If player input isn't understood (isn't an option) then display random text berating player so they know they should do better (maybe show them their options too, eh?)

    4. Run the current rooms method for room specific stuff now that you know what the player wants. This may include changing the room number (which you've probably used an array to represent). If I am in room[3][3] and I went north, (and all went well), I am now in room[3][2]. Nothing but the variable must change for this to take effect, because when the loop starts over, the new description and such will be outputted. You might just have the method print something like, "You go north."

    5. Check to see if this move has ended the game. If so, run an end game sequence. If not, return to step 1.



    Sorry I'm still unregistered - I'm Justin.
    When you're ready for graphics, might I suggest Allegro? My installer for Dev-C++: http://www.envy.nu/springsoft/main.html

  14. #14
    Ethereal Raccoon Procyon's Avatar
    Join Date
    Aug 2001
    Posts
    189
    Well, here's a slightly fancier version, which actually links the areas. It may not be the best way to do things, but it's relatively simple:

    Code:
    #include <iostream.h>
    #include <string.h>
    
    enum dir
    {
      north = 1,
      west = 2,
      south = 3,
      east = 4
    };
    
    class area
    {
      private:
      char thedescription[20];
      area *thenorth;
      area *thewest;
      area *thesouth;
      area *theeast;
      
      public:
      area(char * description);
      void link(area *n, area *w, area *s, area *e);
      void describe()      {cout << thedescription;};
      void go(area **currentarea, dir direction);
    };
    
    
    area::area(char * description)
    {
      strcpy(thedescription, description);
    }  
    
    void area::link(area *n, area *w, area *s, area *e)
    {
      thenorth = n;
      thewest = w;
      thesouth = s;
      theeast = e;
    }
    
    void area::go(area **currentarea, dir direction)
    {
      if ((direction == north) && thenorth) *currentarea = thenorth;
      if ((direction == west) && thewest) *currentarea = thewest;
      if ((direction == south) && thesouth) *currentarea = thesouth;
      if ((direction == east) && theeast) *currentarea = theeast;
    }
    
    int main(void)
    {
      area house("Your house.");
      area pond("A pond.");
      area river("A gentle river.");
      area forest("A shady forest.");
      area field("A grassy field.");
      area mill("An old mill.");
    
      house.link(&pond, &river, &forest, &field);
      pond.link(0, 0, &house, 0);
      river.link(0, 0, 0, &house);
      forest.link(&house, 0, 0, 0);
      field.link(0, &house, 0, &mill);
      mill.link(0, &field, 0, 0);
    
      area * currentarea;
      
      char command[20];
      
      currentarea = &house;
      while (strcmp(command, "exit"))
      {
        currentarea->describe();
        cout << endl << "Enter command: ";
        scanf("%s", &command);
        if (!strcmp(command, "north")) currentarea->go(&currentarea, north);
        if (!strcmp(command, "west")) currentarea->go(&currentarea, west);
        if (!strcmp(command, "south")) currentarea->go(&currentarea, south);
        if (!strcmp(command, "east")) currentarea->go(&currentarea, east);
      }
    
      return 0;
    }

  15. #15
    Registered User
    Join Date
    Oct 2001
    Posts
    81
    I don't think i'm advanced enough to use clases and pointers yet, but i'm fairly sure I have an idea on how to use arrays.

    this is the example i tryed to make, but i can't get it to work right, dod i completely screw it up and just make something full of crap or is this semi close to something that could possible work. Could someone take a look at this and see if they can get it to work.

    #include <iostream.h>
    #include <string.h>

    int main()
    {
    int x, y, MAP[x][y];
    char command[20];
    while (strcmp(command, "exit"))
    {
    cout<<"Enter command: ";
    scanf("%s", &command);
    if (!strcmp(command, "north")) y++;
    if (!strcmp(command, "south")) y = y-1;
    if (!strcmp(command, "east")) x++;
    if (!strcmp(command, "west")) x = x-1;
    }
    MAP[0][0] = {cout<<"Home";}
    MAP[0][1] = {cout<<"You went North";}
    MAP[1][0] = {cout<<"You went East";}
    if(x >= 0 && x <= 3 && y >= 0 && y <= 3) cout<<MAP[x][y];
    if(x < 0 && x > 3 && y < 0 && y > 3) cout<<"Not a valid option";
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. simple text analyzsis program
    By prominababy in forum C Programming
    Replies: 4
    Last Post: 04-16-2009, 10:15 AM
  2. Replies: 0
    Last Post: 11-19-2008, 01:16 AM
  3. Replies: 6
    Last Post: 01-29-2008, 04:40 AM
  4. Text Adventure
    By ArtGeek in forum C++ Programming
    Replies: 4
    Last Post: 05-01-2002, 11:23 PM
  5. simple text dialog ok cancel
    By Brian in forum Windows Programming
    Replies: 1
    Last Post: 02-12-2002, 02:20 AM