From msn@minnie.bell.inmet.com
Date: Wed, 30 Aug 95 16:50:02 PDT
From: Michael Nikkel <msn@minnie.bell.inmet.com>
To: merc-l@webnexus.com
Subject: Command code

Russ, and anyone else interested.  The easiest way to speed up commands is
to use a small hash array based on the commands first character which points
to the first case of that letter in the command table.  If the command table is
organized with all commands which start with the same first letter grouped
together this works very well.  Also this scheme gives you the flexibility to
arrange any command within the letter group in any order of priority you wish,
thus letting you place "get" before "gamble", but still having fast access.
Granted this isn't the absolute fastest, but it is extremely easy to implement.
And for the number of commands most muds have anything else more elaborate
would just be a waste of time.

The following is a partial example of an interp.c cmd_type and the supporting
hash routine.  Comments to improve this would be greatly welcome.

Example cmd_table in alphabetical order for first character, but in priority
order within each character group...

const   struct  cmd_type        cmd_table       [] =
{
    { "auto",           do_auto,        POS_DEAD,        0,  LOG_NORMAL },
    { "alias", 		do_alias,       POS_DEAD,        0,  LOG_NORMAL },
    { "areas",          do_areas,       POS_DEAD,        0,  LOG_NORMAL },

    { "buy",            do_buy,         POS_RESTING,     0,  LOG_NORMAL },
    { "balance",        do_balance,     POS_DEAD,        0,  LOG_NORMAL },
    { "bug",            do_bug,         POS_DEAD,        2,  LOG_NORMAL },

    { "cast",           do_cast,        POS_FIGHTING,    0,  LOG_NORMAL },
    { "chat",           do_chat,        POS_SLEEPING,    0,  LOG_NORMAL },

    /*
     * End of list.
     */
    { "",               0,              POS_DEAD,        0,  LOG_NORMAL }
};


Very simple hash routine to hash both the commands.
The reason you set the hash table to the last array Item is so that it
quickly finds a null string.  To save that loop you could consider putting
a reserved null command at the beginning of the cmd_struct and just setting
Hash_commands[cnt] = 0;  Since hash_commands is only run once at bootup in
db.c when the areas are loaded I saw no reason to mess with this though.

The hash_command routine could be modified to handle socials in exactly the
same manner.


/* ========================================================================= */
/* Hash commands (Ironhand)                                                  */
/* ========================================================================= */

void hash_commands( )
{
   sh_int         cmd, num_cmds, cnt, iHash;

   /* Count the number of commands */
   /* ---------------------------- */

   for( num_cmds = 0; cmd_table[num_cmds].name[0] != '\0'; num_cmds++ );

   /* Initialize the Hash array to the last value */
   /* ------------------------------------------- */

   for( cnt = 0; cnt < 126; cnt++ )
      Hash_commands[cnt] = num_cmds;

   /* Set the Hash array to point to the first comand which starts */
   /* with a particular character                                  */
   /* ------------------------------------------------------------ */

   for( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ )
   {
      iHash = cmd_table[cmd].name[0] % 126;
      if ( Hash_commands[iHash] == num_cmds )
         Hash_commands[iHash] = cmd;
   }

   return;
}


Change the command lookup in interpret to contain the following:

    /*
     * Look for command in command table.
     */
    found = FALSE;
    trust = get_trust( ch );
    for( cmd = Hash_commands[command[0]%126];
         command[0] == cmd_table[cmd].name[0]; cmd++ )
    {
        if ( !str_prefix( command, cmd_table[cmd].name )
        &&   cmd_table[cmd].level <= trust )
        {
            found = TRUE;
            break;
        }
    }


The above code will thus Start at the first command which begins with
the same character as the one input to begin its search, saving a bit of
time with only 126 half_words of space taken.

Once again, I appreciate comments for improvement.

M. Nikkel  (Ironhand)
msn@bell.inmet.com


 =============================================================================
/   ______ _______ ____   _____   ___ __    _ ______    ____  ____   _____   /
\  |  ____|__   __|  _ \ / ____\ / _ \| \  / |  ____|  / __ \|  _ \ / ____\  \
/  | |__     | |  | |_| | |     | |_| | |\/| | |___   | |  | | |_| | |       /
/  | ___|    | |  | ___/| |   __|  _  | |  | | ____|  | |  | |  __/| |   ___ \
\  | |       | |  | |   | |___| | | | | |  | | |____  | |__| | |\ \| |___| | /
/  |_|       |_|  |_|  o \_____/|_| |_|_|  |_|______|o \____/|_| \_|\_____/  \
\                                                                            /
 ============================================================================

------------------------------------------------------------------------------
ftp://ftp.game.org/pub/mud      FTP.GAME.ORG      http://www.game.org/ftpsite/
------------------------------------------------------------------------------

 This archive came from FTP.GAME.ORG, the ultimate source for MUD resources.

------------------------------------------------------------------------------