|
Harlequ1n Newbie
Joined: 24 May 2007 Posts: 5
|
Posted: Fri May 25, 2007 9:09 pm
Lowest value in a given list? |
I'm curious as to how to do this - I realise using %sort helps, but the situation I have is as follows...
I'll have two string lists - Names and health. What I want to do is pick the name with the lowest health (Or preferably lowest 3), so that I can direct attacks at them.
I can't figure out how to have the names list rearrange at the same time as the numbers. Is there a way to do this? |
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Fri May 25, 2007 9:16 pm |
A much easier way would be to use a data record variable with the names as keys and the healths as values (or the other way round, it doesn't make much difference). Then you just do this:
#local $lowest $lowestname
#loopdb @NamesAndHealth {#if (%val<$lowest) {$lowest=%val;$lowestname=%key}}
#var lowestname $lowestname
If you're using health as keys (if it's a large database you might find constructing a reverse database and doing it this way is faster)
#local $lowest
#loopdb @HealthsAndNames {#if (%key<$lowest) {$lowest=%key}}
#var lowestname @{HealthsAndNames.$lowest} |
|
Last edited by Fang Xianfu on Fri May 25, 2007 9:19 pm; edited 1 time in total |
|
|
|
Harlequ1n Newbie
Joined: 24 May 2007 Posts: 5
|
Posted: Fri May 25, 2007 9:18 pm |
Will try that :) Stormhammer with this should be fun.
EDIT: Oh, then how do I get the lowest.. 3? :p |
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Fri May 25, 2007 9:20 pm |
Added something above, just in case you missed it. And the only problem will be tracking everyone's health - I assume you have a passive ability to do that? I'd hate to think of the mana drain with assessing everyone every round :|
|
|
|
|
Harlequ1n Newbie
Joined: 24 May 2007 Posts: 5
|
Posted: Fri May 25, 2007 9:25 pm |
I have 669 mana, which translates to... 7359 achaean/aetolian, I think. And it's a one off this - It'll trueassess every enemy/target in the room, then I'm hoping to have it stormhammer the lowest 3.
EDIT: Ok. That's just returning the last value looked at... Ooer.
EDIT2: Found a way to do this - Save the health/names as you suggested in a database record, but also save the health values in a standard list. Use %sort on the standard list, then use %ismember(%val, @sortedlist) to find the ranking of the person in terms of health. |
|
|
|
gmueller Apprentice
Joined: 06 Apr 2004 Posts: 173
|
Posted: Sat May 26, 2007 9:17 am |
UNTESTED CODE (and not optomized for CMUD)
Code: |
#ALIAS healthsort2 {
#IF (%item(@health,%1) < %item(@health,@low)) {
high = @middle
middle = @low
low = %1
} {
#IF (%item(@health,%1) < %item(@health,@middle)) {
high = @middle
middle = %1
} {
#IF (%item(@health,%1) < %item(@health,@high)) {
high = %1
}
}
}
} |
Code: |
#ALIAS healthsort1 {
#IF (%item(@health,1) < %item(@health,2)) {
low = 1
middle = 2
} {
low = 2
middle = 1
}
#IF (%item(@health,3) < %item(@health,@low)) {
high = @middle
middle = @low
low = 3
} {
#IF (%item(@health,3) < %item(@health,@middle)) {
high = @middle
middle = 3
} {
high = 3
}
}
#IF (%numitems(@health) > 3) {
#LOOP 4, %numitems(@health) {
healthsort2 %i
}
}
} |
calling healthsort1 does everything
After invocation it will cause the smallest index to be in low, next lowest in middle, and third smallest in high.
healthsort2 should probably be reworked to be a function instead of an alias, and should accept four parameters, so you wont need to declare low middle and high, and healthsort2 can be reworked to use local variables, but this is up to you. |
|
Last edited by gmueller on Sat May 26, 2007 9:58 pm; edited 7 times in total |
|
|
|
gmueller Apprentice
Joined: 06 Apr 2004 Posts: 173
|
Posted: Sat May 26, 2007 9:17 am |
lag caused a double post, sorry
|
|
|
|
Drevarr Beginner
Joined: 19 Dec 2001 Posts: 17 Location: USA
|
Posted: Sat May 26, 2007 2:38 pm |
Here is a solution if you still want to use two stringlists, one containing names and the other containing the names hitpoints. The following should do the trick:
Example StringLists:
#VAR groupnames {Blix|Emre|Odef|Thanora}
#VAR grouphps {359|436|376|434}
Code: |
#VAR rlist {}
#VAR glist {}
#LOOP 1,%numitems( @grouphps) {#ADDITEM glist %right( %eval( %item( @grouphps, %i)+100000), 1)"^"%item( @groupnames, %i)}
#VAR sortedgroup %sort( @glist)
#loop 1,%numitems( @sortedgroup) {#additem rlist %word( %item( @sortedgroup, %i), 2, "^")}
|
Then you can loop through the first three to attack the lowest.
Code: |
#LOOP 1,3 {#show %item(@rlist,%i)}
|
|
|
|
|
|
|