ID:154306
 
I finally got through the motivation block far enough to get my first working MUD into action. I decided to go with my own sparcer/parcer/whatchamacallit instead of using the usual verbs, which are too restrictive for my liking. Instead, I've got a single command_text input verb, the usual ">".

So, basically you type in "> Whatever you want" and the whatchamacallit scans whatever you typed for keywords, and from there turns those keywords into actions.

If it finds the word "say "within the first 4 letters of your action, it will convert the action into a say proc. Same goes for every other action in existence, in their proper priorities so that it catch words in one action that are necessary for another action to be possible.

Now, the whole thing works on a big if(findtext), else if(findtext), else if, else if, etc... over and over until it finds the command you're looking for, or returns an error if it doesn't. I don't know if there are any better ways to do this, but I'm hoping to find out, because that's why I posted this thread. I know Zilal, and probably some other people have been working on similar whatchamacallums like this, and I'd like their input and advice.

Any suggestions here?
So you actually sat there and programmed an else if to find one command out of a whole list of them? Wow, I mean programming that, and the whole list would have taken a lot of patience, seeing as there are tons of actions possible in the English language.
Any suggestions here?

Instead of relying on findtext, you might scan the string and break it down into a list of words first:

say "Hello there, friend!" to Bob

...would break up into list elements like so:
[say] ["Hello] [there,] [friend!"] [to] [Bob]

Then you can use a simple switch:

switch(lowertext(wordList[1]))
if("say") HandleSay(usr, wordList)
if("hide") HandleHide(usr, wordList)
if("get") HandleGet(usr, wordList)

Then in your verb-handling procs you'll be able to manipulate the rest of the words with similar ease, so you can allow input such as:

hide behind tree
hide in chest
hide gun behind tree
get suitcase
get brown suitcase

Hope this helps!

In response to Gughunter
...would break up into list elements like so:
[say] ["Hello] [there,] [friend!"] [to] [Bob]

I think it would be somewhat easier to handle if you treat quoted parts all as one "word"... So your example would break into:
[say] ["Hello there, friend!"] [to] [Bob]

-AbyssDragon

In response to AbyssDragon
I think it would be somewhat easier to handle if you treat quoted parts all as one "word"... So your example would break into:
[say] ["Hello there, friend!"] [to] [Bob]

Excellent idea!

In response to Gughunter
<WACKY_IDEA>
What made me think of it was realizing that once I get my mathematical expression evaluator, SET, properly contained in an object, I could subclass under it and use its already powerful parser for things just like this. Stuff like 'say' and 'to' could be considered operators, "Hello there, friend" is a string which it already supports, and 'Bob' could be a variable which would be auto-generated from contents and view, etc.
</WACKY_IDEA>

This is just idle ranting at the moment, but I think it could be done.

-AbyssDragon
In response to Gughunter
Instead of relying on findtext, you might scan the string and break it down into a list of words first:

say "Hello there, friend!" to Bob

...would break up into list elements like so:
[say] ["Hello] [there,] [friend!"] [to] [Bob]


That's a bit beyond my knowledge at the moment...
In other words, how do you do that? :oP

[Edit]

Okay, I think I've got my own version working...
In response to Foomer
When I get home, I'll post the code that I use to break a string into words. I don't know how the other BYONDers do it, but my way involves a good deal of copytext()ing and var saving and loops. Good luck.

-Lord of Water
In response to Gughunter
Suppose I have a character named "Billy Bob Joe".

I want the player to be able to tell Billy Bob Joe, "Hello".

It goes through the scan and comes out like:

[Tell] [Billy] [Bob] [Joe] [Hello].

But, how do you tell it which part is the reference, and which part is the dialogue?

Complications...

(As it is, right now my only idea would be to compare all mobs in view with the string and if their name is in the string, cut it out of the string, and direction the string at them. But I'm sure there are plenty of ways that could get messed up.)
In response to Foomer
which reminds me, ive always wondered if byond has the string functions such as mid() left() and right() and instr() as well as val()(actually, this is just text2num).

I would love to have those functions function exactley as they do in C++ or VB, because they are quite useful for all sorts of things!

FIREking
In response to Foomer
I want the player to be able to tell Billy Bob Joe, "Hello".

It goes through the scan and comes out like:

[Tell] [Billy] [Bob] [Joe] [Hello].

But, how do you tell it which part is the reference, and which part is the dialogue?

I guess the simplest way would be to have the parser leave quotes intact (and count them so that everything between them is counted as a single element, as suggested in an earlier post). Or are you thinking of allowing text to be spoken without quotes? If so, it becomes a lot tougher, I guess...
In response to Gughunter
I think without quotes is preferable. Most people prefer typing

say hello

instead of

say "hello"

...But then I'd have no idea how to get quotes working anyway :oP
In response to Foomer
If you logged into TextMUD as a player, you would notice that the tell command works in the following format:

chat "!tell (person to tell) message

It checks for !tell at the beginning of the message, and if it is found it looks for the ()s. It takes whatever is in the ()s and searches the world for a player with a similar name or key. If it is found, it tells that player the message.

Good deal?
In response to Gughunter
You should make it go through and filter out 'nice' words like 'the'. Also, you need to break down ANDs too. So it reads:

walk to the door and unlock the door

And breaks it down like this:
1) [walk] [to] [the] [door] [and] [unlock] [the] [door]
2) [walk] [to] [door] [and] [unlock] [door]
3) [walk] [to] [door]
[unlock] [door]

You also have to consider ITs. Like using the previous example, change 'and unlock the door' to 'and unlock it'.

ALSO ANDs also can show a list. Example:

pick up the key and hammer and put them in the sack

breaks down to:
1) [pick] [up] [the] [key] [and] [hammer] [and] [put] [them] [in] [the] [sack]
2) [pick] [up] [key] [and] [hammer] [and] [put] [them] [in] [sack]
3) [pick] [up] [key]
[pick] [up][hammer]
[put] [key] [in] [sack]
[put] [hammer] [in] [sack]

Generally, check to see if AND is followed by a verb. If it is, treat it as a break, if not, treat it as a list. Also make THEM be replaced with the list of objects before it.

I used to do text adventure stuff in QBasic so I learned all about how to write parcers :)

[Edit]

Also, it is nice to add adjectives to your objects too. So if you have two different swords on the floor, you can get the one you want (if theres more than one of one kind, just pick up the first one). Like "pick up the iron sword"
In response to Dreq
Feel free to make a library :oP
In response to Dreq
Sorry my man, RancerZero is a 24/7 job. No time for petty things like eating and sleeping :p
Foomer wrote:
I know Zilal, and probably some other people have been working on similar whatchamacallums like this, and I'd like their input and advice.

I can tell you basically how my parser works. It separates the incoming text into words, takes the first one and finds the proper verb with it. Then the verb sends the remaining words into a proc that scans through them *backwards*, matching them to possible targets in the range. That's so if you have something named "a brown snail" the user could type "eat brown snail" and the proc will search only through snails to find a match, rather than through anything with "brown" in the name. So the proc sees you typed "snail," looks for snails. It sees you typed "brown," then searches within the results for brown snails. But you could also just type "eat snail" and it'd return the first one it found, brown or not.

Z
In response to Zilal
Mmm, well, my current parser isn't that, err, advanced, it just seperates the words and matches the first word in the list with the appropriate command. Then it sends the remaining list into the commands, which sepperate them depending on whether or not certain breaker words are found in the list, such as "from" or "in", then divides the list into sections from what was behind the breaker and what was after it.

So, "hold stick in right hand" would tell it to use the Hold proc, checks to see if you have an "in" breaker, if not, asks what you want to hold the stick in. If you do, it'll scan all items in the room until it finds one that matches the name you typed, "stick", then checks searches for commands matching what you typed after the breaker. In the case it would match the first word in "right hand" with "right", so it'll hold the stick in your right hand.

I just made it possible to search a names list for each object too, so now I can have "a beautiful nemeth fur" that will respond to "nemeth", "fur", or "pelt".

Whee!
In response to Zilal
Then the verb sends the remaining words into a proc that scans through them *backwards*, matching them to possible targets in the range. That's so if you have something named "a brown snail" the user could type "eat brown snail" and the proc will search only through snails to find a match, rather than through anything with "brown" in the name.

Hey, that's clever! Though I should have expected no less...
In response to Foomer
Foomer wrote:
I just made it possible to search a names list for each object too, so now I can have "a beautiful nemeth fur" that will respond to "nemeth", "fur", or "pelt".

Now, there's a feature I don't have.

Z
Page: 1 2