Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD General Discussion
Llohr
Apprentice


Joined: 17 May 2005
Posts: 108

PostPosted: Fri Feb 12, 2016 7:28 am   

Minor Pattern Matching issue.
 
So I have this one, small, but very annoying problem trying to match a pattern.

I have a trigger, the pattern of which is a variable. I set that variable with an alias, and it causes things to happen when I see a string that matches that variable's value when I scan (yeah, this is the same script I've been talking about in other threads).

The problem arises in one special circumstance. I have a command, "robscan," which looks for mobs that might have something I can steal from them. They are denoted on scan's output with "(Suspicious)".

I assumed that making my variable equal to "(suspicious)" would be fully specific enough to avoid problems with other "suspicious" mobs, but as it turned out that isn't the case. There is one mob that shows up on scan's output as "- a suspicious trader", and no matter how I quote or escape those parentheses, they just don't seem to matter when the time comes to match the pattern. "~(suspicious~)" doesn't work, for instance.

I could make the trigger case sensitive, but then I'd have to make sure that I get the case right on any target I might decide to scan for, which takes away the effortless utility of being able to scan for things when I might not know exactly how they're named. I could also make that trigger "~-%s@ScanSettings.String" instead of just "@ScanSettings.String", but that would cause the same problem. Now, instead of being able to match any part of a mob's name, I'd have to match at least the first part. So, for example, instead of using "mark crocodile" (to set my scan target to crocodile) I might have to do something like "mark "a large and hungry crocodile". Maybe I want to be non-specific and target any lizard I see, where there might be yellow lizards and red lizards and green lizards--that would be impossible, in this case.

I could also make the trigger something like "~-%s(*)", and do a #if (%1=~@ScanSettings.String) in the trigger body, with another check for that one specific mob to make sure it doesn't match, but honestly I'd just rather match the pattern right in the first place, and keep the script at its current level of non-specificity, which I find to be ideal in all other circumstances.

Failing finding a way to make the pattern match, I'll just continue using #substitute and changing the name of the mobile as it appears on scan. I'm just sort of hoping that somebody knows a trick I don't for this.

tl;dr: I have bouts of OCD and need things just so.
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Fri Feb 12, 2016 8:45 am   
 
I would generally recommend avoiding using the pattern matching =~ operator. When you are working with a trigger you should be able to make the pattern specific enough that you know exactly what is matched. It makes a little more sense when it is an alias working with user input, but that tends towards being a parsing issue and you are better served using %match or %regex so that you can record parts into local variables.

Post a two sizable sets of scan output inside code tags. Try to make sure your samples cover a wide enough range of possible lines that we can be sure to get it right. After each set of scan outputs post a duplicate of some of the lines either those you want matched or those you don't want matched (whichever is less copying). For example:
Code:
lina
line b
      wepjig
I want to match:
Code:
      webjig
I am likely to produce a regex to solve your problem. CMud builds a regex from zScript patterns, but going straight to regex gives greater flexibility and power.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Llohr
Apprentice


Joined: 17 May 2005
Posts: 108

PostPosted: Fri Feb 12, 2016 8:13 pm   
 
Well, scanning from one location that I'm having an issue with looks like:
Code:
Right here you see:
 - Llohr
1 north from here you see:
 - Merthan
1 east from here you see:
 - the golden hound
4 east from here you see:
 - the drunk
1 south from here you see:
 - a suspicious trader
 - the beggar
 - Filthy
1 west from here you see:
 - the beggar
2 west from here you see:
 - the golden hound


I match every line there for one purpose or another, and I MIGHT want to specifically match any line beginning with "- ". The line I don't want to match is:
" - a suspicious trader", but only if my target variable is set to "(suspicious)". Bear in mind, anything I see here might have "(Suspicious)" appended to its name, and thus I'd want it to match in that case.

Here's one with a lot of output, showing a correct match for "(suspicious)":
Code:
Right here you see:
 - Kasan
 - A Ring-Tailed Lemur
 - Mantela Frog
 - Mantela Frog
1 north from here you see:
 - Mantela Frog
 - A Red Panda
 - A Silverback Gorilla
 - A Giant Panda Bear
 - Mantela Frog
 - An Imperial Soldier
 - Mantela Frog
2 north from here you see:
 - Mantela Frog
 - Mantela Frog
 - An Imperial Soldier
 - A Ring-Tailed Lemur
3 north from here you see:
 - Mantela Frog
 - An Imperial Soldier
 - Mantela Frog
 - A Baby Panda Bear
 - A Giant Panda Bear
 - An Imperial Soldier
 - A Ring-Tailed Lemur
4 north from here you see:
 - A Baby Panda Bear
 - Mantela Frog
 - A Silverback Gorilla
 - Mantela Frog
 - Mantela Frog
 - A Ring-Tailed Lemur
1 east from here you see:
 - Mantela Frog
 - A Ring-Tailed Lemur
 - Mantela Frog
 - A Giant Panda Bear
 - A Baby Panda Bear
2 east from here you see:
 - A Baby Gorilla
 - A cassowary
 - Mantela Frog
 - A Giant Panda Bear
3 east from here you see:
 - A cassowary
 - A cassowary
 - Mantela Frog
4 east from here you see:
 - Mantela Frog
 - A cassowary
 - A Ring-Tailed Lemur
 - A Silverback Gorilla
 - A Baby Gorilla
 - Mantela Frog
1 south from here you see:
 - Mantela Frog
 -  (Suspicious)Mantela Frog
 - A Red Panda
 - A cassowary
 - Mantela Frog
 - Mantela Frog
 - An Imperial Soldier
2 south from here you see:
 - A Baby Panda Bear
 - A Baby Gorilla
 - Mantela Frog
1 west from here you see:
 - Mantela Frog
 - A Silverback Gorilla
 - A Baby Panda Bear
2 west from here you see:
 - A cassowary
 - An Imperial Soldier
 - An Imperial Soldier
 - Mantela Frog
 - Mantela Frog
3 west from here you see:
 - Mantela Frog
 - A Baby Gorilla
 - A Baby Gorilla
 - Mantela Frog
4 west from here you see:
 - Mantela Frog
 - A Ring-Tailed Lemur
 - Mantela Frog
 - A Red Panda
 - Mantela Frog
 - Mantela Frog
 - A Silverback Gorilla
 - Mantela Frog


I might want to match any of those, but the (Suspicious)Mantela Frog is the sort of thing I want to match if my target is "(suspicious)". Anything I see there might be (Suspicious).

Here's a short one:
Code:

Right here you see:
 - Kasan
1 north from here you see:
 - Stephanos, the Innkeeper
3 east from here you see:
 - the mountain goblin
1 west from here you see:
 - the sullen bard

Again I might want to match any of the lines that start with "-".

Another:
Code:

Right here you see:
 - Kasan
2 north from here you see:
 - |+|The Grand Knight|+|
1 east from here you see:
 - a White Knight
1 west from here you see:
 - a White Knight
3 west from here you see:
 - a pearled unicorn
 - a pearled unicorn
4 west from here you see:
 - a rainbow pony


And again, I might want to match any of those. Of the mobiles showing on scan, |+|The Grand Knight|+| might (by very very rare chance) have (Suspicious) tacked on to the front of his name.

Another:
Code:

Right here you see:
 - Llohr
 - A <SHADOW> clan member
 - A (GUARDIANS) clan member
 - A {CLAW} clan member
 - A (GUARDIANS) clan member
1 north from here you see:
 - A _-Horizon-_ clan member
 - A (FLAME) clan member
2 north from here you see:
 - A _-Horizon-_ clan member
 - A {CLAW} clan member
1 east from here you see:
 - A =(Dragonlance>> clan member
 - A <*>DRAGON<*> clan member
1 west from here you see:
 - A <SHADOW> clan member
 - A {CLAW} clan member


and:
Code:

Right here you see:
 - Llohr
 - {COBRA} Clan Member
1 north from here you see:
 - O)=[CRUSADERS]=(O clan member
1 east from here you see:
 - [Ninja] clan member
 - -=Vengeance=- clan member
2 east from here you see:
 - [Ninja] clan member
1 south from here you see:
 - <VIKINGS> clan member
 - <VIKINGS> clan member
2 south from here you see:
 - O)=[CRUSADERS]=(O clan member
3 south from here you see:
 - O)=[CRUSADERS]=(O clan member
 - [Ninja] clan member
 - <->Mud Mafia<-> clan member
 - <->Mud Mafia<-> clan member


And again, I might want to match any of the specific mob names (for instance, "Vikings") appearing on that output. Or, I might want to match all of them, by setting my target to "clan member." Any of those mobiles might have "(suspicious)" tacked on to the front of its name. I could probably use the "~-(*)" trigger mentioned earlier, with %begins to match the "(suspicious)" string, but that would require the "=~" pattern matching operator for all other targets.
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4671
Location: Pensacola, FL, USA

PostPosted: Fri Feb 12, 2016 9:53 pm   
 
seems the dash beforore a suspicious character always has two spaces, where normals only have one, there is your big thing

#TR {- ~(suspicious~)(*)} {$mark=%1}

You will have to add to that to strip out the surplus characters you don't need and get to just the keyword for targeting purposes.
_________________
Discord: Shalimarwildcat
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Fri Feb 12, 2016 10:44 pm   
 
Your description in the first post is saying one thing and then what your stated with the output sampled from the mud sounds like something else entirely.
Your current trigger would be useful. I will probably also need to know specific values for some variables. Putting more information than is needed is usually better than not enough.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Llohr
Apprentice


Joined: 17 May 2005
Posts: 108

PostPosted: Sun Feb 14, 2016 8:24 am   
 
I really didn't intend to put anybody to any great effort here, just thought maybe there was a simple solution I was overlooking... I haven't tried setting my variable to \(suspicious\) yet... maybe REGEX escapes would work? I went ahead and learned REGEX the other day, but I'm still not always sure where and how I can apply it within CMUD.

In any event, you can feel free to ignore this wall of text if you're not particularly interested, otherwise, read on :) Warning, I erred WAAAAY on the side of "to much information."

I wish it were as easy as setting the variable to "- ~(suspicious~)". When using a variable as a pattern to match, things like escape characters and parentheses don't seem to work as you'd expect. There seem to be too many layers of checks to get a pattern to match without the escapes and so forth parsing out. Trying to double the escape characters doesn't work (causes errors).

I'll try to run through the steps involved.

First step: I use an alias, "walk" to set my scan target to %params (or "mark" to set both scan target and combat target). This can be any string I hope to see on scan, if I want to find special characters, I can generally just double-escape them. I.e., to match "/^\" I might type: walk "~~/~~^~~\".

Then I scan, and get the output I've shown in the previous post. Assuming I use the alias "scan" (and not "sca"), at "Right here you see:" I clear out @Target_List, and set @Target_Position to "{Steps=0|Direction=L|Stack=0}". I also #T+ a couple of other triggers, the process doesn't start without the alias scan, and has checks along the way to quit processing things if I find no targets/etc. At lines like "(%n) (%w) from here you see: " I change Target_Position.Steps to %1 and Target_Position.Direction to "%left(%2,1)", while resetting Target_Position.Stack to 1 (not zero, because my walking in will change its position in the stack).

Whenever I see "%s~-%s" I increment @Target_List.Stack by 1. if I see a mob that matches my scan target string, I record its position in "@Target_List," Where the key is equal to the number of steps away, and the value is a string list where the odd items are direction and the even items are position in the room's stack. If there is more than one matching target in a given room, I only record the first--I can't think of a reason to do otherwise unless I just wanted to count mobs... and I'd use a less complex script for that.

Anyway, this gives me a Target_List variable with a value like:
Code:
0: L|3
1: n|2|e|5|w|3
2: e|7
3: u|2|s|3
4: n|2


All that done, an alias is called, which chooses the closest target, and if there are equally close targets in different directions, it picks a direction at random. Then it sends the necessary commands to walk me to the target, maybe executes some variable actions if I have any set and if I have that function enabled, and then deletes the target's direction and stack number from the appropriate key of @Target_List.

The script is general purpose, but it has a special case. Apart from future-proofing, the only reason I record the stack positions is in case I'm using "robscan," which tells me if I see a mob on scan that I might be able to rob something valuable from. It knows if I'm doing so by checking my scan target to see if it matches "(suspicious)".

If it does, some of the functions of the script are turned off, (For instance, I won't need to watch for an ongoing fight in the target's room and run to the next target) and after sending the direction commands, it sends the command to rob the target by it's stack number. Based on scan output, I have no way of knowing for certain what that mob's keywords might be, so instead I use target completion's ultimate extension, and, for instance, send "rob 6."

I built the package to have that functionality, and others that allow it to work in tandem with other packages, but in a way that does not require any other packages and behaves normally without them.

The issue I'm having, which I admit is extremely minor given that I can just #sub the problem away, is with that "(suspicious)" target. The trigger that looks for strings is:
Code:
<trigger name="StringCheck" priority="1700" enabled="false" id="162">
  <pattern>@ScanSettings.String</pattern>
  <value>#call @See_Scan_String()</value>
</trigger>


Because of the way things parse out when using the variable as a pattern, there appears to be no way to escape the parentheses and force it to match them.

If I change the trigger to use the pattern: "%s~-(*)", I'll have to do a check like "#if (%1=~@ScanSettings.String) in order to match any part of the output string. In that case I suppose I could do away with the "%s~-%s" trigger entirely, and increment the stack count on the front end of the #if.

When I wrote the package, I had it in mind to put as little as possible in any individual session and keep the bulk of it in its own package, so triggers call functions or aliases rather than simply performing operations themselves. I just wanted to enable/disable triggers rather than using variables to store on-off states, which requires that each session contains those triggers so that multiple sessions can use the package simultaneously.

A question for anybody who made it this far: Is there any way to change the tab-spaces in the package editor?
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Mon Feb 15, 2016 2:32 am   
 
You definitely erred on the side of too much information. You supplied mostly information that is already known from your other posts and not really the information needed to figure it out.

As near as I can tell the following are the details I need confirmed.
When you use the "robscan" alias it sets ScanSettings.String="(suspicious)".
The trigger using a pattern of "@ScanSettings.String", which you posted, is what detect mobs during the scan and records their positions to TargetList.

Given those I would also ask what else is stored in ScanSettings? How hard would it be to split the pattern string off to its own variable so you don't have the extra layer of record lookup activity? Record variables use parenthesis for nesting; if you are not using #ADDKEY then your parenthesis are likely being confused during the lookup.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4671
Location: Pensacola, FL, USA

PostPosted: Mon Feb 15, 2016 6:15 am   
 
try changing the pattern to {@ScanSettings.String}, sometimes it needs the extra curly brackets to properly expand the value.
if that doesn't work, trying using: ScanSettings.String="~(suspicious~)"
or both
_________________
Discord: Shalimarwildcat
Reply with quote
Llohr
Apprentice


Joined: 17 May 2005
Posts: 108

PostPosted: Mon Feb 15, 2016 2:36 pm   
 
That's it!

Changing the pattern to {@ScanSettings.String} made it parse properly, and required no other changes to the package.

That has the added side effect of not requiring escape characters when using special characters in my target.

I had a feeling there would be something simple, thanks guys. Sometimes the finer points of syntax aren't exactly obvious to me, like when I can use $Variable vs ${Variable}.
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD General Discussion All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net