Qbasicnews.com

Full Version: Vocabulary in a text game?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4
I'm, by no means, an experienced QBasic user. I started playing with it three years ago, making a few very amateurish text games and whatnot. Now I've decided to revisit the whole QBasic scene, because I'm nostalgic for the stuff I used to work on and really loved the environment. As I said, though, I am not terribly experienced, and never worked with anything extremely complicated. I would hand-program each possible response. This worked, of course, but the few who played what I did would complain that it's painfully hard to figure out the exact two words to use. You couldn't "grab key" or "pick up melon" unless I had specifically allowed that combination of words to take the object.

Anyway. After a couple years, I'm going back to the whole thing, and would like to program a text game... but this time, I'd like to do it right. However, I'm really not entirely sure how to set up a sort of "vocabulary" list or common terms, so that I could group a bunch of synonyms, and each would have the same function. It would save a lot of programming. I'm wondering if somebody could help me. How would I go about making a bunch of words synonymous, so they would all perform the same function when they're entered with an INPUT command? I know I'm an amateur and all, and I hate to be such a newbie, but I do have a love for QBasic, even if I could never make anything worth doing more than amusing a couple classmates. Oh well, thanks to anyone that can help me!

Cheers,
Oh No! Melon
eamil me and i'll help you with specific questions
this sounds like a really fun challenge, actually. I'd love to help out.

let's say that you want to be able to "take" stuff. so somewhere in this game you're going to have to program some code that "takes" an item (or "get", "pick up", etc.).

the first would be to code a "take" routine. this would mean you'd make a SUB and you could pass to it a string argument. For example:

Code:
SUB Command.Take (TakeThisItem$)
  PRINT "You take the "; TakeThisItem$; "and toss it in your pack."
  OPEN "ITEMS.YOU" FOR APPEND AS #1
    PRINT #1, TakeThisItem$
  CLOSE #1
END SUB

now in your program you could make a call to this sub:

Code:
Command.Take "candle"

and it would print to the screen "You take the candle and toss it in your pack." and it would open up a text file called "ITEMS.YOU" and add "candle" on a new line. Of course, you'd want to make sure there was a candle to pick up first.

now let's back up a bit. obviously in this text game you're going to be getting string input from the player. Let's say they're typing in a line of text at a prompt, and that line of text is being stored into a variable called Text$. Now, the individual letters of that text aren't important. The only thing you really care about is words, probably. So maybe you should make an array of strings in which you can store the words. See if you can follow this logic, and let me know if you have any questions:

Code:
DO

     '*** GET INPUT FROM PLAYER AND TURN IT ALL INTO CAPS ***
     LINE INPUT "> ", Text$
     Text$ = UCASE$(Text$)

     IF LEN(Text$) > 0 THEN
          '*** COUNT THE NUMBER OF WORDS THEY ENTERED ***
          WordCount% = 1
          FOR Letter% = 1 TO LEN(Text$)
               IF MID$(Text$, Letter%, 1) = " " THEN WordCount% = WordCount% + 1
          NEXT Letter%
    
          '*** CREATE A STRING ARRAY TO STORE THE WORDS ***
          REDIM Word$(1 TO WordCount%)
          FOR CurrentWord% = 1 TO WordCount%
               Word$(CurrentWord%) = ""
          NEXT CurrentWord%

          '*** FILL THE ARRAY WITH THE INDIVIDUAL WORDS ***
          CurrentWord% = 1
          FOR Letter% = 1 TO LEN(Text$)
               Letter$ = MID$(Text$, Letter%, 1)
               IF Letter$ = " " THEN
                    CurrentWord% = CurrentWord% + 1
               ELSE
                    Word$(CurrentWord%) = Word$(CurrentWord%) + Letter$
               END IF
          NEXT Letter%
     END IF

     '*** SHOW THE FINAL OUTCOME OF THIS ***
     PRINT "Text$ = "; Text$
     FOR CurrentWord% = 1 TO WordCount%
          PRINT "CurrentWord%("; CurrentWord%; ") = "; Word$(CurrentWord%)
     NEXT CurrentWord%

LOOP UNTIL Text$ = "QUIT" OR Text$ = "EXIT"
Yep, that's a good start by Meg who has shown you how to parse the string input into tokens.

Lets assume we're just dealing with simple two word sentences to start with, consisting of a verb and object (like "take key" or "kill rat"). So in Megs code, Word$(0) would contain the verb, Word$(1) would have the noun. See if you can work out how this code might fit in with it.

(Disclaimer: top of my head - Untested)
Code:
RESTORE SynonymList
DO
   READ syn$
   IF syn$ = "ENDLIST" THEN verb$ = "UNKNOWN" : EXIT DO
   IF syn$ = UCASE$(syn$) THEN verb$ = syn$
LOOP UNTIL LCASE$(Word$(0)) = syn$

'When you drop out the loop here, verb$ holds the 'base verb'
'so if Word$(0) is "snatch" then verb$ will  be "TAKE".
'If no match then verb$ will be "UNKNOWN"

..........

SynonymList:
'base verbs must be given in CAPITALS
DATA TAKE, grab, snatch, obtain
DATA KILL, maim, destroy, eradicate
DATA THROW, lob, hurl, chuck
DATA ENDLIST
Should I release my text games library? Big Grin

A good constructed IF game (Interactive Fiction Game) has three main module (in my implementation):

1. Location Manager : Keeps track of where you are, smartly looking in the location files (stuff should be taken away of the BAS to save space), having functions to show the possible exits, managing connectivity and room info, and carrying the "fixed objects" info (objects that you only can examine such as a tree in a street).

2. Parser: This one takes a complete phrase (or several, separated with "." or ",") and it identifies verb, noun, adjective, [noun2, adjective2] basing upon a defined vocabulary. Every unknown word is left out. You can also have synonyms so if you write take or get it always return verb = get. You need this to let your player be able to write in different ways the same things. It will also be capable of parsing multi-command strings (separated by "." ). My parser understands: "get the book. open it. put it in the bag.". It just makes the game loop run three times with:

Code:
loop #1: verb = "get", noun = "book", noun2 = ""
loop #2: verb = "open", noun = "book", noun2 = ""
loop #3: verb = "put", noun = "book", noun2 = "bag"

3. The Object Manager: [this one gave me headaches]: this is the most complex. Basicly, it deals with objects or items you can interact with in the game. Each object has many attributes, such as weight, size, container/non-container, open/close, source-of-light, etc. The Object Manager is which perform actions on the object, so you can take them, wear them, open and close them, turn them on and off, put an object inside another, and stuff. In my test game you had a wallet with coins inside a bag, for example. You have the "visible" FUNCTION wich returns which objects are visible. For example, if the location has light you see every object in your location. If an object that you see is a container and it is open, you also see what's inside the container. And so forth, recursively.

My engine has two problems right now:

1.- It is in Spanish, but I could convert it to English easily as English has a simpler grammar.

2.- It still doesn't handle NPCs.
hmmm....

how come i only played those text adventures with
multiple choice questions....
You've missed Interactive Fiction. It is like reading a book and being able to interact with it. I've loved it since I was a child Tongue There is a really big scene and community. Just google for "Interactive Fiction" with the quotes Wink.
nah, i know what you mean....i have many of these....but
i don't like them...i prefer reading a book...

(especially in germany there were many text adventure
deveoping teams years ago...)

cheers/mariuz
Wow... thanks for your quick replies, everyone! And to think, I used to do things the hard way...

Code:
keyroom: CLS
PRINT "There's a key here. And a horse. And a door."
PRINT
INPUT "What would you like to do"; action$
IF action$ = "take key" THEN GOTO takekey
IF action$ = "get key" THEN GOTO takekey
IF action$ = "pick up key" THEN GOTO takekey
IF action$ = "ride horse" THEN GOTO ridehorse
IF action$ = "mount horse" THEN GOTO ridehorse
IF action$ = "open door" THEN GOTO opendoor
IF action$ = "close door" THEN GOTO doorisnotopen
GOTO keyroom

Etcetera. Anyway. I just skimmed through all that for now, so I'll have to go back and try and make heads or tails of it all... but thank you all very, very much. I really appreciate the fast reply and the willingness to help a fellow out. Now to study the examples... thanks again!

Cheers,
Oh No! Melon
you could use select case

Code:
keyroom: CLS
PRINT "There's a key here. And a horse. And a door."
PRINT
INPUT "What would you like to do"; action$
SELECT CASE action$
CASE "take key" : GOTO takekey
CASE "get key" : GOTO takekey
CASE "pick up key" : GOTO takekey
CASE "ride horse" : GOTO ridehorse
CASE "mount horse" : GOTO ridehorse
CASE "open door" : GOTO opendoor
CASE "close door" : GOTO doorisnotopen
END SELECT
GOTO keyroom

There i thinks thats right
Pages: 1 2 3 4