So, I’ve been working on this one problem for a couple days now and I seem to have hit a wall. If you could point me in the right direction, or even give me a hint, I think I could make it work. It’s probably more of a stackOverflow kind of question but I thought I’d ask here in case OpenEars had some specific method for it.
Using a pair of words spoken, I would like to identify keyword matches and respond accordingly.
So, for example someone says “DRINK BEER” that would be different than “SMASH BEER”. A beer happens to be available. Let’s call the appropriate method for the keyword match. I am utilizing a series of property list dictionaries, and attempting to use the dictionary’s key to identify the spoken word. Then taking the valueForKey to launch into a BEER function (I’m about to launch into my own BEER function). I am not opposed to switching the dictionaries to arrays, if that would be better programatically.
The problem seems to be when I try to use something like rangeOfString with hypothesis and my dictionary, it’s having issues. I assume because of my inexperience in extracting Keys from dictionaries? Is there an easier way to ID when two specific words are uttered using the hypothesis and a plist? AllKeys?
Using something like the code below, I can get close. It will work with two specific strings, but once I try to tie in my dictionary in different ways as a string it starts crashing on me.
if ([hypothesis rangeOfString:@"DRINK"].location == NSNotFound && [hypothesis rangeOfString:@"BEER"].location == NSNotFound) { //if the words uttered contain drink and beer is equal to notFound.
NSLog(@"You didn't say what we thought you would.. let's stop here.");
} else {
NSLog(@"Ah, you drink the beer. It is cold and refreshing.");
}
I also seem to be okay when using single words, using valueForKey:hypothesis, maybe something along those lines? IDK. Again, now that I write it out, I’m starting to realize this isn’t exactly an OpenEars question, it’s more of a plist question, so I apologize.
]]>Thank you. Basically, I make a best-effort attempt to answer right as questions come in (if it’s feasible and wouldn’t be rude to someone I was with) so I never have a backlog, which lets me keep the support side pretty well under control. So I’d rather take :10 to answer a question in a laid-back way on a Saturday than start a Monday with a backlog that becomes its own time-management task. I usually find that if I can’t handle that approach because a lot more questions than usual are coming in, that indicates that something important is missing from the docs or tutorial.
I think I can help you with your question since I do a lot of text munging and matching in OpenEars. Your approach sounds fine to me so I suspect an issue in your plist/dictionary code, can you show some?
BTW, are you acquainted with the [NSString componentsSeparatedByString] method that returns an NSArray? I use it a lot to work with multiple substrings in combination with fast enumeration. rangeOfString is also fine and I frequently use it, but for what you’re doing you might like to have all the hypotheses dumped right into an ordered array for processing.
Enjoy your BEER function!
]]> objectsInRoom = [playerIsNowAt objectForKey:@"ObjectsInLocation"]; //Bringing objects based on location
NSLog(@"Here are objects in room - %@", objectsInRoom); //logged below
//Failed experiments
//NSArray *objectWords = [objectsInRoom allKeys];
//NSString *objectString = [NSString stringWithFormat:@"%@",objectWords];
//NSArray *spokenWords = [hypothesis componentsSeparatedByString:@" "];
//NSString *spokenString = [NSString stringWithFormat:@"%@",spokenWords];
//if([hypothesis isEqualToString:@"BEER"]) { //only works if they just say BEER
if ([hypothesis rangeOfString:@"BEER"].location != NSNotFound){ // ok but how do i make it search thru allkeys for my dictionary?? maybe the next room has WINE or MIMOSA.
NSLog(@"HOPE KEPT ALIVE");
}
THE LOG :
Here are objects in room – {
BEER = Beer;
PEANUTS = Peanuts;
READ = Menu;
}
So, as you see I can seem to pull single words in using Range, but am stuck on returning a value based on the dictionary.
Other related code.. in .h
@property (copy, nonatomic) NSDictionary *objectsInRoom;
in .m
@synthesize objectsInRoom; //hm, I think i’m supposed to not synthesize these days and use that underscore thingy?
I’ve only been coding for a few months, so understanding is appreciated.
]]>NSArray *keyArray = [objectsInRoom allKeys]; for (NSString *key in keyArray) { if([hypothesis rangeOfString:key].location != NSNotFound) { NSLog(@"I found a match in the hypothesis for the key %@ so I'm doing the action for that key and breaking.", key); if([key isEqualToString:@"BEER"]) { NSLog(@"I found BEER"); [self doBeerThing]; } else if([key isEqualToString:@"HAMBURGER"]) { NSLog(@"I found HAMBURGER"); [self doHamburgerThing]; } else { NSLog(@"I don't have an action for the hypothesis that I found."); } break; // Stop enumerating once we've found something from the keys. } // Next loop will begin if we get here and there are more keys to check }
There are a few different ways this could be organized for efficiency/clarity. For instance you could skip the first general check for any match and go directly to checking for the specific matches you have in mind, and there are a few different ways you can manage the actual “calling a method having found a specific key” part which I haven’t addressed, but this is a simple and fast approach.
]]>I was kind of close with a couple attempts yesterday, I forgot to BREAK out of the For loop. :)
]]>Thanks again, if you take tips email me a paypal address. You helped me out a bunch with this.
]]>