Page 1 of 1

Programming Question II - Units

Posted: Wed Aug 01, 2001 5:00 am
by Jonozon
Hello,

I have currently got my units set up as an array of 30 ships
when one is lost ie. defeated in battle, I currently am using a loop like this to destroy it.

for(int i = iShiptoDestroy; i < iNumShips; i++)
{
?m_arPlayer.m_arFleet.ptFleet = m_arPlayer.m_arFleet.ptFleet[i+1] //etc for all other attributes
}
Is there a better way to handle units than this that anyone can think of?

[glow=purple,2,300]Jonozon[/glow]

Re: Programming Question II - Units

Posted: Wed Aug 01, 2001 7:40 am
by sonneveld
For data structures where you have to insert and delete items in the middle of it, you might want to consider a linked list.  

Ok.. from here on in I'm going to talk about them as if you haven't come across them before.. if you have.. then I didn't mean to be patronising.

Linked lists are kinda like packets of data that point to the next one in the list.  Each entry (or unit) contains all the info for your unit and then a pointer to the next unit.

struct my_unit_struct
{
   struct my_unit_struct *next;
   int pos_x;
   int pos_y;
   unsigned char *data;
}
typedef struct my_unit_struct UNIT;

the cool thing about linked lists is that you can easily remove an entry by just setting some pointers to skip over it.  the bad thing about linked lists is that you have to traverse through it to get to your item.

so if you want to create a new list of units just do this:

UNIT *unitlist_head;
UNIT *cur, prev=0;
int i;

unitlist_head = malloc(sizeof(UNIT));
unitlist_head->pos_x = 0;
unitlist_head->pos_y = 0;
unitlist_head->data = mydata;

prev = unitlist_head;

for (i=0; i<30; i++)
{
    cur = malloc(sizeof(UNIT));
    cur->pos_x = 0;
    cur->pos_y = 0;
    cur->data = mydata;

    prev->next = cur;
    prev = cur;
}

cur->next = 0;   // the last one in the list has a null pointer
                      // so we know which is the last one


so you've got something like this:
unit1 -> unit2 -> unit3 -> unit4 -> unit5 .... ->unit30

if you wanted to delete one of the unit you do this:

void unit_remove(UNIT *foo)
{
  UNIT *cur, *prev;

  cur = unitlist_head;

  /* search through the list for your unit
      eventually we'll reach the end or the unit */
  while (  (cur!=0) && (cur != foo)  )
  {
     prev = cur;
     cur = cur->next
  }

   if (cur != 0)
  {
      // consider if the unit to be deleted is the head
      if (cur == unitlist_head)
           unitlist_head = unitlist_head->next;
     // in the middle
       else
            prev->next = cur->next;  // previous entry points to current NEXT entry

        free(cur);  // make sure you free the memory
   }
}

ok.. that's probably a bit fiddly.   if you wanted to delete a unit without having to search for it's previous entry.. you could try a double-linked list which has pointers to the next and previous unit..

umm.. I hope that made a bit of sense.. I didn't want to type too much in case you already knew what they were. :)

Search for linked lists in google.. you might be lucky.

- Nick