Open warrigal24 opened 3 years ago
Related to issue #198
Reformatted for ease of review ....
start_at = room001
locations {
room001 : location "You're inside a building, a well house for a large spring.";
}
objects {
water : scenery "some water" at = "room001" conspicuous = "false";
bottle : object "a small bottle" at = "room001" {
experimental_matching_text_sequences = [
"small bottle",
"bottle"
]
}
bottled_water : object "a bottle of water" {
experimental_matching_text_sequences = [
"water in the bottle",
"water in bottle",
"bottle of water",
"bottled water",
"water",
"bottle"
]
}
}
on_command {
: if (true) { : debug_sentence; }
// Water
: if (is_present "water") {
: match "examine water" {
: print "It's crystal clear.";
: done;
}
: match "drink water" {
: print "Very refreshing.";
: done;
}
: match "get water" {
: if (is_carried "bottled_water") {
: print "The bottle is already full of water.";
: done;
}
: if (!is_carried "bottle") {
: print "You don't have anything to carry the water in.";
: done;
}
: swap o1 = "bottle" o2 = "bottled_water";
: print "The bottle is now full of water.";
: done;
}
}
// Bottle
: if (is_present "bottle") {
: match "examine bottle" {
: print "It's just a small empty bottle.";
: done;
}
: match "empty bottle" {
: print "It's already empty.";
: done;
}
: match "fill bottle" {
: if (is_present "water") {
: swap o1 = "bottle" o2 = "bottled_water";
: print "You fill the bottle with water.";
: done;
}
: print "There's nothing to fill it with.";
: done;
}
}
// Bottle of water
: if (is_present "bottled_water") {
: match "examine bottle;examine water" {
: print "It's just a small bottle full of water.";
: done;
}
: match "drink water" {
: swap o1 = "bottled_water" o2 = "bottle";
: print "You guzzle down the water until it's all gone.";
: done;
}
: match "empty bottle;pour water" {
: swap o1 = "bottled_water" o2 = "bottle";
: print "You pour out the water and it soaks into the ground.";
: done;
}
: match "fill bottle" {
: print "It's already full of water.";
: done;
}
}
// Drop
: match "drop *" {
: disambiguate_s1 "carried";
: if (noun1_is "all") {
: do_all "inventory_notworn";
}
: if (!is_carried(s1())) {
: print {("You're not carrying any " + original "noun1" + ".")}
: done;
}
: if (is_carried (s1()) && !is_worn (s1())) {
: drop quiet = "true";
: print {("You " + original "verb" + " " + definite(d(s1())) + ".")}
: done;
}
}
// Get
: match "get *" {
: disambiguate_s1 "present";
: if (noun1_is "all") {
: do_all "current_location_objects";
}
: if (is_carried(s1())) {
: print {("You're already carrying " + definite(d(s1())) + ".")}
: done;
}
: if (!is_present(s1())) {
: print {("You can't see any " + original "noun1" + " here.")}
: done;
}
: if (!is_pocketable (s1())) {
: print "You can't carry any more. Try dropping something.";
: done;
}
: if (is_beside (s1())) {
: get quiet = "true";
: print {("You " + original "verb" + " " + definite(d(s1())) + ".")}
: done;
}
}
}
Analysis (not yet resolved this in code yet).
The reason this appears to be happening, is that the matching_text_sequences are being substituted for a single noun prior to logical sentence processing. In this case, the "bottle" alias for the"bottled_water" object id maps to "water" noun.
The water noun then during adjective noun scanning maps to the "water" object id.
The resolution to this is to resolve the text sequences during the adjective noun scanning stage.
Problems to be resolved are what happens if the same text sequence applies to two objects. In that case, then the usual known/universal matching should be used, and disambiguation should take care of everything else.
This late resolution will likely take a little more cpu time, but adventuron has mountains of cpu time, and this will resolve the issue.
Now the problem has morphed via input
> GET BOTTLE
> FILL BOTTLE
> DROP BOTTLE
... does not work
New code snippet
start_at = room001
game_settings {
add_standard_prepositions = false
auto_pluralize_nouns = false
enable_standard_all_behaviour = false
experimental_auto_propogate_known = true
header_length_limit = 32
}
locations {
room001 : location "You're inside a building, a well house for a large spring.";
}
objects {
water : scenery "some water" at = "room001" conspicuous = "false";
bottle : object "a small bottle" at = "room001" noun="bottle" {
experimental_matching_text_sequences = [
"small bottle",
"bottle"
]
}
bottled_water : object "a bottle of water" noun="water" {
experimental_matching_text_sequences = [
"water in the bottle",
"water in bottle",
"bottle of water",
"bottled water",
"water",
"bottle"
]
}
}
on_command {
: if (true) {:debug_sentence;}
// Water
: if (is_present "water") {
: match "examine water" {
: print "It's crystal clear.";
: done;
}
: match "drink water" {
: print "Very refreshing.";
: done;
}
: match "get water" {
: if (is_carried "bottled_water") {
: print "The bottle is already full of water.";
: done;
}
: if (!is_carried "bottle") {
: print "You don't have anything to carry the water in.";
: done;
}
: swap o1 = "bottle" o2 = "bottled_water";
: print "The bottle is now full of water.";
: done;
}
}
// Bottle
: if (is_present "bottle") {
: match "examine bottle" {
: print "It's just a small empty bottle.";
: done;
}
: match "empty bottle" {
: print "It's already empty.";
: done;
}
: match "fill bottle" {
: if (is_present "water") {
: swap o1 = "bottle" o2 = "bottled_water";
: print "You fill the bottle with water.";
: done;
}
: print "There's nothing to fill it with.";
: done;
}
}
// Bottle of water
: if (is_present "bottled_water") {
: match "examine bottle;examine water" {
: print "It's just a small bottle full of water.";
: done;
}
: match "drink water" {
: swap o1 = "bottled_water" o2 = "bottle";
: print "You guzzle down the water until it's all gone.";
: done;
}
: match "empty bottle;pour water" {
: swap o1 = "bottled_water" o2 = "bottle";
: print "You pour out the water and it soaks into the ground.";
: done;
}
: match "fill bottle" {
: print "It's already full of water.";
: done;
}
}
// Drop
: match "drop *" {
: disambiguate_s1 "carried";
: if (noun1_is "all") {
: do_all "inventory_notworn";
}
: if (!is_carried(s1())) {
: print {("You're not carrying any " + original "noun1" + ".")}
: done;
}
: if (is_carried (s1()) && !is_worn (s1())) {
: drop quiet = "true";
: print {("You " + original "verb" + " " + definite(d(s1())) + ".")}
: done;
}
}
// Get
: match "get *" {
: disambiguate_s1 "present";
: if (noun1_is "all") {
: do_all "current_location_objects";
}
: if (is_carried(s1())) {
: print {("You're already carrying " + definite(d(s1())) + ".")}
: done;
}
: if (!is_present(s1())) {
: print {("You can't see any " + original "noun1" + " here.")}
: done;
}
: if (!is_pocketable (s1())) {
: print "You can't carry any more. Try dropping something.";
: done;
}
: if (is_beside (s1())) {
: get quiet = "true";
: print {("You " + original "verb" + " " + definite(d(s1())) + ".")}
: done;
}
}
}
One of the problems is that the sample code checks for specific noun, and the noun is no longer a unique identifier if it has been mapped.
// Does this want to match bottled water
: match "examine water" {
}
Design Thoughts
Sentence Tokenizer Changes
When resolving initial s1 & s2....
To be calculated when the sentence is processed ....
Word Calculation Cleansing
(e.g. an eye-of-newt becomes "eye" "newt")
logical sentence
Always look up the most specific subject first. Then the other subject can be calculated from the remaining entities.
Rationalized Noun will correspond to the noun associated with the object id.
Add Topics
Topics should be added, which allow us to put nouns into global scope. Therefore all words refer to a unique entity or topic.
Update Match Command
Update match command to be able to reference individual entity / topic ids, but alow be able to reference other special values, such as traits.
(eventually we will add add pattern handlers to deal with this - this is just the first cut.
: match "get [water_bottle]" {
}
Be sure to examine the following parts:
Check out everything that touches ... LogicalSentenceElementOverrides
Especially
sentenceTokenizer.explodeLogicalSentence sentenceTokenizer.handleSentenceChunk
More Notes + Sample Code
start_at = room1
redescribe = auto_beta
game_settings {
experimental_new_parser = true
}
locations {
room1 : location "From here you can go inside <(enter)<_dir>>[south] the room2. ";
room2 : location "You are in room2. You exit the room to go to room1." ;
room3 : location "You are in room3." ;
}
connections {
from, direction, to = [
room1, enter, room2
room1, south, room3
]
}
objects {
// Per Object ...
// Set of adjectives + aliases
// Set of nouns + aliases
// When matching, tally the adjectives, tally the nouns.
// Score the match
// Needs at least one noun to match
// The more specific scores highest.
// Exact match is highest
// Everything is treated as noun, unless adjectives defined elsewhere (id scanning, or vocabulary section)
// In the case of orange orange, the same word is specified twice, so the earlier word is an orange adjective, the later word is an orange noun.
// Adjectives can have different synonyms
// Think about word category.
// an orange orange = fruit
// eye-of-newt = ingredient
// torch = light
orange_orange : object "an orange orange" at = "room1";
orange_tie : object "an orange tie" at = "room1";
bottle_1 : object "a bottle of water" at = "room1" ;
bottle_2 : object "a bottle of wine" at = "room1" ;
eyeofnewt : object "eye-of-newt" at = "room1";
earl : scenery "the earl of york" at = "room1";
jackbox : object "a jack in the box" at = "room1";
torch : object "torch" at = "room1";
torch_1 : object "a lit torch" at = "room1" ;
dogbone : object "a dog and bone" at = "room1" ;
torch_2 : object "a torch (on)" at = "room1";
torch_3 : object "a switched on torch" at = "room1";
torch_4 : object "a switched-on torch" at = "room1" msg = "fdsfdfdsdsfsd" ;
// TODO :: Dog and Bone
}
on_command {
: match "get *" {
: disambiguate_s1 "beside";
: debug_sentence;
: get ;
}
: match "x" {
: match "x *" {
: disambiguate_s1 "present";
: debug_sentence;
: gosub "examine";
}
: match "x -" {
: if (count "_current_location" == 0) {
: print "Nothing obvious to look at.";
}
: else_if (count "_current_location" == 1) {
: print "Nothing obvious to look at.";
: iterate "_current_location" {
: set_subject1 (item());
: gosub "examine";
}
}
: else {
: iterate "_current_location" {
: add_choice text -> (d(item())) payload -> (item()) ;
}
: choose "Examine what?" ;
: if (chosen() != "") {
: set_subject1 (chosen());
: gosub "examine";
}
: else {
: print "Nothing obvious to examine.";
}
}
}
}
}
subroutines {
examine : subroutine {
: if (s1() != "unknown") {
: if (emsg ("*") != "") {
: print (emsg ("*"));
}
: else {
: print "You notice nothing special.";
}
}
}
}
themes {
my_theme : theme {
theme_settings {
text_decorations= [ directions, directions_subtract ]
}
lister_exits {
exit_list_style = verbose
//is_list_enter = false
}
lister_objects {
list_type = list
}
colors {
exit_list_item_pen = 14
}
}
}
Pre-existing registered prepositions = [of] Pre-existing registered adjectives = [] Pre-existing registered nouns = [newt, swimmy]
get eye of newt
Seperate into different categories, so that difference aliases can be applied to each category.
All words are scanned as nouns (except internal prepositions), all items are lower cased, with punctuation removed.
A noun doesn't have to be in the dictionary to be scanned as a neo noun. A neo noun exists atop of the existing parser (for now), but the existing dictionaries are used for working out if something is an adjective or preposition.
s1_neo_adjectives = [ - ] s1_neo_nouns = [eye, newt] s1_neo_word_sequence = [eye, of, newt]
Need s2, s3, s0, variants.
When scanning the entity heirarchy, a similar cleansing operation is done, then a scoring is applied. If there is a precise sequence match or if more words match, then there is no ambiguity. If there are multiple matches, then s1 will contain multiple elements ready for disambiguation.
I have an empty bottle and some inconspicuous water. When I GET WATER with the empty bottle, it's supposed to get swapped with the bottle of water, but I can't GET BOTTLE in the first place, because it's converted to GET WATER. Debugging code indicates that
noun1
is wrongly converted to 'water', rather than 'bottle'. Why is Adventuron so obsessed with changing my input to something other than what I typed and looking at objects that aren't in scope?Sample input is below.
Sample code is below.