• Hey! Guest! The 39th GMC Jam will take place between November 26th, 12:00 UTC and November 30th, 12:00 UTC. Why not join in! Click here to find out more!

Teaching myself basic AI

Guy Danino

Member
After going through several online sources regarding the basic conscept of coding in game maker, I have decided I want to up my game with trying to create some very basic forms of AI.

the first one I created one a square who could randomly jump, move left and right, pause and shoot fireballs, all at random intervals. That one the simpler one.

Now I'm trying to figure out (unsuccessfully) how to create an object that can travel around randomly in a maze, like a pacman ghost going through a random path.

The idea was to start with moving from left to right, and when It reaches an intersection, it will randomly choose one of the available routes it could take.

I just want it to turn whenever it can for now, and make it smarter later on.

the code for scr_findrandompath is:

Code:
var isup, isdown, isleft, isright,

isup = !place_meeting(x, y-sprite_height,obj_wall);
isdown = !place_meeting(x, y+sprite_height,obj_wall);
isleft = !place_meeting (x-sprite_width,y,obj_wall);
isright = !place_meeting (x+sprite_width,y,obj_wall);

if vspeed!=0
{
if (isleft)
{
vspeed = 0;
hspeed = -3;
}

if (isright)
{
vspeed = 0;
hspeed = 3;
}

if (isleft && isright)
{
choose(isleft,isright)
}
if (!isdown || !isup)
vspeed=vspeed*-1;
}

if hspeed!=0
{
if (isup)
{
vspeed = -3;
hspeed = 0;
}

if (isdown)
{
vspeed = 3;
hspeed = 0;
}

if (isup&&isdown)
choose(isup,isdown);

if (!isleft || !isright)
hspeed=hspeed*-1;
}
when I run it, it starts moving left and then it either freezes at the intersection or starts switching between vspeed and hspeed values, making it look like its vibrating. I don't remember exactly what I changed in between the two. I'm pretty sure the problem is that I conditioned the check for the temporary variables by checking whether hspeed or vspeed are not zero.

what happens is its going left, seeing that there is a turn downwards, changes vspeed to -3 and hspeed to 0, and because vspeed is now not 0, its checks and sees that it can go left and changes hspeed to 3 and vspeed back to 3, and so on.

But I have no idea what other condition should I use. I tried a couple that I cant remember right now but non worked.

tl;dr
it gets to an intecsection and stops moving. the check for the intersection is based on direction of speed which is causing the problem but I cant figure out what to condition it by.

What I need basically is a push in the right direction, not a substitute piece of code.. Its important for me to understand and reach the solutions myself, and this is a learning process so I need maybe a hint or something like that.

Thanks in advance for taking the time!
 

Alexx

Member
You need some form of flag as whether you have just reached an intersection, and only look for another direction when a new intersection is reached.

There's a few ways to approach this, but you asked just for method not a solution.
 

Guy Danino

Member
Well, apparently this is more complicated than it sounds, I created another variable containing a script that checks around the bounding box in all directions. its set to true when all four checks do not encounter obj_wall. I put all the rest of the code inside this condition hoping that as soon as the speed value is changed, the object will move which will cause the flag to turn off. but that didn't happen. I hate it when my logic is flawed and I can't figure out why :(
 

TheouAegis

Member
//Create Event:
routes = ds_list_create();
randomize();


//Step Event:
if place_meeting(x+hspeed,y+vspeed,obj_wall) {
while !place_meeting(x+sign(hspeed),y+sign(vspeed),obj_wall) {
x+=sign(hspeed); y+=sign(vspeed);
hspeed = 0; vspeed = 0;
}
ds_list_clear(routes);
if !place_meeting(x+1,y,obj_wall) ds_list_add(routes,3);
if !place_meeting(x-1,y,obj_wall) ds_list_add(routes,-3);
if !place_meeting(x, y-1,obj_wall) ds_list_add(routes,7);
if !place_meeting(x,y+1,obj_wall) ds_list_add(routes,13);
ds_list_shuffle(routes);
var i = routes[| 0];
if i < 0 hspeed = i;
else vspeed = i - 10;
}


That's a purely random method.
 

Guy Danino

Member
Thank you for your time and effort. but what I asked was not for a substitution of code that I will not understand , but rather a push in the right direction. As I have stated, this is a purely a learning exprience and not a part of a project Im building. I won't benefit from it if I will just get a quick fix..

Can you explain the code you wrote? I am already using this type of collision as a script, but can you describe what is going on below and what is ds_list?
 

Alexx

Member
I must say that TheouAegis's method is elegant and on the money.

There is a time that you'll need to increase your knowledge of GML functions and their use.
Try looking up each function in his / her example in the manual (press F1 in GameMaker) and try learn what each does and how it works.

I admire your approach to increase your GML knowledge, but at some point you'll need to learn more functions.
 
Last edited:

Guy Danino

Member
I must say that TheeouAegis's method is elegant and on the money.

There is a time that you'll need to increase your knowledge of GML functions and there use.
Try looking up each function in his / her example in the manual (press F1 in GameMaker) and try learn what each does and how it works.

I admire your approach to increase your GML knowledge, but at some point you'll need to learn more functions.
Thank you! I agree with that approach, I defiantly don't know enough to do what I want to do just yet. the thing is, functions and built in variables are just chunks of codes compressed into single lines. so technically, what I want is to understand how to functions work, and for that I want to find manual ways, and basically trying to write them on my own based on how I understand what needs to be done. for example, I only allowed myself to use vspeed and hspeed after I could program my own variables that functions as these, and then use hspeed and vspeed as a shortcut to what I already know how to do. I want to know what these functions do, and use that to write something on my own. after that works and I understand it, I'll use the functions :)

I will post my way of tackling this manually later on once I figure it out, I'll be happy if you'll take a look at it.
by the way, will your suggested use of a flag variable remove the need of the ds_list?
 
Top