Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ Lua ➜ Assistance with a little project

Assistance with a little project

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1 2  

Posted by Shinrar Vallar   (13 posts)  Bio
Date Wed 20 Feb 2008 06:25 PM (UTC)
Message
I'm trying to do as much of this as possible myself, but I seem to be running into a couple of... interesting problems.

The project I'm working involves three phases, the first being collecting a mass amount of data from the Mud, and storing it for the other two phases (which, luckily, don't need to last beyond the current mudding session). The second phase, performing mathematical operations with the data, will involve accessing the data in the first phase, doing some basic math, and spewing out a new set of numbers. Then, comparing that new set of numbers, a choice is made by the script (Or rather, it chooses the final value that is the largest integer, and sets two other variables based on that choice), and Phase 3 is a series of actions that depend on the choice made by the script.

Sounds complicated. To me at least. But I'm hoping I can at least do most of it on my own.

However - I've already encountered a problem. One I'm not sure if its based on the version of Lua and MUSHClient I have, or what...

Reading the tips and introduction to scripts threat, it mentioned the following:

(?P<name>\d+)

I can't seem to get that to work on my client. I'm using (?P<name>.*) at present - but its storing them as literal text rather then the numerical value I need in order to perform the math later on. When I change it to the above, the trigger simply doesn't fire. At all. (The numbers in question are decimals, such as 8.21, ranging from 0.00 to 9.99 (it may be possible for the number to enter double digets, such as 15.5, but I've never seen it as I recall at present).

My Client is version 3.65, and I'm not sure how to check my Lua version, but I don't think that is the cause of the trigger not firing...

Thank you for your help!
Top

Posted by Onoitsu2   USA  (248 posts)  Bio
Date Reply #1 on Wed 20 Feb 2008 06:37 PM (UTC)

Amended on Wed 20 Feb 2008 06:38 PM (UTC) by Onoitsu2

Message
something like

(?P<name>\d+\.\d+)

This will allow for a decimal point within the match and multiple digits in front and behind, so these will all match

1.2
12.1
23.23

you ought to get the idea.

-Onoitsu2
Top

Posted by Shinrar Vallar   (13 posts)  Bio
Date Reply #2 on Wed 20 Feb 2008 06:46 PM (UTC)
Message
Ahhhh! But will it allow the stored variable to be processed using math functions, since now its two numbers and an imposed character in the center?
Top

Posted by Nick Gammon   Australia  (23,099 posts)  Bio   Forum Administrator
Date Reply #3 on Wed 20 Feb 2008 07:46 PM (UTC)

Amended on Wed 20 Feb 2008 07:48 PM (UTC) by Nick Gammon

Message
You can "tonumber" them. This example trigger will demonstrate it:


<triggers>
  <trigger
   custom_colour="2"
   enabled="y"
   match="(?P&lt;foo&gt;\d+\.\d+)"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
n = tonumber ("%&lt;foo&gt;")

print ("n = ", n, "type = ", type (n))
</send>
  </trigger>
</triggers>


If I test this:


say 123.5454
You say '123.5454'
n =  123.5454 type =  number


Notice how it has correctly assigned the number to n, and the type of n is number, which is what you want.

See: http://mushclient.com/pasting for copying this trigger directly into MUSHclient.

See: http://www.gammon.com.au/scripts/doc.php?lua=tonumber

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,099 posts)  Bio   Forum Administrator
Date Reply #4 on Thu 21 Feb 2008 04:23 AM (UTC)

Amended on Thu 21 Feb 2008 04:29 AM (UTC) by Nick Gammon

Message
Another way of doing the regexp is this:


(?P<foo>[0-9.]+)


This matches on digits and a dot. However strictly speaking it would match multiple dots, eg. matching on 123..356

It also matches on a single dot, so you probably need to insist on a number at the start:


(?P<foo>[0-9]+[0-9.]*)


If you want to be anal about it (and if the period would not necessarily occur), you could finesse it up a bit:


(?P<foo>[0-9]{1,}(\.[0-9]{1,}){0,1})


Or, using the \d syntax:


(?P<foo>\d{1,}(\.\d{1,}){0,1})


And, this is equivalent:


(?P<foo>\d+(\.\d+)?)


This one requires at least one digit, followed by an optional decimal point and more digits. That is, if the decimal point is present (and there would only be one of them), it needs to be followed by at least one digit.

In this case the sub-group has a quantifier, so the group "(\.[0-9]{1,})" can occur zero or one times.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Shinrar Vallar   (13 posts)  Bio
Date Reply #5 on Fri 22 Feb 2008 03:29 PM (UTC)

Amended on Fri 22 Feb 2008 03:50 PM (UTC) by Shinrar Vallar

Message
Thank you a lot!
Thats all been a great help. I, fortunately, have Phase 1 completed. I punch in a command, and the script stores... Er... I think its like 70 or so variables into wildcard.variable_name

Now, I was reading some material on how to complete Phase 2, which will involve talking wildcard A, subtracting it from wildcard B, and dividing it by a constant value (Its not the same constant for each pair of variables, but A and B will always have the same constant, as the constant is a function of time I establish via trial and error). Then, store the value in a 3rd wildcard/variable thing (probably named AtoB). After thats done with all of them, I need to sort it from highest numberical value, to lowest. And then be able to get some sort of automated feedback on which is the highest value, because that will set up a trigger which assigns a few variables, so Phase 3 knows what to do (phase 3 will deal with the automated actions of doing what Phase II said was the 'best' to do, numerically).

I had planning on skimming the pages and pages of materials and teaching myself how to do it, but sadly: Something happened in the Mud, and I need to finish this script as quickly as possible...

Can someone direct me towards the forum post that involves whatever method or device of programming that would be most able to accomplish this? I'd appreciate it. Thanks.

In the meanwhile, I'm going to be looking over tables. Intuition tells me thats a good place to start.
Top

Posted by Nick Gammon   Australia  (23,099 posts)  Bio   Forum Administrator
Date Reply #6 on Fri 22 Feb 2008 08:03 PM (UTC)

Amended on Fri 22 Feb 2008 08:07 PM (UTC) by Nick Gammon

Message
Yes I would use tables. I have done a small example below that illustrates the general idea.

I would read by posting about Lua tables:

http://www.gammon.com.au/forum/?id=6036

The important thing about tables is there are two general types, ones with numeric keys, which are really like vectors or arrays, or ones where you "key" into them to quickly get to a particular spot. You can only sort (using the Lua sort) ones with numeric keys, so below I use a bit of a trick to sort a keyed table.

I have invented a table "tbl" which has various fields in it (stuff from the trigger, and a constant "c"). This is keyed by name, so if a particular trigger fires you can directly go to the item (eg. if the "foo" trigger fires then you could assign to tbl ["foo"] sub-table items).

You can see from the { ... } things for each item that each table item has a sub-table inside it. This way you can store multiple things for one main item. Here is the code:


tbl = {
  
  foo =    { a = 22, b = 33, c = 44 },
  bar =    { a = 17, b = 22, c = 5.6 },
  fubar =  { a = 5, b = 99, c = 42 },

  } -- end tbl


-- calculate a to b

for k, v in pairs (tbl) do
  v.atob = (v.b - v.a) * v.c  -- difference times a constant
end -- for loop


-- display results

require "tprint"
tprint (tbl)


-- sort to find highest atob

require "pairsbykeys"

function f (ka, kb)
  return tbl [ka].atob < tbl [kb].atob
end -- sort comparison function

for k, v in pairsByKeys (tbl, f) do
  print ("-----", k, "-----")
  tprint (v)
end -- for



After the table definition I do a simple loop to calculate your "atob" thing by considering each table item. In practice you would probably do that on a case by case basis as you assign the values for a particular trigger.

However I wanted to show how you can quickly do a calculation on the whole table.

Then we use the tprint module to display the results, which are:


"fubar":
  "a"=5
  "atob"=3948
  "c"=42
  "b"=99
"bar":
  "a"=17
  "atob"=28
  "c"=5.6
  "b"=22
"foo":
  "a"=22
  "atob"=484
  "c"=44
  "b"=33


Next you wanted them in order. There is already something supplied with MUSHclient (another module) called pairsbykeys which is designed to iterate a keyed table in sequence. Internally it does this by creating a temporary table, copying the keys of the desired table into it, and sorting it.

The default would be to sort by key name (ie. bar / foo / fubar), however you really wanted them in numeric order. To achieve this we need a custom sort function - I called it "f".

Inside the "f" function I use the supplied keys (ka and kb) to index back into the main tbl table, and return true if the "atob" field in one is less than the "atob" field in the other. This is all that is required to sort into atob order.

Finally we display the sorted results:


----- bar -----
"a"=17
"atob"=28
"c"=5.6
"b"=22
----- foo -----
"a"=22
"atob"=484
"c"=44
"b"=33
----- fubar -----
"a"=5
"atob"=3948
"c"=42
"b"=99


You can see that they are now displayed in atob order - lowest to highest. To get the highest first simply change the sort function to use > rather than <.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Shinrar Vallar   (13 posts)  Bio
Date Reply #7 on Sun 24 Feb 2008 07:26 AM (UTC)
Message
I feel like an utter... well, I could think of a few strong words, but lets just say I'm becoming frustrated beyond belief.

I got individual segments of the whole thing to work right, alone, using CTRL-I to test my ideas and the like. It worked cool. Great even.

But when I tried to throw everything together, it just all feel apart...

If I was to just post what I wanted done, and what I'm working with as far as what the mud tells me, would someone here more or less help me out by writing the script? Since its so long and complicated, I figured if I just had one 'segment' of it written, I could duplicate said segment for the other possibilities that will occur. Or is that against the spirit of these forums? I'd rather try and figure it all out myself, but time is running shorter and shorter in the mud for me to finish this, and I'm starting to loose sleep over it's frustration. Maybe I wasn't cut out for programming...

Thanks in advance, either way. If someone'll help, I'll jot together what the mud gives me, and what I want the end result to be, and you can all help me from point A to point Z.
Thanks again...
Top

Posted by Nick Gammon   Australia  (23,099 posts)  Bio   Forum Administrator
Date Reply #8 on Sun 24 Feb 2008 08:39 AM (UTC)
Message
It is hard to help when you say you have written a script (which you haven't posted any of), and things have gone wrong (but you don't give any error messages or indicate in what way they have gone wrong).

You are trying to process MUD output (which you haven't shown any of), and do some calculations (which you have only described in very general terms, as subtracting one thing from another).

I also don't understand the time limit - is the MUD about to close? In which case it won't matter. Are they about to ban bots or something?

More information would definitely be a plus.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Shinrar Vallar   (13 posts)  Bio
Date Reply #9 on Sun 24 Feb 2008 05:43 PM (UTC)

Amended on Sun 24 Feb 2008 05:44 PM (UTC) by Shinrar Vallar

Message
Another reason why you shouldn't write posts and script on a lack of sleep...

Anyways on the first bit: The time limit has to do with my character suddenly having only X amount of time to complete something. Doing it on my own is taking a long time, so when I can't mud (due to being at work and only having a limited amount of time to accomplish it), I work on this script. The end goal is for me to be able to sit here, and focus on other things in the Mud while the character itself does this - not only quicker then I could on my own - but more efficiently.

I also have this nasty habbit of being vauge.

So:

Stage 1 of my script:

I have an alias set up that stacks 18 commands, and each command returns eight to ten values (Well, actually there are a few more, but they're irrelevant). I have 18 trigger, each set up to 'catch' one of the set of numbers. To weed out the actual mud Jargon, I'll put it simple. LocationA has ResourceA and B and C.


<triggers>
  <trigger
   enabled="y"
   expand_variables="y"
   ignore_case="y"
   lines_to_match="4"
   keep_evaluating="y"
   match="^Location: A\nResourceA - (?P&lt;locationa_resorucea&gt;\d+\.\d+)\nResourceB - (?P&lt;locationa_resoruceb&gt;\d+\.\d+)\nResourceC - (?P&lt;locationa_resorucec&gt;\d+\.\d+)\n"
   multi_line="y"
   regexp="y"
   script="setuplocationa"
   sequence="100"
  >
  <send>score</send>
  </trigger>
</triggers>


The matching line should look something like:


Location: A
ResourceA - 1.11
ResourceB - 5.55
ResourceC - 1.23


Location B and C each have their own values, obviously, and their own trigger and their own called function (which populates the value B on all the tables - which I'll show shortly).

Now - obviously I have to tell the script where I am initially, but it should be able to keep track as the script runs it's course, realizing that if I'm at A, and I travel to C, I'm then at C for the next travel bit.

Because of that, I'm using a 'switch' - a variable I'm calling origin (or rather: I plan on using a switch. I haven't gotten to this part yet, having run into issues with moving the data from the mud to the table. More on that later). If origin = 1 when the above information runs by, then it'll set that location information into the table's values for A (the origin). For example: The mud's triggers will display, when I'm at location B, the information for location B with the Origin value at 1. It'll then populate the table (which is called tbl)... Now, because I'm going to refer to the table a lot, this is what it should look like when all is said and done.
Top

Posted by Shinrar Vallar   (13 posts)  Bio
Date Reply #10 on Sun 24 Feb 2008 05:43 PM (UTC)

Amended on Sun 24 Feb 2008 05:45 PM (UTC) by Shinrar Vallar

Message

tbl = {
     Resource_AtoA = { a = 1.11, b = 1.11, c = 5 },
     Resource_BtoA = { a = 2.22, b = 1.11, c = 5 },
     Resource_CtoA = { a = 3.33, b = 1.11, c = 5 },
     Resource_AtoB = { a = 1.11, b = 9.99, c = 5 },
     Resource_BtoB = { a = 2.22, b = 1.11, c = 5 },
     Resource_CtoB = { a = 3.33, b = 1.11, c = 5 },
     Resource_AtoC = { a = 1.11, b = 1.11, c = 999 },
     Resource_BtoC = { a = 2.22, b = 2.22, c = 999 },
     Resource_CtoC = { a = 3.33, b = 3.33, c = 999 },
     }


Now - obviously looking above: The origin is location C. -We- can see that, because thce resources match the origin. (B-A)/C is going to equal 0. Now, while the time unit for C to C should in theory be zero, considering they're the same location, when I set the C values based on the origin (again, I'll mention later), any location it can't reach I'm sticking a high number for - in attempts to persuade the script from not selecting that value at the end of Stage 2 of the script, where it selects the most cost effective route immediately. I probably should put in more safeguards, but I can't think for the life of me -how- at the moment, and it doesn't matter. I'll be at the computer reguardless, babysitting the script - so I can pause it if it does something that I told it that it 'can' do, but I know that it shouldn't.

Anyways - back to the table. We can tell that Buying Resource A at Location C and bringing it to Location B is the most cost effective trade. (In the above example, all the constants are 5, meaning it takes 5 units of time to get from location C to B and A).

Now, pausing what we have so far, the problems I'm having thus far.

So the script starts. I initiate an alias, that says:
"origin LocationA"
This should call a script in the .lua file that sets origin = 1, and then calls for the LocationA data from the mud (by sending the appropriate command, "look chart LocationA" - where LocationA is obviously the stored variable). The chart echoing to the mud will call forth the trigger, which will call for the script "SetupLocationA" - that script should have an IfCheck, where If Origin = 1, it populates the appropriate A values in the table; then set origin = 0; the send the stacked commands to read all of the charts - which activate their own triggers. If its = 0, it should populate the B values - which once origin = 0, when the stacked commands come through, they'll populate all the B values.

In order to test it, I set up a script (below) that is called for instead of SetupLocationA, which uses the ExampleScript as a model to help me ensure all appropriate values are assigned by the trigger.

That worked great.

Then I tried making the function SetupLocationA - which I deleted last night out of frustration. Stupid me. Now I have to start over.

When I tried to assign the values to the table, I kept getting nil value errors every time I tried to call the wildcards that were pulled from the mud - and stick them in the table. So I was probably doing it entirely wrong. It looked something to the effect of (based on memory)


ResourceA = tonumber ("ResourceA")
tbl.resource_AtoB.b = ResourceA


A lot of places I probably screwed up there.

Now:

When that problem is solved, and I can populate the table correctly, the plan is to follow the end of the population script (by calling command at the end of the last chart's population function) with the aforementioned example to do the math and sort the data:


-- calculate a to b

for k, v in pairs (tbl) do
  v.atob = (v.b - v.a) / v.c  -- difference divided by a constant
end -- for loop


-- display results

require "tprint"
tprint (tbl)


-- sort to find highest atob

require "pairsbykeys"

function f (ka, kb)
  return tbl [ka].atob > tbl [kb].atob
end -- sort comparison function

for k, v in pairsByKeys (tbl, f) do
  print ("-----", k, "-----")
  tprint (v)
end -- for


Now - the problem I'm going to face at THAT point - is how do I take what the script now has determined (that being the most efficient path to take the item), and assign them to two variables - the resource and destination. While I would normally at this point dump said information into the client and rely on triggers and the like, I have a feeling scripts might actually work better - due to the ability to call forth the wait function - but thats neither here nor there. I can at least make it work for now via triggers, and then upgrade the script once to include the additional bits.

But again:

I have no idea how to even pull the needed values out of the above code to populate the variables - partly because I'm not quite sure what went on there. Pairs and the like. I skimmed the help file, and it said to transverse all items in the table. I was thinking - brilliant? Now what do the augmentations in the syntax mean? I could maybe figure it out, but I keep having to split my time between writing this and actually doing it the slow way in the Mud- in the event I can't actually pull this off....

Well -
I'll reread this in about an hour, once I've cleared my head, and see if I can ammend anything to it to make it clearer. Thanks...
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #11 on Sun 24 Feb 2008 09:47 PM (UTC)
Message
If I'm understanding this correctly, you are printing out the key/values in the correct order, that is, the most advantageous trade comes first. Is that correct?

If so, then you have the "k" value -- the table key -- which is of the form "Resource_XtoY". You can do string matching on the table key to figure out what X and Y are; something like:

x,y = string.match(k, "Resource_(.)to(.)")

The '.' means 'any character', and the parentheses in the pattern tell it to "capture" that value as the result of the match.

Is that the information you needed or is there something else?

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Shinrar Vallar   (13 posts)  Bio
Date Reply #12 on Mon 25 Feb 2008 03:26 AM (UTC)
Message
Assuming that works the way that it looks like it does - then yes, it does help for the final stage. Which will make life a lot easier when everything else works.

Thanks!
Top

Posted by Shinrar Vallar   (13 posts)  Bio
Date Reply #13 on Mon 25 Feb 2008 06:38 PM (UTC)

Amended on Mon 25 Feb 2008 06:42 PM (UTC) by Shinrar Vallar

Message
Alright. I started over the script file, hoping to get a clear head and a fresh start. And I'm doing it at work, meaning I've plenty of time to clear my head between shots at getting this to work...

Now...

Mud Echos:

Location: A
ResourceA - 1.11
ResourceB - 5.55
ResourceC - 1.23

Trigger catches:

locationa_resourcea = 1.11
locationa_resourceb = 5.55
locationa_resourcec = 1.23

That part I'm certain works right, because I can test it with:
print (wildcards.locationa_resourcea)


Now, the script file the trigger calls for, looks something like:

function LocationASet (name, trig_line, wildcards)

  if origin == 1 then
    local locationa_resourcea = tonumber (wilcards.locationa_resourcea)
    print (locationa_resourcea, wildcards.locationa_resourcea)
  end -- if


The print line (line 42) gives me the following Error:
[string "Script file"]:42: attempt to index global 'wilcards' (a nil value)
stack traceback:
	[string "Script file"]:42: in function <[string "Script file"]:29>
Top

Posted by Nick Gammon   Australia  (23,099 posts)  Bio   Forum Administrator
Date Reply #14 on Mon 25 Feb 2008 06:58 PM (UTC)

Amended on Mon 25 Feb 2008 08:57 PM (UTC) by Nick Gammon

Message
You have to get your spelling right. In the function declaration you have "wildcards" but you are trying to use "wilcards". Note the missing "d".

I notice further back in this thread you had "locationa_resorucea" which is potentially another spelling mistake. It doesn't really matter how you spell "resource" as long as you do it consistently, and I am not sure that you are.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


62,023 views.

This is page 1, subject is 2 pages long: 1 2  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.