Skip to main content
GameDev.net gamedev.net
🔒 Locked

I need help with a simple AI

Started by Forkaster May 22, 2009 at 5:09 AM 9 replies 2.1k views
Original Post
Forkaster
Forkaster
Hi, I am not entirely sure this is the correct forum for what i am about to ask, but here goes. I need to code an "AI" for a "bot" that moves around the world map randomly, but when the distance from him to the player is less or equal than a defined value the will turn to the player and run towards it. I have succeeded in writing something that works, but it has a bug that i do not understand/know how to fix. So i'll leave the code i have here with hope that some one can help me out, or give me a better suggestion

typedef struct guardian
{
	double pos_x, pos_y, pos_z;

	double look_at_x, look_at_y, look_at_z;

	double horizontal_angle;

	int HAS_DESTINATION;
	
	double destination_x,destination_z;

}Guardian;

void guardiansMoviment()
{
	for(int i=0; i<NUMBER_OF_GUARDIANS;i++)
	{
		double dist=distanceGuardian(guardians);
		if(dist <= DIST_MIN)
		{
			guardians.destination_x = agent.pos_x;
			guardians.destination_z = agent.pos_z;

			guardians.HAS_DESTINATION = 1;
		}
		
		guardianRandomMoviment(i);
		destinationDirection(i);

		guadianStep(1,i);
	}
}

void guardianRandomMoviment(int i)
{
	if(!guardians.HAS_DESTINATION)
	{
		guardians.destination_x = 3 + rand()/(double)RAND_MAX*(WORLD_WIDTH-6);
		guardians.destination_z = 3 + rand()/(double)RAND_MAX*(WORLD_LENGTH-6);
		guardians.HAS_DESTINATION = 1;
	}

	if(distanceGuardianDestination(guardians) <= 0.0)
	{
		guardians.HAS_DESTINATION = 0;
	}
}

void destinationDirection(int i)
{
	double difx = guardians.pos_x - guardians.destination_x;
	double difz = guardians.pos_z - guardians.destination_z;
	
	double destination_angle = atan2(difx,difz) * RAD;
	
	guardians.horizontal_angle = destination_angle;
	
	guardians.look_at_x = sin(guardians.horizontal_angle); 
	guardians.look_at_z = cos(guardians.horizontal_angle);
}

void guadianStep(double step,int i)
{
	double new_pos_x = guardians.pos_x + step * (guardians.look_at_x);
	double new_pos_z = guardians.pos_z + step * (guardians.look_at_z);

	guardians.pos_x = CLAMP(new_pos_x,2,WORLD_WIDTH-3);
	guardians.pos_z = CLAMP(new_pos_z,2,WORLD_LENGTH-3);

	guardians.pos_y = terrainGetInerpolatedHeight(guardians.pos_x,guardians.pos_z) + 1.f;
}

The bug that occurs with the code above is that when the guardians are near (not sure of the distance) the player and if the gives a step backward/forward the guardians stop closing in on the player, they seem to be rotating in place. [Edited by - Forkaster on May 22, 2009 5:27:48 AM]
Zakwayda
Zakwayda
For source code, use [source] tags rather than [quote] tags; that will make it easier for us to read. (You can edit your post using the 'edit' button in the upper right.)
Forkaster
Forkaster
Edited the post.

I did not know of the existence of the source tag.
Zakwayda
Zakwayda
In this line of code:
double destination_angle = atan2(difx,difz) * RAD;
What is the '* RAD' for?
Forkaster
Forkaster
Well, the "* RAD" bit is something that i honestly think that shouldn't be there.

The "RAD" is a defined value to convert an angle between radian and degrees. Honestly I don't think it should be there, but if i remove it the Guardians stop moving in the right direction.
Zakwayda
Zakwayda
Quote:
Original post by Forkaster
Well, the "* RAD" bit is something that i honestly think that shouldn't be there.

The "RAD" is a defined value to convert an angle between radian and degrees. Honestly I don't think it should be there, but if i remove it the Guardians stop moving in the right direction.
If it converts from degrees to radians, then it shouldn't be there; the value returned by atan2() is already in radians. (I'm not sure though why you're getting better results with it than without it...)
Forkaster
Forkaster
Tomorrow i am planning to look at it in alot of detail. But yeah i know all that you have said. I guess i have a bug very well hidden.
zanmato
zanmato
atan2(y,x) already returns the angle in radians, so there's no need to do any extra work for converting it yourself. I'm not sure what the RAD const/macro is, but I'm guessing it's something like #define RAD (3.14/180), and if that's the case then it's screwing up atan2's result.

Also, atan2() expects the arguments to be [y,x], so if you're giving it [x,z] (I assume with z being basically the y component in a top-down 2d coordinate system view) then you'll probably get incorrect results from that as well.

By the way, if e.g. you're not sure about what distance the behavior is being caused at, it's always a good idea to keep a log or simply printf() some stuff while your app is running. That way at least you can keep track of some of the numbers running behind the scenes so to speak. Personally I always have my app running in a window with a console on the side outputting all the debugging text.
Forkaster
Forkaster
Quote:
Original post by zanmato
atan2(y,x) already returns the angle in radians, so there's no need to do any extra work for converting it yourself. I'm not sure what the RAD const/macro is, but I'm guessing it's something like #define RAD (3.14/180), and if that's the case then it's screwing up atan2's result.

Also, atan2() expects the arguments to be [y,x], so if you're giving it [x,z] (I assume with z being basically the y component in a top-down 2d coordinate system view) then you'll probably get incorrect results from that as well.

By the way, if e.g. you're not sure about what distance the behavior is being caused at, it's always a good idea to keep a log or simply printf() some stuff while your app is running. That way at least you can keep track of some of the numbers running behind the scenes so to speak. Personally I always have my app running in a window with a console on the side outputting all the debugging text.


That is what i plan to do tomorrow. It's late here now. I'll get to you tomorrow.
Forkaster
Forkaster
I managed to have noticed the following.

The glitch only occurs when i move backwards and the guardian is at a distance from me of about 10.

I have also noticed that when the guardian speed is smaller this problem does not occur. But he still rotates around itself while i move, but he moves towards me when i stop moving.
wodinoneeye
wodinoneeye


In guardianRandomMoviment(int i)


if(distanceGuardianDestination(guardians) <= 0.0)



should have some kind of DIST_MIN value also (close enough...)

less than or equal to zero may cause a dodging action
if your movement doesnt do partial step when closer than one step from target.

Roundoffs can also make it never be 'equal zero....
--------------------------------------------[size="1"]Ratings are Opinion, not Fact

Topic Locked

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

Sign in to reply to this topic.