Re: [TOTD] (maybe) purgeplay

From: James Turner (turnerjh@XTN.NET)
Date: 04/22/98


Angus Mezick <angus@EDGIL.CCMAIL.COMPUSERVE.COM> writes:

> I added this to the purgeplay utility to reduce the number of idnum's used.
> at the top:
[snip]
> I did this because the code seems to assume that ID nums are in sequential
> order.  seemed kind of bad to have big gaping holes in there. esp since i can
> now do a binary search by idnum on the player_table
> Anyone see any code conflicts here?

This will be a Bad Thing.  The problem here is that id nums are used
for a lot of things that have persistance over reboots -- house
ownership, posters on boards, mail recipient and sender, and maybe
more.  They're very much needed, and if an id number changes, as far
as the code is concerned, it's a different player.

However, you're mistaken -- even if there are gaps in the numbers, you
can still do binary searches.  Binary searching works even if the
numbers aren't consecutive.  The man page on bsearch (and the related
qsort) should give you the info you need to avoid having to rewrite
something already part of the C standard library :)

For example, say you have an array of pointers to players:

struct char_data *players[NUM_PLAYERS];

Now, to search these using bsearch, you need to write a helper
function:

int
compare_player_ids(void *p1, void *p2)
{
  struct char_data *ch1, *ch2;

  ch1 = (struct char_data *p1);
  ch2 = (struct char_data *p2);

  return ch1->idnum - ch2->idnum;
}

Then, you can call bsearch:

struct char_data *tch, *target_id;
int id_num_to_search_for = 15;

CREATE(target_id, 1, struct char_data);
target_id->id_num = id_num_to_search_for;

tch = (struct char_data *) bsearch((void *)target_id, players,
                                   NUM_PLAYERS,
                                   sizeof(struct char_data *),
                                   compare_players_ids);

free(target_id);

Then tch will have a pointer to the character in the array that had
the id id_num_to_search_for.

This is ugly, though, and probably would best be hidden behind a
wrapper function.  Here's the prototype -- writing it basically
involves copying the above into a function:

struct char_data *
search_array_for_id(struct char_data *arr, int size, int targ_id);

Then you could call search_array_for_id thusly:

vict = search_array_for_id(players, NUM_PLAYERS, 15);

Of course, you could also write your own bsearch function, but there
is an advantage in this.  Suppose you wanted to also sort the list.
You could call

qsort(players, NUM_PLAYERS, sizeof(struct char_data *),
      compare_players_ids);

That would sort the list using a quick sort.

qsort and bsearch are two very useful standard C library functions.

Hmm someone asked for a tip of the week, maybe this sortakinda
qualifies.

Chip

--
James Turner               turnerjh@xtn.net
                           http://www.vuse.vanderbilt.edu/~turnerj1/


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/15/00 PST