Author Topic: ordered array? please help  (Read 2601 times)

Offline capo

  • Friend
  • **
  • Posts: 70
    • View Profile
ordered array? please help
« on: October 24, 2006, 12:59:44 PM »
This follows from the ds channel, I am attempting to make an ordered command that is similar to who but returns the names of the people online in specific order.



This is how I would like it to display:





quote:
> twho

*******************************{ 'Thief Who' }*******************************  



[ Boss      ] Capo the creator

[ Under-Boss] Fred the unaccomplished (idle)

[ Soldier   ] Test the unaccomplished (sleeping)



*****************************************************************************  




Currently it displays like this:



quote:
> twho

*******************************{ 'Thief Who' }*******************************  



[ Boss      ] Capo the creator

[ Soldier   ] Test the unaccomplished (sleeping)

[ Under-Boss] Fred the unaccomplished (idle)



*****************************************************************************  




This is the code for the command:



code:
#include <lib.h>
#include <privs.h>
#include <config.h>

inherit LIB_DAEMON;

int cmd(string args)
 {
    int p;
    string x, tmp="", ret="";
    object *thieves;
    object ob;
    string rank;

    ob = this_player();
    thieves = filter(users(), (: $1->GetGuild() == "thief" :) );


    rank = this_player()->GetGuildRank();
    p = 0;

  if(!creatorp(ob) && lower_case(ob->GetGuild()) != "thief")
     {
        message("info","That is not a command", ob);
        return 0;
     }

   for (int i=0; i<sizeof(thieves); i++)
        {
        if(!thieves || !environment(thieves)) continue;
         {
            tmp += "";
            if(sizeof(thieves->GetShort()) < 50)
                {
            tmp += sprintf("%%^YELLOW%%^[%%^RESET%%^ %%^RED%%^%-10s%%^YELLOW%%^] %%^RESET%%^%5s", thieves->GetGuildRank(), thieves->GetShort());
                }

            if(thieves->GetSleeping() > 0) tmp+=" (%^YELLOW%^sleeping%^RESET%^) ";
            else if (in_edit(thieves)) tmp+=" (%^RED%^scribing%^RESET%^)";
            else if(thieves->GetInCombat())  tmp+=" (%^RED%^combat%^RESET%^)";
            tmp+="\n";
            p++;
         }
      }

    ret+= "%^BOLD%^%^BLACK%^*******************************%^RESET%^%^BOLD%^%^WHITE%^{ %^YELLOW%^'Thief Who'%^BOLD%^%^WHITE%^ }%^RESET%^%^BOLD%^%^BLACK%^***********************$
    ret+=tmp;
    ret+= "\n%^BOLD%^%^BLACK%^*****************************************************************************%^RESET%^  \n";
    write(ret);
    return 1;
 }

Offline daelaskai

  • BFF
  • ***
  • Posts: 174
    • View Profile
ordered array? please help
« Reply #1 on: October 24, 2006, 01:22:50 PM »
I would do something like this:



code:

static int special_sort(object alpha, object beta) {
    string a, b;

    if((a=(string)alpha->GetGuild())!=(b=(string)beta->GetGuild())) {
      if(!a) a = "zzzz";
      if(!b) b= "zzzz";
      return strcmp(a, b);
    }
    return 0;
}




Then, under:

code:

obs=users();


you would add:

code:

obs = sort_array(obs,"special_sort",this_object());

Offline capo

  • Friend
  • **
  • Posts: 70
    • View Profile
ordered array? please help
« Reply #2 on: October 24, 2006, 01:42:52 PM »
I must admit that I have no idea what's going on with this command...shouldn't it be going after GetGuildRank() rather than GetGuild()?



Moreover, Im a little confused how this would fit into the command.  This is the current command:



code:
#include <lib.h>
#include <privs.h>
#include <config.h>

inherit LIB_DAEMON;

int cmd(string args)
 {
    int p;
    int i;
    string x, tmp="", ret="";
    object *thieves;
    object ob;
    string rank;
    array ranks;

    ob = this_player();
    thieves = filter(users(), (: $1->GetGuild() == "thief" :) );
    ranks = ({ "Boss", "Under-Boss", "Soldier" });
    rank = this_player()->GetGuildRank();
    p = 0;


  if(!creatorp(ob) && lower_case(ob->GetGuild()) != "thief")
     {
        message("info","That is not a command", ob);
        return 0;
     }

     while( i < sizeof(ranks))
         {
          if (this_player()->GuildGetRank() == ranks)
           {
            tmp += sprintf("%%^YELLOW%%^[%%^RESET%%^ %%^RED%%^%-10s%%^YELLOW%%^] %%^RESET%%^%5s", thieves->GetGuildRank(), thieves->GetShort());

           }
        i++;
        }
    ret+= "%^BOLD%^%^BLACK%^*******************************%^RESET%^%^BOLD%^%^WHITE%^{ %^YELLOW%^'Thief Who'%^BOLD%^%^WHITE%^ }%^RESET%^%^BOLD%^%^BLACK%^***********************$
    ret+=tmp;
    ret+= "\n%^BOLD%^%^BLACK%^*****************************************************************************%^RESET%^  \n";
    write(ret);
    return 1;
 }






It returns :





twho

*******************************{ 'Thief Who' }*******************************  





*****************************************************************************

Offline daelaskai

  • BFF
  • ***
  • Posts: 174
    • View Profile
ordered array? please help
« Reply #3 on: October 24, 2006, 01:47:28 PM »
Okay, try this.  Since I don't have your GetGuildRank() on my mud, I could not test.



code:

#include <lib.h>
#include <privs.h>
#include <config.h>

inherit LIB_DAEMON;

int cmd(string args)
 {
    int p;
    string x, tmp="", ret="";
    object *thieves;
    object ob;
    string rank;

    ob = this_player();
    thieves = filter(users(), (: $1->GetGuild() == "thief" :) );
    thieves = sort_array(thieves,"special_sort",this_object());


    rank = this_player()->GetGuildRank();
    p = 0;

  if(!creatorp(ob) && lower_case(ob->GetGuild()) != "thief")
     {
        message("info","That is not a command", ob);
        return 0;
     }

   for (int i=0; i<sizeof(thieves); i++)
        {
        if(!thieves || !environment(thieves)) continue;
         {
            tmp += "";
            if(sizeof(thieves->GetShort()) < 50)
                {
            tmp += sprintf("%%^YELLOW%%^[%%^RESET%%^ %%^RED%%^%-10s%%^YELLOW%%^] %%^RESET%%^%5s", thieves->GetGuildRank(), thieves->GetShort());
                }

            if(thieves->GetSleeping() > 0) tmp+=" (%^YELLOW%^sleeping%^RESET%^) ";
            else if (in_edit(thieves)) tmp+=" (%^RED%^scribing%^RESET%^)";
            else if(thieves->GetInCombat())  tmp+=" (%^RED%^combat%^RESET%^)";
            tmp+="\n";
            p++;
         }
      }

    ret+= "%^BOLD%^%^BLACK%^*******************************%^RESET%^%^BOLD%^%^WHITE%^{ %^YELLOW%^'Thief Who'%^BOLD%^%^WHITE%^ }%^RESET%^%^BOLD%^%^BLACK%^***********************$
    ret+=tmp;
    ret+= "\n%^BOLD%^%^BLACK%^*****************************************************************************%^RESET%^  \n";
    write(ret);
    return 1;
 }

static int special_sort(object alpha, object beta) {
    string a, b;

    if((a=(string)alpha->GetGuildRank())!=(b=(string)beta->GetGuildRank())) {
      if(!a) a = "zzzz";
      if(!b) b= "zzzz";
      return strcmp(a, b);
    }
    return 0;
}


Offline capo

  • Friend
  • **
  • Posts: 70
    • View Profile
ordered array? please help
« Reply #4 on: October 24, 2006, 01:57:58 PM »
Unfortunately this seems to sort by the first letter in the rank... not exactly what I was looking for... it returns this:



quote:
> twho

*******************************{ 'Thief Who' }*******************************  



[ Boss      ] Capo the creator

[ Soldier   ] Test the unaccomplished

[ Soldier   ] John the unaccomplished

[ Soldier   ] Tester the unaccomplished

[ Under-Boss] Fred the unaccomplished

[ Z-Test    ] Newbie the unaccomplished



*****************************************************************************  




Rather than by actual rank.. Any ideas?

Offline Aransus

  • Acquaintance
  • *
  • Posts: 2
    • View Profile
ordered array? please help
« Reply #5 on: October 24, 2006, 02:23:17 PM »
The strcmp() function is sorting alphabetically, yes. If you want a hierarchical-type sort, you'll want to tweak Amun-Ra's solution like this:



LPC code:
static int special_sort(object alpha, object beta) {

    mapping titles = ([
        "Boss" : 0,
        "Under-Boss" : 1,
        "Soldier" : 2
    ]);
    int a = titles[ alpha->GetGuildRank() ];
    int b = titles[ beta->GetGuildRank() ];

    if( a < b ) return -1;
    else if( a > b ) return 1;
    return 0;

}




This is just a sample of something that may work. I don't think I advocate doing it this way in the long run, because it seems sensible for rank names and their relative 'levels' to be defined in the same place (wherever GetGuildRank() is getting its info from). This is just a demonstration. Ok, now with the disclaimer out of the way, I hope it works ;).

Offline capo

  • Friend
  • **
  • Posts: 70
    • View Profile
ordered array? please help
« Reply #6 on: October 24, 2006, 02:36:27 PM »
Works great... tweaked it a bit... now have this:





code:
> twho
*******************************{ 'Thief Who' }*******************************  

[  Boss        ] Capo the creator
[  Under-Boss  ] Newbie the unaccomplished
[  Soldier     ] Tester the unaccomplished
[  Soldier     ] Test the unaccomplished
[  Soldier     ] John the unaccomplished
[  Enforcer    ] Testingthree the unaccomplished
[  Associate   ] Testingtwo the unaccomplished

*****************************************************************************  

Offline detah

  • BFF
  • ***
  • Posts: 190
  • Ruler of 2D
    • View Profile
ordered array? please help
« Reply #7 on: October 24, 2006, 11:19:37 PM »
Please post the finalized working code.