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.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ MUSHclient
➜ Lua
➜ Table Sorting
It is now over 60 days since the last post. This thread is closed.
Refresh page
Pages: 1 2
Posted by
| tobiassjosten
Sweden (79 posts) Bio
|
Date
| Thu 05 May 2005 07:32 PM (UTC) |
Message
| Is there any way of sorting tables in a predefined way? I was thinking that I could it by having a second table with the correct sorting, then loop through it and checking each key to see if the first table had it, if so I would add it to a third table which would then be a correctly sorted table. But there has to be a better and faster way, right..? |
Simplicity is Divine | http://nogfx.org/ | Top |
|
Posted by
| Flannel
USA (1,230 posts) Bio
|
Date
| Reply #1 on Thu 05 May 2005 07:38 PM (UTC) Amended on Thu 05 May 2005 07:39 PM (UTC) by Flannel
|
Message
| From the lua manual:
table.sort (table [, comp])
Sorts table elements in a given order, in-place, from table[1] to table[n], where n is the size of the table (see 5.4). If comp is given, then it must be a function that receives two table elements, and returns true when the first is less than the second (so that not comp(a[i+1],a[i]) will be true after the sort). If comp is not given, then the standard Lua operator < is used instead.
The sort algorithm is not stable, that is, elements considered equal by the given order may have their relative positions changed by the sort.
Basically, it sorts them by default (a < b) or does the PHP thing (usort) where you give it a function that can do your complicated comparisons (and uses the results from that to sort).
So, your use would depend on what you want sorted (and how).
And I believe it uses a bubble sort internally. |
~Flannel
Messiah of Rose
Eternity's Trials.
Clones are people two. | Top |
|
Posted by
| tobiassjosten
Sweden (79 posts) Bio
|
Date
| Reply #2 on Thu 05 May 2005 09:06 PM (UTC) |
Message
| This is for keeping score on my afflictions (states of my character). For now I have them in a table called aff (like: aff['paralysis'] or aff['stupidity']) where they have a boolean value. I then check them one by one:
if aff['stupidity'] then
eat('orphine')
elseif aff['paralysis'] then
eat('maidenhair')
etc..
In zMUD I started off with having these afflictions in an array, which I sorted to have the most annoying/lethal ones in the top. Then I just picked the off using (translated to LUA):
cure(aff['1']). It got slow (damn tanky zMUD) so I replaced it with single variables for each affliction. I can't quite recall why I would want to use this method, other than laziness with all the IFs. ;) But still, if there's a method for doing this sorting, I'd like to learn. |
Simplicity is Divine | http://nogfx.org/ | Top |
|
Posted by
| Flannel
USA (1,230 posts) Bio
|
Date
| Reply #3 on Fri 06 May 2005 04:35 AM (UTC) Amended on Fri 06 May 2005 04:43 AM (UTC) by Flannel
|
Message
| You could have another array (table, technically) that is just numerically indexed, that contains the afflictions from highest to lowest severity.
Then use the values in that to cycle through your afflictions in order.
And actually, you could have a third table with affliction names and their remedies (keys are names, values, remedies, like studidity => orphine) so you could have everything be dynamic, you cycle through your numerically indexed array to get the names of the keys, and then a simple if aff[names[i]] then eat(cures[names[i]]) in a loop.
I guess in code it would look something like this (I think):
for _,name in pairs (names) do
if aff[name] then
eat(cures[name])
end
end
|
~Flannel
Messiah of Rose
Eternity's Trials.
Clones are people two. | Top |
|
Posted by
| tobiassjosten
Sweden (79 posts) Bio
|
Date
| Reply #4 on Sat 07 May 2005 09:30 PM (UTC) |
Message
| That's how I had it setup in zMUD. But with LUA, it's still a little harder for me to do. The next curve seems steeper, so to say. Mind explaining what that snippet of code does? Especially the underscore is there for. And also, is there some easy built-in functions to add/remove a value to an numeric array (table)? Remove duplicates? Found a snippet of code in lua.org to check if a value was present, so I'm thinking I'll have to code the add/remove/duplicate-functions on my own as well? (couldn't find anything for that in the PIL) |
Simplicity is Divine | http://nogfx.org/ | Top |
|
Posted by
| Flannel
USA (1,230 posts) Bio
|
Date
| Reply #5 on Sat 07 May 2005 10:02 PM (UTC) Amended on Sat 07 May 2005 10:06 PM (UTC) by Flannel
|
Message
| http://www.lua.org/manual/5.0/manual.html#5.4
Has add/remove things. For duplicates, I think you'll have to iterate over it yourself.
As for the underscore, it could just as well be a k or whatever.
for k,v in pairs (table) puts a value k (key) and v (value) into the loop. I believe the underscore just says we don't care what it is (since we're only concerned with the values), I have no idea if it's any faster doing that though.
Instead of worrying about removing duplicates, why don't you just code in a check when adding values?
Anyway, that code loops through all the values in a (numerically indexed) table 'names' (presumably where you keep the names of afflictions, in the order you want to cure them) and for each of those names, it checks the value of that affliction (in the aff table, using the name as the key) and if so, it sends the value from the 'cures' table (again, using the name as the key).
What this doesn't however do, is break once something is found, but that's easy enough to do (just add a break statement into the if block). |
~Flannel
Messiah of Rose
Eternity's Trials.
Clones are people two. | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #6 on Mon 09 May 2005 07:04 AM (UTC) |
Message
| I think you can solve this problem more creatively than using lots of tables. In Lua a table can consist of tables (ie. a table of tables).
Thus a single table could hold afflictions (by name, say) and for each one hold stuff like what the cure is, what string identifies it and so on.
Then rather than trying to sort the table for efficiency simply have a second table of the active afflictions. Tables can contain pointers (references) to other tables, so your second table could simply be a list of the active afflictions, you add to it when you get one, and delete from it when it is cured. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| tobiassjosten
Sweden (79 posts) Bio
|
Date
| Reply #7 on Mon 09 May 2005 09:14 AM (UTC) Amended on Mon 09 May 2005 11:02 AM (UTC) by tobiassjosten
|
Message
| Would you mind explaining how that would look? With the reference I mean. I do have multidimensional arrays for another module, tracking -> track['crox']['dstab']['miss'] would give me the amount of times crox have doublestabbed me, but missed. But you're talking about something else?
Edit: Remade the routines into using Flannels example, which might be a really smooth was of doing it.
How does this look?:
curesHerbs = {["stupidity"] = "orphine", ["paralysis"] = "maidenhair"}
function curePrompt ()
if canEat () then cureHerb () end
end
function cureHerb ()
for _,name in pairs (curesHerbs) do
if aff[name] then
eat(curesHerbs[name])
end
end
end
function canEat ()
if bHerb and doHerb == false then
if anorexia == false or doSalve == "epidermal" or doFocus then
if unconcious ~= true and stunned ~= true and sleeping ~= true then
if entangle['transfix'] ~= true then
return true
end
end
end
end
return false
end
Edit2: Just came to think of an issue with this, concearning salves. They can be targeted (eg, apply mending to head) for better control of what you cure. In some cases you must target the salve. Can this be done by splitting strings in some way? Like, if I add the cure "restoration_head" for the affliction "crip_head", it sends apply("restoration", "head"). |
Simplicity is Divine | http://nogfx.org/ | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #8 on Tue 10 May 2005 07:17 AM (UTC) Amended on Tue 10 May 2005 07:19 AM (UTC) by Nick Gammon
|
Message
| This is what I am talking about.
-- table of herbs and cures
curesHerbs =
{
{ name = "stupidity", cure = "orphine" },
{ name = "paralysis", cure = "maidenhair" },
{ name = "sleep", cure = "wildvine" },
}
tprint (curesHerbs)
-- current afflictions
currentAffs = {}
table.insert (currentAffs, curesHerbs [1])
table.insert (currentAffs, curesHerbs [3])
for k, v in currentAffs do
print ("name = ", v.name)
print ("cure = ", v.cure)
end -- for
-- remove 2nd item
table.remove (currentAffs, 2)
tprint (currentAffs)
My table curesHerbs is a table of tables, where each item has a name (eg. name, cure).
The if an affliction is current you insert it into the currentAffs table (using table.insert). You can iterate through the current ones, see the "for" loop, where the value (v) is the reference to the original table, so you can dereference it (eg. v.name).
You can then remove it from the currentAffs table (using table.remove) however it still exists in the "master" table.
Output:
Master table
1:
cure=orphine
name=stupidity
2:
cure=maidenhair
name=paralysis
3:
cure=wildvine
name=sleep
For loop, showing current afflictions
name = stupidity
cure = orphine
name = sleep
cure = wildvine
Current afflictions, after removing 2nd item
1:
cure=orphine
name=stupidity
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| tobiassjosten
Sweden (79 posts) Bio
|
Date
| Reply #9 on Tue 10 May 2005 09:57 PM (UTC) |
Message
| How will that for-loop scroll through the table? I did it as Flannel suggested and it worked excellent, if it werent for the fact that FOR seems to loop through the tables in a reversed alphabetic order.. Who the #¤%& wrote that FOR-routine? |
Simplicity is Divine | http://nogfx.org/ | Top |
|
Posted by
| Akraa
(3 posts) Bio
|
Date
| Reply #10 on Fri 13 May 2005 12:43 PM (UTC) |
Message
| hmm, Nick, is there any way to maintain the priorities from the curesHerbs table when you transfer it to the affliction list?
Because in your example, that would just make it a first on first off curing setup, so like, the actual order that affs are cured in isnt taken into account,despite the fact that you set priorities in the original table. | Top |
|
Posted by
| tobiassjosten
Sweden (79 posts) Bio
|
Date
| Reply #11 on Fri 13 May 2005 07:51 PM (UTC) |
Message
| With Nick's setup, you could instead loop through the curesHerb-table and check if the current value is true in your affliction-list. Methinks.
I've been pondering this some, and come up with the thought that there must be a more efficient to track/cure afflictions with LUA's tables. Let me explain IRE's affliction/curing-system some, and perhaps some of the veterans gets an idea?
There are alot of afflictions, which all have their effect. Some restricts an action (attacks/curing-method/ect), some damages you, some decreases the information sent to you.
These afflictions are all normally cured in just one way: eating a herb, applying a salve, smoking a herb or drinking an elixir. There are however some other curing methods, which you get access to buy training certain skills. These curing methods have their own lists of afflictions they are able to cure, which interlaces with the regular ones. All curing methods have their individual balances, and you'll have to use them wisely to not get behind on the curing.
For now, I have a function which adds afflictions to an affliction-que, one which removes from my "current list" and one which loops through my balances and sends out the appropriate cures The latter one is called everytime I get balance back from a curing method, and when I get afflicted with something.
To complicate it further (allthough I don't know what value it could have to you) there's also illusions mixed in this. Some classes are able to conjure illusions to mess upp your affliction-tracking. Hence why I use a que before adding the affliction to my "current list". Whenever I get a prompt, the system hasn't detected an illusion (by unlikely happenings/bad illusioners) and the affQue has items in it, I add them all to my "current list".
Now, how would you go about tracking and curing these afflictions? A plus is that the system is usable by people who lack the special curing methods. |
Simplicity is Divine | http://nogfx.org/ | Top |
|
Posted by
| Akraa
(3 posts) Bio
|
Date
| Reply #12 on Fri 13 May 2005 10:04 PM (UTC) |
Message
| hmm what if you added a third part to the herbcure thing,
curesHerbs =
{
{ name = "stupidity", cure = "orphine", active = "0" },
{ name = "paralysis", cure = "maidenhair", active = "0" },
{ name = "sleep", cure = "wildvine", active = "0" },
}
could you a) change the "active" in each set from another script or trigger (like when your paralysis trigger goes off, have it set curesHerbs[2] to { name = "paralysis", cure = "maidenhair", active = "1" } ?)
and b) go down the table in priorty then have it, when it finds a line with active = 1 to send that to the curing cue then stop its search until herb balance is regained? (ie only process the instance of active = "1" that is highest on the priority list, then exit out of the table)
if those two can be done, can anyone explain to me how to do it? | Top |
|
Posted by
| tobiassjosten
Sweden (79 posts) Bio
|
Date
| Reply #13 on Fri 13 May 2005 10:31 PM (UTC) |
Message
| Check out Nick's post above, it explains it all. Just add a break when it finds something to cure. And for the updating, don't know the syntax to do it in LUA, but I'm sure it's doable. |
Simplicity is Divine | http://nogfx.org/ | Top |
|
Posted by
| Akraa
(3 posts) Bio
|
Date
| Reply #14 on Fri 13 May 2005 11:57 PM (UTC) |
Message
| I found a way to edit the cureherb table here http://www.lua.org/pil/13.4.2.html
if Im understanding it right, then I could trigger the paralysis line to:
rawset (curesHerb[2], active, 1)
which would set
{ name = "paralysis", cure = "maidenhair", active = "0" },
to
{ name = "paralysis", cure = "maidenhair", active = "1" },
that is, if im understanding it properly.
How would the syntax for adding a break to curesHerb = {} work?
so when I have:
curesHerbs =
{
{ name = "stupidity", cure = "orphine", active = "0" },
{ name = "paralysis", cure = "maidenhair", active = "1" },
{ name = "sleep", cure = "wildvine", active = "0" },
}
it would go through the table down to:
{ name = "stupidity", cure = "orphine", active = "0" },
{ name = "paralysis", cure = "maidenhair", active = "1" },
then immediately go to the curing attempt, rather than continuing down the table? | 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,025 views.
This is page 1, subject is 2 pages long: 1 2
It is now over 60 days since the last post. This thread is closed.
Refresh page
top