Skip to main content
gamedev.net
🔒 Locked

linked list re-ordering problem

Started by Damocles 1 reply 200+ views
Original Post
Damocles
Damocles
I''ve been struggling with this one for about a week now and it''s beginning to drive me nuts. I have a linked list of all the actor objects in my 2d game. I decided I wanted to add a kind of depth factor so that objects could rise and fall (it''s a top-down view). So I added a couple of extra functions to control the actor''s position in the linked list. But it''s causing some pretty nasty errors. I think it''s causing some kind of infinite loop, but I''m not sure how. Perhaps someone can spot what it is I''ve overlooked? Here are the two functions I use to propogate the list:
  
void Actor::RemoveFromActorList()
{
	// remove this actor from the linked list

  	if (FirstActor==NULL && LastActor==NULL)
	{
		log("what the f?  both first actor and last actor are null!");
	}	
	if (FirstActor==this && LastActor==this)
	{
		FirstActor=NULL;
		LastActor=NULL;
		next=NULL;
		prev=NULL;
	}
	else
	{
		if (FirstActor==this)
		{
			next->prev=NULL;
			FirstActor=next;
			next=NULL;
			prev=NULL;
		}
		else if (LastActor==this)
		{
			prev->next=NULL;
			LastActor=prev;
			next=NULL;
			prev=NULL;
		}
		else // in the middle somewhere

		{
			next->prev=prev;
			prev->next=next;
			next=NULL;
			prev=NULL;
		}
	}
}

void Actor::AddToActorList()
{
 	if (FirstActor==NULL)
	{
		FirstActor=this;
		LastActor=this;
	}
	else
	{
		LastActor->next=this;
		prev=LastActor;
		LastActor=this;
	}
}
  
and here are the two new functions which I use to re-order the list...
  
void Actor::InitialNudge(float z)
{
	if (FirstActor==NULL)
		return; // no need to sort a non-existant list


	// set the actors height and sort into the actor list

	zpos=z;
	if (zspeed>0.0f && next!=NULL)
	{
		if (next->zpos>zpos)
			return;
	}
	else if (zspeed<0.0f && prev!=NULL)
	{
		if (prev->zpos<zpos)
			return;
	}
	Actor* A;
	A=FirstActor;
	while (A!=NULL)
	{
		if (A->next!=NULL)
		{
			if (A->zpos>zpos)
			{
				RemoveFromActorList();
				// found our slot

				if (A==FirstActor)
				{
					// insert into first slot

					next=FirstActor;
					FirstActor->prev=this;
					FirstActor=this;
					A=LastActor;
				}
				else if (A==LastActor)
				{
					next=NULL;
					prev=LastActor;
					LastActor->next=this;
					LastActor=this;
					A=this;
				}
				else
				{
					// insert into position before next

					next=A;
					prev=A->prev;
					A->prev->next=this;
					A->prev=this;
					A=LastActor;
				}
			}
		}
		else
			return; // default position is at the end anyway, so just return

		if (LastActor->next!=NULL)
			LastActor->next=NULL;
		A=A->next;
	}
}

void Actor::Nudge(float z)
{
	// move the actors height and check if list needs re-arranging

		// set the actors height and sort into the actor list

	if (zspeed==0.0f)
		return;
	zpos+=z;
	if (zspeed>0.0f && next!=NULL)
	{
		if (next->zpos>zpos)
			return;
	}
	else if (zspeed<0.0f && prev!=NULL)
	{
		if (prev->zpos<zpos)
			return;
	}
	Actor* A;
	if (FirstActor==NULL)
		return; // no need to sort a non-existant list

	A=FirstActor;
	while (A!=this)
			A=A->next; // find the current slot

	if (zspeed>0.0f) // (going up)

	{
		A=A->next;
		while (A!=NULL)
		{
			if (A->next!=NULL)
			{
				if (A->zpos>zpos)
				{
					RemoveFromActorList();
					// found our slot

					if (A==FirstActor)
					{
						// insert into first slot

						next=FirstActor;
						FirstActor->prev=this;
						FirstActor=this;
						A=LastActor;
					}
					else
					{
						// insert into position before next

						next=A;
						prev=A->prev;
						A->prev->next=this;
						A->prev=this;
						A=LastActor;
					}
				//return;

				}
			}
			else
			{
				RemoveFromActorList();
				LastActor->next=this;
				prev=LastActor;
				LastActor=this;
				A=this;
			}
			A=A->next;
		}
	}
	else // zspeed < 0.0f  (going down)

	{
		A=A->prev;
		while (A!=NULL)
		{
			if (A->prev!=NULL)
			{
				if (A->zpos<zpos)
				{
					RemoveFromActorList();
					// found our slot

					if (A==FirstActor)
					{
						// insert into first slot

						next=FirstActor;
						FirstActor->prev=this;
						FirstActor=this;
						A=LastActor;
					}
					else
					{
						// insert into position before prev

						next=A->next;
						prev=A;
						A->next->prev=this;
						A->next=this;
						A=LastActor;
					}
				}
			}
			else
			{
				if (A==FirstActor) // it damn well better do!

				{
					RemoveFromActorList();
					// insert into first slot

					next=FirstActor;
					FirstActor->prev=this;
					FirstActor=this;
					A=LastActor;
				}
			}
			A=A->prev;
		}
	}
}
  
The second function, NudgeActor, takes in a distance to move on the z axis, then attempts to re-order the current actor into a new position if required. During one debug, it seemed to get stuck in the main while loop of this function. It kept trying to sort an infinite number of objects even though only 12 were created
------------------------------------------[New Delta Games] | [Sliders]
Drazgal
Drazgal
Have you tried looking at your debugger and when you get stuck in the loop look at the list, chances are somewhere one of your pointers is pointing back to an earlier node or something so you keep looping and never reach the tail of the list. You might also want to look up the STL list as its very useful when you need to do linked lists and cna avoid annoying bugs like this, sorry I couldnt help more

Ballistic Programs
Damocles
Damocles
Strange. I altered my list remove function so that instead of checking for first point, last point then middle points, it now checks for middle points, last point then first point. Some way, which doesn''t really seem like it should, this has fixed the problem. I would have preferred to understand how, but right now I''m just releived to have it working :D Seems stable enough, no crashes or strange glitches after a couple of hours worth of testing, so fingers crossed
------------------------------------------[New Delta Games] | [Sliders]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.