Re: What is wrong here?

From: Thomas Matthews (Thomas_MatthewsHatesSpam_at_sbcglobal.net)
Date: 11/17/03


Date: Mon, 17 Nov 2003 16:41:09 GMT

Matthew wrote:

> I am working on a simple text adventure game. I have implemented one
> word commands and a bit for two words. I have a problem though the
> movement commands n and s (north and south respectivly) don't work. I
> can't figure out why!
There are better methods for what you want to do.
I suggest tables of constant <token, function pointer> for
standard commands. This will allow you to add commands without
having to change the driver (table lookup & execution).

You may want to make a generic parser {Factory} that reads in
the text and creates pointer to a base <token, functor> object.
You may not need the token field, as the functor could contain
the token.

> #include <string>
> #include <iostream>
> #include <vector>
> using namespace std;
>
> struct command_v
> {
> string name;
> bool (*vfunc)();
> bool (*dfunc)();
> };
>
> struct command_vd
> {
> string name;
> bool (*vfunc)(vector<string> input);
> bool (*dfunc)(vector<string> input);
> };
What is the difference between command_v and command_vd?
Comments would be helpful here.

>
> enum dirName{ n, s, e, w, north, south, east, west };
I think a table lookup would be better here.
You could add: in, out, up, down, nw, sw, etc, without
changing the driver.

> class Exit;
What is this for?
Exiting the program?
Exit from a room?

> class Item
> {
> public:
> string name;
> vector<command_vd> theVDCmds;
> };
This describes an Item. The Item _has_ a name.
It _has_ commands. Why?
Are these actions that can be performed on an
item (i.e. throw rock)?

> class Character
> {
> public:
> vector<Item> inven;
> string name;
> string desc;
> vector<command_vd> theVDCmds;
> };
A Character _has_:
   name
   description (this may need more clarification,
      such as can the description be "green").
   a vector of Items
   a vector of commands.
I don't understand what the commands are. Are
they actions, behaviors, etc?

> class Location
> {
> public:
> string name;
> string desc;
> vector<Exit> exits;
> vector<Item> items;
> vector<Character> chars;
> vector<command_vd> theVDCmds;
> };
Perhaps a location should contain a vector
of other locations or pointers to other locations.

Should a location contain a character or a character
contain a reference (or pointer) to a location. A
character could be in any location. This design
decision depends on whether you are operating on
characters or locations.

>
> class Exit
> {
> public:
> Location leadsTo;
> int shortName;
> int longName;
> string name;
> vector<command_vd> theVDCmds;
> };
This class _could_be_ eliminated by redesigning the
Location class.

[snip]

> void interpreter()
> {
> cout << "Parser v0\n";
> bool quit = false;
> bool un;
This variable could be declared within the while
loop below, because it is not used outside of the
loop.

> string input;
> dlook();
Prefer a more descriptive function name.

> while(!quit)
> {
> cout << ":> ";
> getline(cin, input);
> un = parse(input);
> if(!un)
> {
> cout << "Huh?\n";
> continue;
> }
> }
> }
Where does the variable 'quit' modified within
the while loop?

Is the above function really an interpreter or
is it the main function executing the program?

>
> void setup()
> {
> // set up standalone commands
> command_v quit;
> quit.name = "quit";
> quit.vfunc = vquit;
> quit.dfunc = dquit;
> theVCmds.push_back(quit);
[snip -- initialiation of Command variables]
I don't see the need for command variables when the
variables don't change (hence not 'variable').
I believe a table would be better.

> mainChar.name = "Matthew";
> mainChar.desc = "A valiant warrior!";
>
> ex1.leadsTo = room1;
> ex1.shortName = s;
> ex1.longName = south;
> ex1.name = "To the kitchen";
If you convert the directions to tokens, there will
be no need for both "shortName" and "longName" fields.
It may revert to "direction".

[snip -- I can't take it anymore]

I think you need to put some thought into the design
and simplify it (reduce, reuse, recycle).

Let us consider that there is one primary character.
The character traverses a set of locations. Each
location has N possible routes to other locations.
These routes may be null for directions that are
not possible or implemented. Each location has a
name and a description, as well as zero or more
objects and zero or more other characters (i.e.
monsters). The objects and characters are the
variable data. The routes, name and description
are the constant data.

I suggest using some database theory and placing
the data into tables. One table would contain the
names and descriptions, indexed by room number:
   | Room Number | Name | Description |
   +-------------+------+-------------+
   | 25 | swamp| Muggy, wet |
   +-------------+------+-------------+

Another table would contain the routes:
   | Room Number | Direction | Next Room |
   +-------------+-----------+-----------+
   | 25 | South | 26 |
   +-------------+-----------+-----------+

Another table, initialized at startup, would contain
variables {maps} for objects and characters:
   std::map<unsigned int, /* room ID */
            Object *> /* pointer to an object child */
   std::map<unsigned int, Character>

I let the OP and readers figure out how to perform the
table look-ups.

-- 
Thomas Matthews
C++ newsgroup welcome message:
          http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq:   http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
          http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
     http://www.josuttis.com  -- C++ STL Library book


Relevant Pages

  • Re: Sony CDs are not safe to play in a Windows computer
    ... I'm going to give you a list of commands that you would ... s - Replace character at current position with typed text ... ^T - Insert indentation to next shiftwidth position ...
    (rec.arts.anime.misc)
  • Re: Writing a book on AI Assistants in holographic computing
    ... Now since any character can be your AI assistant, people will want to have nice ones that suit their own character, sense of humor, and group or clique or culture or personality. ... You can get add-on behaviors and new languages and of course themes, that they can play act in, and also new abilities which we cannot even imagine what those will be today. ... If you want to execute a command, you can text the AI with your cell phone, using short commands that you learn, or merely tell the AI to go somewhere to a room, and get an object, and in that way you can remember where the commands are and what they are, by using the context of rooms. ... A lot of shoulder shrugging since they won't know much to begin with, but as this technology gets used, people will improve their ability to communicate. ...
    (comp.ai.philosophy)
  • Re: Strangely tiny type in some MF fonts
    ... Ideally, positions within a character are in terms of the height, ... so the various drawing commands should be in those ... def getpen = pickup pencircle scaled pensize enddef; ...
    (comp.text.tex)
  • Re: Telnet command question
    ... WideCharToMultiByte (using UTF-8 encoding perhaps). ... get is that if I step through it, it "understands" all the commands. ... Do you have to send it character by character? ... You should be sending byte arrays, not strings, over sockets. ...
    (microsoft.public.vc.language)
  • Re: Benchmarks question
    ... if token = 37 then jump to command 1 ... More commands, yes, but the only penalty that implies is that tokenizing might take a little longer because of more keywords to look through. ... Keyword tokens are always used as indices into jump tables on all machines. ... All this is necessary because the BASIC ROM space, BASIC program text space, and BASIC variable memory space, while all physically separate, overlay each other in the 8502's address space. ...
    (comp.sys.cbm)