View Single Post
Old 04-05-2006, 07:57 PM   #6
Drealoth
Member
 
Join Date: Jan 2006
Location: Japan
Posts: 74
Drealoth is on a distinguished road
Send a message via MSN to Drealoth
At this point my mud doesn't exist, but if (and maybe when) it did, it would be on the table. Looking at the table would give 'There's a table here with a sword lying on it.' If you kicked the table, it would fall off - if it was made of glass, it might break when it fell.

Right now I've been mostly doing the parser for fun, to see how far I can take it so that it still understands my commands. One feature it has right now is that adjectives on a noun are attached as a list to it, so 'get yellow shining sword' 'get shining yellow sword' 'get yellow sword' and 'get shining sword' all will (probably) target the same object.

Also, to reply to KaViR's point that it's faster to type - I was thinking of this system as a compliment to a shorter condensed system, not a replacement. If a person knows the condensed syntax, they'll obviously use that. If a player wants to get the second sword, all they have to do is type 'get the second sword.' The game might even reply with 'HINT: This command is the same as 'g 2.sword'.' I think that having a more english like syntax available would help make it so the player doesn't have to be constantly looking up help files for commands.

The other thing that will be implemented will be the ability to specify a number of objects to perform the verb on. 'get three apples from basket'

Here's some buggy code in Ruby that I threw together yesterday. Doesn't work properly yet, but I'm getting there.

[code] # An object within the game. Takes a name and any number of adjectives
class Game_Object
attr_accessor ;adjectives #A list of adjectives associated with the object
attr_accessor ;name #A single word describing the object

def initialize(name,adjectives)
@name=name
@adjectives=adjectives #adjectives can be any number of single words.
end
end

#For parsing input
class Parser
def initialize
@ignore=['a','the']
#A list of default objects for testing purposes.
@nouns=[Game_Object.new('sword',['shining','short' ]),
Game_Object.new('sword',['long','shining']),
Game_Object.new('table',['short', 'sturdy']),
Game_Object.new('knife',nil),
Game_Object.new('chair',['sturdy','wooden']),
Game_Object.new('chair',['tall','sturdy','wooden'] ),
Game_Object.new('chair',['metal']),
Game_Object.new('door',['sturdy','iron']),
Game_Object.new('chest',['small','iron'])
]
@verbs=['get','put','sit','stand','run']
@prepositions=['from','on','with','to','at']
@adverbs=['quickly','slowly','quietly']
@counters=['first','second','third','fourth','fift h',
'sixth','seventh','eighth','ninth','tenth'
]

#and here we define our grammar. Ones that go to ';end' can end the phrase
@expected= {
;verb => [;preposition,;ignore,;counter,;adjective,;noun,;e nd],
;adjective => [;adjective,;noun],
;noun => [;list,;adverb,;preposition,;end],
;adverb => [;verb,;end],
;preposition => [;ignore,;adjective,;noun,;counter],
;ignore => [;counter,;adjective,;noun],
;counter => [;adjective,;noun],
;list => [;ignore,;counter,;adjective,;noun]
}
end

#to determine the type of a word
private
def is_verb?(word)
return false if word == nil
return @verbs.include?(word)
end

private
def is_noun?(word)
@nouns.each do |noun|
return true if noun.name==word
end
return false
end

private
def is_adverb?(word)
return false if word == nil
return @adverbs.include?(word)
end

private
def is_preposition?(word)
return @prepositions.include?(word)
end

private
def is_counter?(word)
return @counters.include?(word)
end

private
def is_adjective?(word)
@nouns.each do |noun|
return true if noun.adjectives and noun.adjectives.include?(word)
end
return false
end

private
def is_ignore?(word)
return @ignore.include?(word)
end

private
def is_list?(word)
return word=='and'
end

private
def is_type?(type,word)
case type
when ;verb then return is_verb?(word)
when ;adjective then return is_adjective?(word)
when ;noun then return is_noun?(word)
when ;preposition then return is_preposition?(word)
when ;counter then return is_counter?(word)
when ;adverb then return is_adverb?(word)
when ;list then return is_list?(word)
when ;ignore then return is_ignore?(word)
end
end

#Yes, this shouldn't be here, but it makes life easier.
public
def look
puts "You see;"
@nouns.each do |noun|
line="A "
if noun.adjectives
noun.adjectives.each do |adj|
line += adj + " "
end
end
puts line + noun.name + "."
end
end



#Parse 'msg'
#TODO; adverb support later.
def parse(msg)
return "Empty message" if msg==nil
words = msg.strip.downcase.squeeze(' ').split(' ')
argc=words.length
return "Empty message" if words.length==0
#now we just have to iterate over the tree

#the first word must be a verb (or adverb eventually)
valid_types=[;verb]
is_valid=validate(words,valid_types)
return is_valid
end

#recursively valdiate the list of words
private
def validate(words,valid_types)
word = words[0]
if words.length == 1
if is_adverb?(word) || is_verb?(word) || is_noun?(word)
return true
end
puts "Sorry, #{word} is not a noun/verb/adverb."
return false
end
valid_types.each do |type|
if is_type?(type,word)
return validate(words[1..words.length-1],@expected[type])
end
end
return false
end

end


##
# Testing, testing, one two three.
##

parser=Parser.new
parser.look
puts
puts "TEST CASES;"

puts "The following should fail due to syntax;"
puts parser.parse(nil)
puts parser.parse('')
puts parser.parse('hello world!')
puts parser.parse('sit on')
puts

#These ones are syntactically correct, but should return errors for reasons
#such as an object not existing
puts "The following should fail due to circumstance;"
puts parser.parse('get axe') #no axe in the room
puts parser.parse('get the second shining axe') #Again, no axe in the room
puts parser.parse('get the second shining axe from the chest')
puts parser.parse('get the sword from the strange box') #No strange box.
puts parser.parse('get second long sword') #only one long sword
puts parser.parse('sit on couch')
puts parser.parse('sit on the couch')

puts

puts "The following should succeed;"
puts parser.parse('sit')
puts parser.parse('get sword')
puts parser.parse('get shining sword')
puts parser.parse('get the sword')
puts parser.parse('get the shining sword')
puts parser.parse('get the second shining sword')
puts parser.parse('get sword from chest')
puts parser.parse('get the sword from the chest')
puts parser.parse('get the shining sword from the chest')
puts parser.parse('get the second shining sword from the iron chest')
puts parser.parse('sit on chair')
puts parser.parse('sit on the chair')
puts parser.parse('sit on the wooden chair')
puts parser.parse('sit on the metal chair')
puts parser.parse('sit on the second chair')
puts parser.parse('sit on the second wooden chair')
puts parser.parse('sit on the second sturdy wooden chair')
puts parser.parse('put the second sword on the second wooden chair')

puts
puts "Fin."[/quote]
Drealoth is offline   Reply With Quote