Closest target AI example

Learn how to make certain types of games and use gameEditor.

Closest target AI example

Postby lcl » Sun Feb 26, 2017 3:47 pm

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


Attachments
screenshot.png
User avatar
lcl
 
Posts: 2339
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 276 Give a positive score

Re: Closest target AI example

Postby schnellboot » Sun Feb 26, 2017 6:34 pm

Cool!
The global focus is AI nowadays, so I think it's really neat to see some examples on this topic.
schnellboot
 
Posts: 819
Joined: Sat Mar 31, 2007 1:35 pm
Location: Germany
Score: 102 Give a positive score

Re: Closest target AI example

Postby lcl » Sun Feb 26, 2017 7:06 pm

Thanks! :)
User avatar
lcl
 
Posts: 2339
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 276 Give a positive score

Re: Closest target AI example

Postby ITomi » Mon Feb 27, 2017 8:24 am

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...
User avatar
ITomi
 
Posts: 48
Joined: Sun Aug 21, 2016 1:56 pm
Location: Hungary
Score: 5 Give a positive score

Re: Closest target AI example

Postby lcl » Mon Feb 27, 2017 2:29 pm

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:)
User avatar
lcl
 
Posts: 2339
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 276 Give a positive score

Re: Closest target AI example

Postby ITomi » Tue Feb 28, 2017 2:41 pm

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()?
User avatar
ITomi
 
Posts: 48
Joined: Sun Aug 21, 2016 1:56 pm
Location: Hungary
Score: 5 Give a positive score

Re: Closest target AI example

Postby lcl » Tue Feb 28, 2017 8:11 pm

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! :)
User avatar
lcl
 
Posts: 2339
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 276 Give a positive score

Re: Closest target AI example

Postby ITomi » Wed Mar 01, 2017 8:43 am

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.)
User avatar
ITomi
 
Posts: 48
Joined: Sun Aug 21, 2016 1:56 pm
Location: Hungary
Score: 5 Give a positive score

Re: Closest target AI example

Postby lcl » Wed Mar 01, 2017 3:38 pm

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..)
Last edited by lcl on Sun Mar 26, 2017 11:32 am, edited 2 times in total.
User avatar
lcl
 
Posts: 2339
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 276 Give a positive score

Re: Closest target AI example

Postby ITomi » Thu Mar 02, 2017 1:41 pm

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(?).)
User avatar
ITomi
 
Posts: 48
Joined: Sun Aug 21, 2016 1:56 pm
Location: Hungary
Score: 5 Give a positive score

Re: Closest target AI example

Postby lcl » Thu Mar 02, 2017 4:20 pm

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..?
User avatar
lcl
 
Posts: 2339
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 276 Give a positive score


Return to Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest