Page 1 of 1

A.I Programming

Posted: Wed Nov 27, 2013 11:48 pm
by ruthven
Hello everyone! :awesome: , so, I've learning just for couple of days Love and Lua, great indeed, reading and stuff, so I did this little code trying to emulete some AI or something, just a guy walking forever in square, so I did everything with IF's statements and counters, obviously must be a better way to do the same using other stuff, so that's the question to the experts, What's the proper way to do this kind of events in Love and of course using Lua? ^^

Waiting for suggestions.. thanks

here's the code and the .love:

Code: Select all

if veces == 1  then
          player2.x = player2.x + player2.speed * dt
          
      elseif veces == 2 then
          player2.x = player2.x - player2.speed * dt
      elseif veces == 3 then
          player2.y = player2.y - player2.speed * dt
      elseif veces == 4 then
          player2.y = player2.y + player2.speed * dt
      end    
       if player2.x >= 600 and veces == 1 then 
             veces = 2
             semaforo.tiempo = semaforo. tiempo + 1 --veces que llega a punto
             player2.animation = player2.animations.left
      
      elseif player2.x <= 400 and veces == 2 then
             veces = 1
             semaforo.tiempo = semaforo. tiempo + 1  --veces llega
             player2.animation = player2.animations.right
      end
      --hero square walking
      if semaforo.tiempo == 3 then
          veces = 3
          player2.animation = player2.animations.up
      elseif semaforo.tiempo == 6 then
             veces = 2
             player2.animation = player2.animations.left
            -- semaforo.tiempo = 0 --reset time
      elseif semaforo.tiempo == 9 then
             veces = 4
             player2.animation = player2.animations.down
       --      semaforo.tiempo = 2
      elseif semaforo.tiempo == 12 then
             veces = 1
             player2.animation = player2.animations.right
             semaforo.tiempo = 0             
      end
      if player2.y <= 100 and veces == 3 then
        veces = 4
        semaforo.tiempo = semaforo. tiempo + 1 --veces que llega a punto
        player2.animation = player2.animations.down
      elseif player2.y >= 410 and veces == 4 then
             veces = 3
             semaforo.tiempo = semaforo. tiempo + 1 --veces que llega a punto
             player2.animation = player2.animations.up
end

Re: A.I Programming

Posted: Thu Nov 28, 2013 12:30 am
by iPoisonxL
That's the way I would do it. I'm not sure if there's a better way at all.

Re: A.I Programming

Posted: Thu Nov 28, 2013 12:56 am
by kikito
If you put the coordinates of the square in a table, you can have a smaller algorithm, which will be also more maintainable and easier to extend.

This could be the path:

Code: Select all

local path = { {x=0,y=0}, {x=600,y=0}, {x=600,y=400}, {x=0,y=400} }
You will also need some variables to know where you want to go next. Depending on your implementation, you will need to put them in local variables or inside your player/monster, as attributes. I would have two: one for the index, and one for the goal itself.

Code: Select all

local current_goal_index = 1
local current_goal = path[current_goal_index]
Now you need to move your player up/down or left/right depending on whether he's up/down of current_goal.y, and left/right of current_goal.y.

Once he's very near current_goal, you can assume he's reached it. Don't try to test for equality, because dt makes it very difficult to 'land' on exactly one number. If the sum of the abs differences is < 1, then you are near enough.

Code: Select all

local dx, dy = math.abs(player.x - current_goal.x), math.abs(player.y - current_goal.y)
if dx + dy < 1 then -- the player is on the goal, proceed to the next
To proceed to the next goal you have to increase current_goal_index by 1, but if it's greater than #path you have to make it one. That can be done with a little math with the % operator:

Code: Select all

if dx + dy < 1 then -- the player is on the goal, proceed to the next
  current_goal_index = (current_goal_index + 1) % #path
end
That's the gist of it. I hope it is enough for you to fill the blanks.

This method has the advantage of not only accepting rectangles of any kind; you can give your player any polygon of any arbitrary size. It might not look great if the player only moves up/down and left/right. You might need some trigonometry in order to make it move just the right amount in the right direction instead. It's also more maintainable since there are no "magic numbers" laying around in your code - if you want to change the square width to 500, you have to make changes only in path. Also, if you make path a member of player, you could have different players following different paths.

Re: A.I Programming

Posted: Thu Nov 28, 2013 8:24 am
by ivan
kikito's answer is on the right path.
To make your agent steer smoothly, you have to look into "path following" which Buckland discusses in his book based on the work of Craig Reynolds.
More generally speaking, your AI system could use one of several approaches.

1) Finite state machines are one of the easier design solutions where you could have a "followPath" state that is initialized using a table of positions.

2) Behavior trees are a little more complicated where behaviors are decomposed into "atomic goals" so you would write AI scripts that (more or less) look like:

Code: Select all

follow = sequence()
follow [1] = move_to(200, 200)
follow [2] = move_to(0, 0)
follow [3] = move_to(100, 100)
follow [4] = move_to(200, 200)
ai.set_goal ( agent, follow )

Re: A.I Programming

Posted: Fri Nov 29, 2013 1:15 am
by ruthven
Thank you so much guys, indeed is a great improvement your method kikito :ultrahappy: and more elegant, I've changed it, ivan, I'll get the book, thanks, ,
Edit: I was wrong,,, :? I thought I have it but there's something I'm missing, my hero does the square but sometimes he loops, must be something bad in my ifs to reach the current_goal, I can't figure out what, some help will be great.. :awesome: