Page 1 of 1

Closest target AI example

PostPosted: Sun Feb 26, 2017 3:47 pm
by lcl
Hello!

I made a small demo of AI that targets the closest enemy and only if no other AI is already closer to that enemy.
The demo is pretty quickly made and thus the programming is kind of messy and not a good example of programming, but the logic of the system is the main thing here.

Basically what the code does is:
  • Loop through every target actor clone
  • Find the AI that is closest to the current target
  • See, if the current target is closer to the AI than the previously found closest target and if it is, replace the old with the current one
  • Move each AI to the target that is closest to them

Closest target AI.zip
Download the demo (requires Game Editor 1.4.1)
(497.3 KiB) Downloaded 174 times



Re: Closest target AI example

PostPosted: Sun Feb 26, 2017 6:34 pm
by schnellboot
Cool!
The global focus is AI nowadays, so I think it's really neat to see some examples on this topic.

Re: Closest target AI example

PostPosted: Sun Feb 26, 2017 7:06 pm
by lcl
Thanks! :)

Re: Closest target AI example

PostPosted: Mon Feb 27, 2017 8:24 am
by ITomi
I download it a few minutes ago and looking over just now. I had to set the resolution lower, but it works perfectly. I hope, I will learn good GE programming techniques from it. Thank you! :D
P.S.: the function getclone() doesn't work perfectly? Because there is a getclone2() function in the GE 1.4.1.b. I tried to use the getclone() in GE 1.4.0, but I didn't know how it is work...

Re: Closest target AI example

PostPosted: Mon Feb 27, 2017 2:29 pm
by lcl
ITomi wrote:I download it a few minutes ago and looking over just now. I had to set the resolution lower, but it works perfectly. I hope, I will learn good GE programming techniques from it. Thank you! :D

Okay, good thing I coded it to adapt to changes in resolution :D And well, this is not really a prime example of good GE programming, but I'm sure you still can learn a thing or two from it. :)
ITomi wrote:P.S.: the function getclone() doesn't work perfectly? Because there is a getclone2() function in the GE 1.4.1.b. I tried to use the getclone() in GE 1.4.0, but I didn't know how it is work...

There's no problem with getclone(), it works just as it should. getclone2() is a slightly different function implemented because of its usefullness and the fact that most people here dealing with cloned actors always ended up writing their own getclone2() functions.

The difference is that getclone() takes only one input, an actor's clonename while getclone2() takes two inputs, actors name and it's cloneindex, thus being much easier to use when you, for example, have to perform an operation for all clones.

getclone() example:
Code: Select all
// This moves myActor's fourth (indexes start from 0) clone to position 150 on x-axis
getclone("myActor.3")->x = 150;

getclone2() example:
Code: Select all
int i;

for (i = 0; i < 10; i ++)
{
    // This positions the first 10 clones to x = 0, x = 30, x = 60, etc.
    getclone2("myActor", i)->x = 30 * i;
}


getclone() on GE's Script Reference: http://game-editor.com/docs/script_refe ... m#getclone
(That site is a friend, I recommend bookmarking it :wink:)

Re: Closest target AI example

PostPosted: Tue Feb 28, 2017 2:41 pm
by ITomi
I often read the GE's Script Reference, but getclone2() wasn't included in it yet.
I tried to use the old getclone() to ask attributes (e.g.: X and Y coordinates) of particular actors, but I couldn't do it. For example this code is not work:
Code: Select all
int i;
char a_ghost;

i=2;
a_ghost=strcat("ghosts.",i);
sprintf(text,"X place:%d",getclone(a_ghost)->x);

I can realize it only with getclone2()?

Re: Closest target AI example

PostPosted: Tue Feb 28, 2017 8:11 pm
by lcl
ITomi wrote:I tried to use the old getclone() to ask attributes (e.g.: X and Y coordinates) of particular actors, but I couldn't do it. For example this code is not work:
Code: Select all
int i;
char a_ghost;

i=2;
a_ghost=strcat("ghosts.",i);
sprintf(text,"X place:%d",getclone(a_ghost)->x);

I can realize it only with getclone2()?

This code's problem is not getclone(). It's that there's a couple of errors in it.

First thing you should notice is that char a_ghost; doesn't define a string pointer (a pointer to an array of chars), but instead a variable that can hold a single character, like 'e' for example. To define a string pointer you have to do this:
Code: Select all
char *a_ghost; // This would define a pointer to a character or an array of characters

Second thing is that you're using strcat() incorrectly. First off, you can't give strcat() a string literal as the first argument. strcat() will append the second string to the first one, but if the first one is a string literal, it's just as many characters long as the string literal is, meaning that there's no space to add any other characters to. strcat() also returns a pointer to a string (an array of chars), so the variable that you want to assign the returned value to has to also be a char pointer (char *), not a single char.

One last problem is that an actor's x coordinate is not an integer, but a double value, so %d won't work in sprintf. You either have to use %f or to cast the value to integer type first.

Here's the two alternative ways to fix your code:
Code: Select all
sprintf(text, "X place: %f", getclone("ghosts.2")->x); // Now sprintf is looking for a real variable
sprintf(text, "X place: %d", (int)getclone("ghosts.2")->x); // The (int) part casts the value to integer type so that sprint can deal with it correctly


But if you want to pass the cloneindex number by a variable, I'd suggest you to use sprintf for that:
Code: Select all
char temp[100]; // An array of chars, 100 chars long
int i = 2;

sprintf(temp, "ghosts.%d", i);
sprintf(text, "X place: %d", (int)getclone(temp)->x);


I hope this cleared some things up for you! :)

Re: Closest target AI example

PostPosted: Wed Mar 01, 2017 8:43 am
by ITomi
Thank you, Lcl, I will try it. Some attributes of C language still unusual a bit for me (e.g.: pointers, etc.), but I will get into.
Otherwise, can I give a variable to getactor() in its parameter? For example, across a loop:
Code: Select all
for (i=0;i<ActorCount("ghosts");i++)
{
 sprintf(text,"GhostX:%d",(int)getclone("ghosts.i")->x);
};

(My first game ("Zozóhami") is almost finished, now I'm working on the levels.)

Re: Closest target AI example

PostPosted: Wed Mar 01, 2017 3:38 pm
by lcl
ITomi wrote:Otherwise, can I give a variable to getactor() in its parameter? For example, across a loop:
Code: Select all
for (i=0;i<ActorCount("ghosts");i++)
{
 sprintf(text,"GhostX:%d",(int)getclone("ghosts.i")->x);
};

(My first game ("Zozóhami") is almost finished, now I'm working on the levels.)

No, you can't do that. As soon as you put 'i' inside the double quotes it becomes just another character in the string literal. That code would literally try to get the x of ghosts.i, but i does not mean any number here, it's just a character i. An actor's cloneindex can not be a character (obviously). What you are trying to do is exactly the reason why getclone2() exists. It is way easier to use for looping through all clones:
Code: Select all
for (i=0;i<ActorCount("ghosts");i++)
{
 sprintf(text,"GhostX:%d",(int)getclone2("ghosts", i)->x);
}

But what you want to do can of course be achieved with getclone() as well. It just requires a temporary string variable for forming the correct string. Just do what the last example in my previous post did.
lcl wrote:But if you want to pass the cloneindex number by a variable, I'd suggest you to use sprintf for that:
Code: Select all
char temp[100]; // An array of chars, 100 chars long
int i = 2;

sprintf(temp, "ghosts.%d", i);
sprintf(text, "X place: %d", (int)getclone(temp)->x);

So, to apply that to a for loop that goes through all clones, here's what you'd have to do:
Code: Select all
int i;
char temp[100];

for (i = 0; i < ActorCount("ghosts"); i ++)
{
    sprintf(temp, "ghosts.%d", i); // Form the correct input string for getclone(). For example, when i = 3, temp will now contain the string "ghosts.3"
    sprintf(text, "GhostX: %d", (int)getclone(temp)->x);
}

(But a loop like that makes no sense because the only value that will be shown is the x of the last clone found..)

Re: Closest target AI example

PostPosted: Thu Mar 02, 2017 1:41 pm
by ITomi
Aha. So, it needs a temporary variable to join and store the variable that the getclone() will be able to process it?
And can I covert type of variables if I write (int) or (char), etc. in front of a variable?
(I ask these just because I've crib a technique to see an unique actor from your closest target AI example, but I can imagine with difficulty it without using function getclone(), but it seems not proper for this task(?).)

Re: Closest target AI example

PostPosted: Thu Mar 02, 2017 4:20 pm
by lcl
ITomi wrote:Aha. So, it needs a temporary variable to join and store the variable that the getclone() will be able to process it?

Yes, that's the only way to do it, you have to use a temporary string to build the correct input for getclone().
ITomi wrote:And can I covert type of variables if I write (int) or (char), etc. in front of a variable?

It's called type casting, and yes, basically you can, but it's a little more complicated than just converting variable types.

In case of converting a double to an int (like I showed you) what casting does is to ignore the digits after the decimal point. So, casting 5.2 to int returns 5 but also casting 5.9 to int still returns 5.
Code: Select all
double testDouble = 5.2;
int myInt = (int)testDouble;
sprintf(text, "%d", myInt); // This will print 5

Code: Select all
double testDouble = 5.9;
int myInt = (int)testDouble;
sprintf(text, "%d", myInt); // This will print 5

Converting a char to an int gives you the ASCII value of the character in question. For ASCII values check the ASCII table.
Code: Select all
char testChar = 't';
int myInt = (int)testChar;
sprintf(text, "%d", myInt); // This will print 116 because that's the ASCII code for the letter 't'

ITomi wrote:(I ask these just because I've crib a technique to see an unique actor from your closest target AI example, but I can imagine with difficulty it without using function getclone(), but it seems not proper for this task(?).)

Sorry, I don't quite understand what you're saying there..?