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

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » zMUD General Discussion
Daje123
Beginner


Joined: 16 Jun 2009
Posts: 13

PostPosted: Tue Jun 16, 2009 8:41 pm   

Sorting one String list via a DBRec var
 
Ok so i've been having some real trouble lately, I have -no- idea how to code this and I really need this done because this is the biggest problem I'm having. %sort() in zmud doesn't do anything of what I need it to, it only sorts a list via alphabetical order. What I need to do is sort a string list via a set of given numbers in a dbrec variable. I'll give an example and the code that I've come up with up until now.


Example:


String list:

Afflictions:
asthma
paralysis
impatience

Dbrec:

AfflictionPriority:
impatience=400
asthma=395
paralysis=390


SO What I need to do is sort the afflictions list based on the priority list, now these priorities are going to be constantly changing values, that's why I have to do this, and it'll constantly be sorting but that's a different story, I need the code for the sort. It needs to be sorted in DESCENDING order, so 400, 395, 390 etc.

The outcome of the afflictions list based on the given priority list should look like this:

Afflictions:
impatience
asthma
paralysis

Also the reason why its a dbrec is because I'll be doing math with its values to add/subtract certain values to prioritize correctly. Here's the code that I've come up with (and have had other people help me with so far)

Code:
#VARIABLE HoldVar {1}
#IF (%null( %numitems( @Afflictions))) {} {
  #VARIABLE CurrentMax {@Afflictions.1}
  #UNTIL {@HoldVar == %eval( %numitems( @Afflictions)+1)} {
    #IF (%db( @AfflictionPriority, @{Afflictions.@HoldVar}) > %db( @AfflictionPriority, @CurrentMax)) {#VARIABLE CurrentMax {@{Afflictions.@HoldVar}}}
    #ADD HoldVar {1}
    }
  }
#ECHO @CurrentMax


That'll only tell me the highest priority, so one alternative is using and alias like that for each type of curing in Achaea (elixir, salve, herb, etc). Need helps! Thanks in advance.[/code]
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Tue Jun 16, 2009 9:02 pm   
 
First of all, %sort does exactly what you want, with some modifications. Use %sort(@variable, 1) to go in descending order.

Second, make a temporary variable that places the afflictions as the value, and their priority as a key. You'll want to concact some zeros to the front of it (like %concat("0000",%val) for the reasons described below).

Third, sort the temp variable. The reason I say add the 0000 is because sort works in a way contrary to what we'd like it to. It takes 1, 9, 4, 3, 2, 10, and sorts it out as 1, 10, 2, 3, 4, 9. It's basically sorting them as if the numbers were the alphabet.

That should help your sorting problems. There's actually a post somewhere here (search for sorting databases or something) that will describe it in better detail.

Charneus
Reply with quote
Daje123
Beginner


Joined: 16 Jun 2009
Posts: 13

PostPosted: Tue Jun 16, 2009 9:12 pm   
 
Yes I suppose I need an explanation in greater detail! I couldn't find the "sorting databases" post but I'll keep looking.


If only zmud allowed multi-dimensional arrays and for-each loops my life would be so much easier.
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Tue Jun 16, 2009 9:23 pm   
 
Here. Look over this post. Hope it helps!

Charneus
Reply with quote
Daje123
Beginner


Joined: 16 Jun 2009
Posts: 13

PostPosted: Tue Jun 16, 2009 9:47 pm   
 
Man that's almost it, I only have two problems after that: 1 I still need the values of the priority dbvar put into a dbvar (#addkey afflictionPriority impatience 400 etc), and I need it in descending order. I'm using this currently:


#VARIABLE templist ""
#LOOPDB %1 {#VARIABLE templist %concat( @templist, "|", %repeat( "0", 10 - %len( %val)), %val, "=", %key)}
#VARIABLE templist %delete( @templist, 1, 1)
#VARIABLE templist %sort( @templist)
#FORALL @templist {#addkey testpriority2 %right( %copy( %i, %pos( "=", %i) + 1, %len( %i) + %pos( "=", %i) + 1))}
#UNVAR templist
#GAG

Help please, this is beyond my expertise of coding Shocked. I don't even understand what's going on anymore in the alias, heh.
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Tue Jun 16, 2009 10:02 pm   
 
Well, if you clear the AfflictionPriority variable after using it in the script, then you can just use #LOOPDB @testpriority2 {#ADDKEY AfflictionPriority %val %key}, and it'll put them in reverse order of what's in testpriority2. *shrug* If that's not what you need done, please elaborate some more. ;)

Charneus
Reply with quote
Daje123
Beginner


Joined: 16 Jun 2009
Posts: 13

PostPosted: Tue Jun 16, 2009 10:12 pm   
 
Whenever I execute the script, the new variable that I put everything into doesn't have any values, so it only comes up with the names of afflictions, not their priority values. Also how can I change the order that it sorts in?
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Tue Jun 16, 2009 11:56 pm   
 
Edit: I was wrong in my previous statement, so edited it out. Let me see what I can come up for you.

Charneus
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Wed Jun 17, 2009 12:09 am   
 
Ok. Using the post that I showed you (did you happen to go all the way to the bottom, where Dharkael posted his solution?), here is the final result.

Code:
#CLASS {DBNumericValSort}
#ALIAS SortByVal {
  #var insort {}
  #var postsort {}
  #var insort %sort( %exec( "#loopdb %0 {#var insort %additem(%concat(%replace(%format('&7.f',%val),' ','0'),'=',%key),@insort)};@insort"),1)
  #var insort %subchar( @insort, "=|", %concat( %char( 30), %char( 29)))
  #loopdb @insort {#var postsort %addkey( @postsort, %val, %number( %key))}
  }
#VAR postsort {} {}
#VAR insort {} {}
#CLASS 0


I'm going to show you examples of how it works. First...

#ADDKEY afflictions {abcd} {400}
#ADDKEY afflictions {efgh} {300}
#ADDKEY afflictions {ijkl} {432}
#ADDKEY afflictions {mnop} {143}
#ADDKEY afflictions {qrst} {321}

sortbyval @afflictions
#SHOWDB @postsort

Returns:
ijkl: 432
abcd: 400
qrst: 321
efgh: 300
mnop: 143

Is this what you want?

Charneus
Reply with quote
Daje123
Beginner


Joined: 16 Jun 2009
Posts: 13

PostPosted: Wed Jun 17, 2009 12:56 am   I'm such a pest, and an idiot!
 
So that's part of what I need, now I need an alias that sorts a string list (different from the priority list) according to how the priority list is organized.


Lets go back to the scores scenario from that post:

John: 50
Bob: 33
Jim:62
Bill:12
Tim:71
Tom:68

That's the dbvar. So you use sortbyval and it comes up with a list that looks like this:

Tim: 71
Tom: 68
Jim: 62
John: 50
Bob: 33
Bill: 12

Now, lets say... you have a different list, a list without numbers that corresponds with scores (lets say you want to show who is in first out of the top 3, but nobody cares about their scores).

It'd look like this pre-sort:

Jim
Tim
Tom

Post-sort its:

Tim
Tom
Jim


Does that make sense? If not I'll try to elaborate more. This problem is so vast and complicated its really starting to irk me, I apologize for dragging it out.

Thank you for your previous help, and more help soon to come.
Reply with quote
Daje123
Beginner


Joined: 16 Jun 2009
Posts: 13

PostPosted: Wed Jun 17, 2009 2:06 am   
 
Bump for justice!
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Wed Jun 17, 2009 2:20 am   
 
Please don't bump your posts. :P I was working on it, and hadn't forgotten about you.

Here's your answer, though.

Code:
#CLASS {DBNumericValSort}
#ALIAS SortByVal {#var insort {};#var postsort {};#var topthree {};#var insort %sort( %exec( "#loopdb %0 {#var insort %additem(%concat(%replace(%format('&7.f',%val),' ','0'),'=',%key),@insort)};@insort"), 1);#var insort %subchar( @insort, "=|", %concat( %char( 30), %char( 29)));#loopdb @insort {recnum=0;#var postsort %addkey( @postsort, %val, %number( %key));#ADDITEM temptops %val};#SHOWDB @postsort;#LOOP %numitems( @temptops) {#IF (%i<4) {#ADDITEM topthree %item( @temptops, %i)}};#UNVAR temptops;#FORALL @topthree {#say %i}}
#VAR postsort {}
#VAR insort {}
#VAR topthree {}
#CLASS 0


You can change the #IF (%i<4) statement to be any number you want, and change the @topthree variable name to whatever you want, too. You can even delete the #FORALL @topthree {#say %i} bit. Just remember that the %i<# number must be one higher than the total number you want to save. It's rudimentary, but it works. You can also remove the #SHOWDB @postsort, too. I was using that for testing.

Charneus
Reply with quote
Daje123
Beginner


Joined: 16 Jun 2009
Posts: 13

PostPosted: Wed Jun 17, 2009 3:00 am   
 
Christ you're so helpful, this is insane.
Reply with quote
Daje123
Beginner


Joined: 16 Jun 2009
Posts: 13

PostPosted: Wed Jun 17, 2009 3:12 am   
 
Code:
#CLASS {VariableSorting}
#ALIAS SortByVal {
  #var insort {}
  #var postsort {}
  #var topthree {}
  #var insort %sort( %exec( "#loopdb %0 {#var insort %additem(%concat(%replace(%format('&7.f',%val),' ','0'),'=',%key),@insort)};@insort"), 1)
  #var insort %subchar( @insort, "=|", %concat( %char( 30), %char( 29)))
  #loopdb @insort {
    recnum=0
    #var postsort %addkey( @postsort, %val, %number( %key))
    #ADDITEM temptops %val
    }
  #SHOWDB @postsort
  #LOOP %numitems( @temptops) {#IF (%i<4) {#ADDITEM topthree %item( @temptops, %i)}}
  #UNVAR temptops
  #FORALL @topthree {#say %i}
  }
#VAR postsort {impatience400asthma395paralysis390} {}
#VAR insort {0000400impatience0000395asthma0000390paralysis} {}
#VAR topthree {impatience|asthma|paralysis}
#VAR afflictions {paralysis|impatience|asthma}
#VAR afflictionpriority {asthma395impatience400paralysis390shyness100vertigo150}
#CLASS 0


That's what I have in my class now, this problem is so ridiculously acute, and I haven't been clear enough. I didn't mean for a topthree to be shown, but that's ok I can fix that, what I need is it to look at that "afflictionpriority" variable and then at the "afflictions" variable and sort the afflictions variable. (I already have something to sort the priority variable, but right here its unsorted). So you see how its paralysis|impatience|asthma? It needs to change afflictions to be the same ORDER as the priority, but not completely reflect its values.


So, afflictionpriority looks like this right now:
#VAR afflictionpriority {asthma395impatience400paralysis390shyness100vertigo150}

I need afflictions to look like this post sort:
#VAR afflictions {impatience|asthma|paralysis}

See what I mean?
Essentially I don't want to cure things that aren't there, but i want to cure the things that ARE there, and cure them correctly. If I haven't been clear again I'm sorry :(.
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Wed Jun 17, 2009 5:14 am   
 
Ok. I get the gist of what you're trying to do, but I'm going to need a bit more information. Therefore, I want you to walk me step-by-step what you do, where you get your information from, and what you want the end result to be. Right now, I'm just flying in the dark. An example would be:

1. I get affected by something, it goes into this varaible.
2. After so long, I check the variable and compare it.
3. After comparing, I cure.

Something like that would be VERY helpful. :P However, you should be able to change topthree to afflictions. *shrug* Try that to see if to does what you want.

Charneus
Reply with quote
Daje123
Beginner


Joined: 16 Jun 2009
Posts: 13

PostPosted: Wed Jun 17, 2009 5:26 am   
 
Ok, good, I should've said that in the first place haha! Ok here goes:

1. I get afflicted by an a malady (eg. asthma).
2. I add asthma to my list of maladies that I've deemed "afflictions". Afflictions contains all the maladies that are hurting my character at the present time. For instance I can diagnose myself and see: You have asthma, impatience etc.
2. Once something is added to the affliction list I sort that list (of current maladies) based on how I want to cure each affliction, in a certain order. The way that my system knows how to cure in order is from this database record variable deemed "afflictionPriority".
3. All of the CURRENT afflictions affecting me, now sorted by the priority list (eg. impatience -> asthma -> paralsysis is how I want to cure it, each one has a cure that after curing 1 i have to wait 2 sec to cure again) are cured one by one by doing #forall @afflictions{cure_%i}.
4. Each time an affliction is cured, it is deleted from the list and that list is resorted (although I haven't determined if I should do that, basically because of how it cures things and the fact that that's 8 billion iterations checking hundreds of #ifs.)

If I think of anything else that should be included I'll just edit this post or make a new one, I'm sure I've missed something, if there's any piece of information I've missed that you think you need, do tell me.
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Wed Jun 17, 2009 6:38 am   
 
Hah. If you had started with this, this would have been done so much sooner! :P

Here's what you want (I hope).

Code:
#CLASS {VariableSorting}
#ALIAS SortByVal {#var insort {};#var postsort {};#var insort %sort( %exec( "#loopdb %0 {#var insort %additem(%concat(%replace(%format('&7.f',%val),' ','0'),'=',%key),@insort)};@insort"), 1);#var insort %subchar( @insort, "=|", %concat( %char( 30), %char( 29)));#loopdb @insort {#var postsort %addkey( @postsort, %val, %number( %key));#ADDITEM temptops %val}}
#ALIAS cureme {#VAR cureafflictions {};#FORALL @afflictions {#ADDKEY cureafflictions %i {%db( @afflictionpriority, %i)}};sortbyval @cureafflictions;#VAR afflictions {};#LOOP %numitems( @temptops) {#IF (%i<4) {#ADDITEM afflictions %item( @temptops, %i)}};#UNVAR @temptops;#FORALL @afflictions {cure_%i}}
#VAR postsort {}
#VAR insort {}
#VAR afflictions {}
#VAR cureafflictions {}
#ADDKEY afflictionpriority {asthma} {395}
#ADDKEY afflictionpriority {impatience} {400}
#ADDKEY afflictionpriority {paralysis} {390}
#ADDKEY afflictionpriority {shyness} {100}
#ADDKEY afflictionpriority {vertigo} {150}
#CLASS 0


If you notice, there's a new alias in there called 'cureme'. What it does is basically what you ask it to do. I'm assuming that you do want to limit it to like the top three? Or do you want to cure all things, but in a specific order? If you want to cure all things, change the #IF (%i<4) {#ADDITEM afflictions %item( @temptops, %i)} to just #ADDITEM afflictions %item(@temptops, %i).

Hope this does it all! (By the way, I didn't add the deleting of the cure because you said you weren't sure on that. That's easy to do, too. Just change #FORALL @afflictions {cure_%i} to #FORALL @afflictions {cure_%i;#DELITEM afflictions %i}...)

Charneus
Reply with quote
Daje123
Beginner


Joined: 16 Jun 2009
Posts: 13

PostPosted: Wed Jun 17, 2009 6:55 am   
 
Unless I was using it incorrectly, this happened: Whenever I change the priority in any of the variables it still says it wants impatience on top, that's what one of the conditions were, so that the priorities could change according to what was in the most dire need to be cured, like if asthma became more important. Damn I knew I forgot something. Also if I add more afflictions to the cureaffliction list it just adds those to the variable that contains the current afflictions! I'll understand if you don't want to help anymore, I'm considering just changing to MUSH client since I can just use LUA.
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Wed Jun 17, 2009 7:24 am   
 
Heh... if you want to use LUA, use CMUD instead!

I think the reason why it wasn't changing the order correctly was because of a stupid thing. *shrug* Not sure. But in the 'cureme' alias, put #VAR temptops {} under #VAR cureafflictions {}.

The cureafflictions variable is created based on what's in the afflictions variable. You shouldn't be changing that by hand at all.

I just tested this out, and changed priorities and everything, and it worked every time. If there's still a problem, let me know. :)

Charneus
Reply with quote
Daje123
Beginner


Joined: 16 Jun 2009
Posts: 13

PostPosted: Wed Jun 17, 2009 7:31 am   
 
It works. IT ACTUALLY WORKS. HOLY COW. IVE BEEN WORKING FOR WEEKS TRYING TO GET THIS TO WORK. YOU ARE THE ANSWER TO MY PRAYERS THANK YOU SO MUCH!!!! OH MY GOD!!!!!!!!!!!!!!



Thank you for that, now I can enjoy my vacation this next week and not worry about this. OH MY GOD, what a relief....you have NO idea!!!!!

EDIT: I highly appreciate your dedication to all this, you had no obligation. You're a great person Very Happy
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Wed Jun 17, 2009 7:41 am   
 
You're quite welcome. I know what it's like to be stuck on a script and have no clue where to go to. Enjoy your vacation now! And if you need help in the future, you know where to find me. :P

Charneus
Reply with quote
Daje123
Beginner


Joined: 16 Jun 2009
Posts: 13

PostPosted: Wed Jun 17, 2009 7:46 am   
 
Indeedy do
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » zMUD 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