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
vortis
Novice


Joined: 15 Jul 2010
Posts: 39
Location: USA

PostPosted: Wed Apr 29, 2015 2:34 am   

SOLVED: Capturing from a paragraph and splitting it into a database variable
 
I am having trouble finding a way to split out this paragraph:

In the green fleece satchel you see some fresh stems of thistleweed (x62), some fresh bitterleaf (x17), some deep purple thornberries (x18), a package (closed), some mustard seeds (x12), some sprigs of rosemary (x15), some mint leaves (x9), some wild onions (x6), some fresh yellow-green bitemoss (x2), some fresh red-tinged deep green bloodwort (x2), some emberberries (x3), some fresh cuttings of lifevine (x3) and some fresh sprigs of bloodstem (x2).

What I was hoping to do was to split the various plants into a variable, whether having 1 variable for each plant type, but more preferably a database variable SatchelDB with a key for each plant and a value of each amount.
I had tried doing a trigger:
some fresh %1 ~(x%2~)

But that simply captures every plant up until the final () set in the paragraph and it assigns a key as:
stems of thistleweed (x62), some fresh bitterleaf (x17), some deep purple thornberries (x18), a package (closed), some mustard seeds (x12), some sprigs of rosemary (x15), some mint leaves (x9), some wild onions (x6), some fresh yellow-green bitemoss (x2), some fresh red-tinged deep green bloodwort (x2), some emberberries (x3), some fresh cuttings of lifevine (x3) and some fresh sprigs of bloodstem (x

with a value of 2.

Not very helpful, I am sure there must be a better way to sort this out?


Last edited by vortis on Thu May 07, 2015 4:40 am; edited 1 time in total
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Wed Apr 29, 2015 6:00 am   
 
I didn't know whether the mud sent you the paragraph in multiple lines or all at once. I also didn't have any examples of a single plant to work with. Your closed package gives me some idea what it might look like, but in order to capture properly a list of names to match against would be needed. Also if you store things in multiple bags then you will likely want to accumulate a total for all your bags instead of starting new each time. This at least gives you a starting point.
Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
  <class name="PlantCaptures" copy="yes">
    <trigger name="PlantCap" priority="30" copy="yes">
      <pattern>^In {a|an|the} * satchel you see (*)</pattern>
      <value>Plants=%1
#IF (%ends(%1,".")) {
 #STATE PlantCap 2
 #SET PlantCap 2 1
}</value>
      <trigger type="Loop Lines" param="100">
        <value>Plants=%concat(@Plants," ",%line)
#IF (%ends(%line,".")) {
 #STATE PlantCap 2
 #SET PlantCap 2 1
}</value>
      </trigger>
      <trigger type="Manual">
        <value>Plants=%subregex(@Plants,"(?:some ((?:\w+ ?)*) \(x(\d+)\)|[^,\.]+)(?:(, | and )|\.)","(?(1)\1=\2(?(3)\|))")</value>
      </trigger>
    </trigger>
    <var name="Plants" type="Literal" copy="yes"/>
  </class>
</cmud>
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
vortis
Novice


Joined: 15 Jul 2010
Posts: 39
Location: USA

PostPosted: Wed Apr 29, 2015 10:32 pm   
 
Well, sadly this coding does go way over my coding experience head, but the good news is it does work exactly the way I wanted it to. As for how the information is received from the MUD it would look like this:

NOTE: EsAvd> is the MUD prompt

EsAvd>
In the green fleece satchel you see some fresh stems of thistleweed (x62), some fresh bitterleaf (x17), some deep purple thornberries (x18), some mustard seeds (x12), some sprigs of rosemary (x15), some mint leaves (x9), some wild onions (x6), some fresh yellow-green bitemoss (x2), some emberberries (x3), some fresh cuttings of lifevine (x3), some fresh sprigs of bloodstem (x2), some fresh mountain bloom, a package (closed) and a detailed pine monk carving (x2).
There is plenty of room left in the green fleece satchel.

EsAvd>

As for a single plant:
You are holding some fresh bitterleaf in your left hand.
or
You are holding some mint leaves in your left hand.

I have absolutely no idea how to read this line or have any idea what exactly it is really doing either:
Plants=%subregex(@Plants,"(?:some ((?:\w+ ?)*) \(x(\d+)\)|[^,\.]+)(?:(, | and )|\.)","(?(1)\1=\2(?(3)\|))")

and lastly as for multiple bags, yes I have a 'pouch' a 'satchel' and a 'backpack' that would be nice to check them all. They would have the same syntax of:
"In the <color> <material> <pouch/satchel/backpack> you see: <inventory list as exampled above with the satchel>'

Thanks for the help!
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Thu Apr 30, 2015 12:19 am   
 
Added recognition for other bags to the pattern. Changed parsing pattern to support singular plants. Corrected parsing pattern so last item would not be accidentally eaten. Added processing to accumulate a total from multiple bags. It looks like you don't need the multiline capturing, but I saw no reason to strip it out. You will still have to manually clear the accumulation variable, and you will have to issue whatever commands to inventory each bag.
Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
  <class name="PlantCaptures" copy="yes">
    <trigger name="PlantCap" priority="30" copy="yes">
      <pattern>^In {a|an|the} * {pouch|satchel|backpack} you see (*)</pattern>
      <value>PlantsCap=%1
#IF (%ends(%1,".")) {
 #STATE PlantCap 2
 #SET PlantCap 2 1
}</value>
      <trigger type="Loop Lines" param="100">
        <value>PlantsCap=%concat(@PlantsCap," ",%line)
#IF (%ends(%line,".")) {
 #STATE PlantCap 2
 #SET PlantCap 2 1
}</value>
      </trigger>
      <trigger type="Manual">
        <value>PlantsCap=%subregex(@PlantsCap,"(?:(some) ((?:\w+ ?)*)( \(x(\d+)\))?|(?:(?! and )[^,\.])+)(?:(, | and )|\.)","(?(1)\2=(?(3)\4|1)(?(5)\|))")
#LOOPDB @PlantsCap {
 #IF (%key) {#ADDKEY Plants {%key} {%eval(%db(@Plants, %key)+%val)}}
}
PlantsCap=""</value>
      </trigger>
    </trigger>
    <var name="Plants" type="Literal" copy="yes"/>
    <var name="PlantsCap" usedef="true" copy="yes"></var>
  </class>
</cmud>
Most of it is my standard multiline capture design, it might take a little thinking about, but is easily understood. The magic happens in this line:
PlantsCap=%subregex(@PlantsCap,"(?:(some) ((?:\w+ ?)*)( \(x(\d+)\))?|(?:(?! and )[^,\.])+)(?:(, | and )|\.)","(?(1)\2=(?(3)\4|1)(?(5)\|))")
The reason I use a complex %subregex is because it shifts all of the processing load into fastest mode possible. In order for it to work correctly all of the text has to be handled by some part of the regex pattern. To explain what it is doing we first have the matching possibilities:
Code:
(some) ((?:\w+ ?)*)( \(x(\d+)\))?
(?:(?! and )[^,\.])+
That says try to match the keyword "some" and if you don't find it go into the other mode which looks ahead to see that the next part is not ' and ' then eats a character that is not ',' or '.' and repeats for as long as it can. When the keyword is found it then records as many words as possible and looks for the key information '(x' to tell it that there are many of that item. After either of those portions have handled an entry the pattern then looks for a delimiter. The substitution is a series of conditionals. The first one says "if capture 1 was captured then (output capture 2 and '=' and if capture 3 was captured then output capture 4 else '1')"
_________________
The only good questions are the ones we have never answered before.
Search the Forums
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