Archived

This topic is now archived and is closed to further replies.

GrayKnight2k

Please help me figure this out...

Recommended Posts

Hi all, I''m new to Artificial Intelligence. Right now I''m using Visual Basic 6 for my games programming. I have a game in the very early stages that I''ve been working on for some time now. It''s one screen per level, and uses tiles. There are the walkable tiles and the nonwalkable wall tiles. I have a user-controlled player, and an enemy that moves (well, somewhat moves) through the level and goes after the player. There''s no way I can figure it out on my own...The player can move around the level, the walls stop him, and the enemy can initially find out what direction to travel in to get to the player (the walls also stop the enemy). The problem is, the enemy won''t walk around all of the walls to get to the player taking the best route possible. I am in dire need of someone to help me with this (preferably do it for me, just because I can''t fathom how to do it and it would help me a whole lot!), and so I have zipped up a file and am ready to send it to any willing Code Master who thinks they might be able to help me solve this problem. What needs to happen is the enemy must know to walk around the walls and stay on path to the player...If it gets jammed in a corner, or even by just one wall, it needs to know how to walk around it or back out of it (in the corner''s case) and I can''t pull it off. What''s in it for you... 1)Your name will be placed on a very Special Thank You list when my project has been completed (and it will be completed!) 2)You will have the satisfaction of knowing you helped a poor newbie who can''t do AI worth an Irish Jig in winter time..(I''m Irish, don''t ask...) SO there it is. Thanks a lot for your help in advance (and I''ll thank you about a million more times as well) and let the requests for my amazing AI file begin! -Gk2k

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

Sounds like a job for the A* algorithm. Do a search on it. Use www.google.com. Also search for it here on gamedev.net. It really is the bog-standard path finding algo out there, and is not too difficult to employ.

I really doubt you will get anyone to just up and write it for you. However, if you at least make an attempt at writing your own algorighthm, and ask a question here when you run into a brick wall, you will find plenty of peeps who will help you.

Share this post


Link to post
Share on other sites
Right, thanks. I suppose you''re right. It''s just that I''ve tried so many different things for this AI and for countless hours at that, I thought I''d take a shot at the possiblity of someone doing all my dirty work. =)

But in any case, thanks a lot. I''ll look into this algorithm.

-Gk2k

Share this post


Link to post
Share on other sites
i haven''t learned much about A*, but another easy way to find paths is with a recursive maze traversal algorithm. assuming your tiles are only up/down/left/right and your grid isn''t too huge, the performance factor shouldn''t be too much of a hit. if you don''t know how to implement this, just ask.

cyn

Share this post


Link to post
Share on other sites
Do a search here on Gamedev, and also on search engines like Google. The keyword you want is Pathfinding. Specific algorithms include A* (A Star), BFS (Breadth First Search), and Dijkstra''s algorithm. (Note: a lot of people post on here with ''new'' or ''different'' algorithms... but they are nearly always just one of the ''standard'' ones, just that the writer didn''t know it. For example, Cyn''s suggestion is either Breadth-first search or Depth-first search depending on how you implement the recursion. Breadth-first requires an added data structure such as a queue, I think.)

Share this post


Link to post
Share on other sites
Here''s a simple idea.

I''ve never understood all of those pathfinding things, so you could just cheat a bit. Just make a copy of the enemy and send him around the play area. Whenever he meets a point where he has the option of going down more than 1 route, get him to go down either of them randomly. Keep doing this until he meets the player. Then record how long it took to get there. If after, say 10 squares, he hasn''t met the player, start again. Repeat this process several times. Then, get him to go down the route that took the least time. (If none of the routes met him, make him go in a random direction.)

I''ve made a game already like yours and this works well. It makes the enemy act more randomly, and it is more effective when closer to the player. The other pathfinding ways may result in the enemy moving perfectly, which wouldn''t be much fun for anybody who wanted to play the game - more a form of torture. My way at least gives the player a chance. Go on, try it.

Share this post


Link to post
Share on other sites
Hello all - thanks for so many responses. First thing off, Cyn, I like the sound of your idea (I have no idea where to begin with A*) but I'm not sure how to do the recursive maze traversal algorithm. I'd like to know more about it if you would enlighten me a bit. The game entities only travel up/down/left/right and my grid is 20 squares long by 24 squares high.

MarkyD - That is a really cool idea, I think that would definitely enhance the game play with your way of "cheating" for the enemy's path to the player. Unfortunately I'd have no idea how to implement it.

And Kylotan - thanks for your input on the various different algorithms and advice...I've looked into a lot of different path finding algorithms..I found this page last night that seemed to have everything I needed, however for an individual with my skill level, it was like trying to decipher an ancient dialect of chinese writing with a broken flash light.

Unfortunately my problems still lie in the actual coding aspects. MarkyD's idea sounded easiest to me...I could have an enemy, take a copy of that enemy and have it travel down and to the left, down to the right...but I'd still have troubles figuring out how to save those paths and telling the computer which squares are ok and which ones aren't. Sorry, this is all very confusing for me. =0

I'm keeping up my efforts...

Thanks to all,
-Gk2k

Edited by - GrayKnight2k on August 12, 2001 1:07:54 PM

Share this post


Link to post
Share on other sites
Hi there! It may have taken me a couple of hours to do, but I have (finally) written the code that you want. It could be improved - it’s rather s***ty, actually - but it should do. It’s written in Delphi, but I’ve crammed it full of comments so that (nearly) anyone can follow it. Those not familiar with Delphi should know that text in between curvy brackets ‘{}’ and after double slashes ‘//’ are comments. It’s rather big, though, and I am aware of spelling mistakes, so don’t point them out! Whoops. Anywho, here it is. Enjoy!

  

type
Directions = (none, left, right, up, down);
const
XPlayArea = 10; // The X size of the play area (in this case, 10)

YPlayArea = 10; // The Y size of the play area (in this case, 10)

NumOfTrys = 10; // The number of trys the algorithm does (in this case, 10)

NumOfMoves = 10; // The number of moves that the algorithm goes into (in this case, 10)

var
px : integer; // The x coordinate of the player

py : integer; // The y coordinate of the player

ex : integer; // The x coordinate of the enemy

ey : integer; // The y coordinate of the enemy

Dir : Directions; // The direction of the enemy

Occ : array[1..XPlayArea] of array[1..YPlayArea] of Boolean;
// True or False. True if the square is unusable; False if the square is usable


Procedure Move_Enemy;

var
LeastMoves : Integer; // Keeps a record of the least number of moves it takes to reach the player

NewDir : Directions; // The final direction that the algorithm chooses

TempDir : Directions; // The direction that the algorithm is moving in

PTempDir : Directions; // The previous direction that the algorithm was moving in

StartDir : Directions; // The very first direction that the algorithm chooses

Finished : Boolean; // True if the algorithm has finished; False otherwise

Succeeded : Boolean; // True if the algorithm has found the player; False otherwise


cx : Integer; // The x position of the ''Copy'' of the enemy

cy : Integer; // The y position of the ''Copy'' of the enemy


Left1 : Boolean; // True if the square on the left is available (in the algorithm)

Right1 : Boolean; // True if the square on the right is available (in the algorithm)

Up1 : Boolean; // True if the square above is available (in the algorithm)

Down1 : Boolean; // True if the square below is abailable (in the algorithm)


CurrentTry : Integer; // The current route that is algorithm is working on

CurrentMove : Integer; // The current move that is being studied

CurrentSquare : Integer; // The number of squares the algorithm has covered


Left : Boolean; // True if the square on the left is available

Right : Boolean; // True if the square on the right is available

Up : Boolean; // True if the square above is available

Down : Booelan; // True if the square below is abailable

NumOfRoutes : Integer; // Keeps a record of how many ajacent squares are available


RandomNum : Integer; // The random number


begin

NumOfRoutes:=0; // There are no available routes of the current square

Left:=false; // Initializes...

Right:=false // ...these...

Up:=false; // ...four...

Down:=false; // ...variables


{if the enemy is not in the far left column, and the square on the left is available...}
if (ex > 1) and (Occ[ex-1][ey] = false) then
begin
Left:=true; // ...Set ''Left'' to TRUE

Inc(NumOfRoutes); // Increases the number of routes

end;

{if the enemy is not in the far right column, and the square on the right is available...}
if (ey < XPlayArea) and (Occ[ex+1][ey] = false) then
begin
Right:=true; // ...Set ''Right'' to TRUE

Inc(NumOfRoutes); // Increases the number of routes

end;

{if the enemy is not in the highest row, and the square above is available...}
if (ex > 1) and (Occ[ex][ey-1] = false) then
begin
Up:=true; // ...Set ''Up'' to TRUE

Inc(NumOfRoutes); // Increases the number of routes

end;

{if the enemy is not in the lowest row, and the square below is available...}
if (ey < YPlayArea) and (Occ[ex][ey+1] = false) then
begin
Down:=true; // ...Set ''Down'' to TRUE

Inc(NumOfRoutes); // Increases the number of routes

end;

if NumOfRoutes = 1 then // If there is only one route available...

begin
if Left = true then NewDir:=Left; // If the enemy can only go left, make it go left

if Right = true then NewDir:=Right; // If the enemy can only go right, make it go right

if Up = true then NewDir:=Up; // If the enemy can only go up, make it go up

if Down = true then NewDir:=Down; // If the enemy can only go down, make it go down

end;

if NumOfRoutes = 2 then // Tf there are two routes available...

begin
{if the enemy can go left, and didn''t already come from the left, make it go left}
if (Left = true) and (Dir <> Right) then
NewDir:=Left;

{if the enemy can go right, and didn''t already come from the right, make it go right}
if (Right = true) and (Dir <> Left) then
NewDir:=Right;

{if the enemy can go up, and didn''t already come from above, make it go up}
if (Up = true) and (Dir <> Down) then
NewDir:=Up;

{if the enemy can go down, and didn''t already come from below, make it go down}
if (Down = true) and (Dir <> Up) then
NewDir:=Down;
end;

if NumOfRoutes > 2 then // If the enemy has a choice of directions...

begin
NewDir:=None; // The enemy is not ready to go in any direction

LeastMoves:=0; // The ''LeastMoves'' variable is initialized


{Here is the main algorithm, which is used whenever there is a choice of routes available to the enemy}

for CurrentTry:=1 to NumOfTrys do // Attempts to find the player using this Loop

begin

cx:=ex; // The X position of the ''Copy'' is reset to the same as the enemy''s

cy:=ey; // The Y position of the ''Copy'' is reset to the same as the enemy''s

CurrentSquare:=0; // The algorithm has gone over no squares

CurrentMove:=0; // The algorithm has met no multiple routes

StartDir:=None; // There is no starting direction


{A random direction is chosen}

repeat
RandomNum:=Random(4);
if (RandomNum = 0) and (Left = true) then
StartDir:=Left;
if (RandomNum = 1) and (Right = true) then
StartDir:=Right;
if (RandomNum = 2) and (Up = true) then
StartDir:=Up;
if (RandomNum = 3) and (Down = true) then
StartDir:=Down;
until StartDir <> None;
TempDir:=StartDir; // The starting direction is assigned to the tempoary direction


Finished:=false; // The algorithm has not finished


repeat
Inc(CurrentSquare); // Increase the number of squares the algorithm has gone over

if CurrentSquare > 1 then // If this is NOT the first square...

begin // ...choose a direction


{Here, I just copied the code from earlier. But instead of using the variables ''Left'' and stuff, I
used ''Left1''.}


NumOfRoutes:=0; // There are no available routes of the current square

Left1:=false; // Initializes...

Right1:=false // ...these...

Up1:=false; // ...four...

Down1:=false; // ...variables


{if the enemy is not in the far left column, and the square on the left is available...}
if (ex > 1) and (Occ[ex-1][ey] = false) then
begin
Left1:=true; // ...Set ''Left'' to TRUE

Inc(NumOfRoutes); // Increases the number of routes

end;

{if the enemy is not in the far right column, and the square on the right is available...}
if (ey < XPlayArea) and (Occ[ex+1][ey] = false) then
begin
Right1:=true; // ...Set ''Right'' to TRUE

Inc(NumOfRoutes); // Increases the number of routes

end;

{if the enemy is not in the highest row, and the square above is available...}
if (ex > 1) and (Occ[ex][ey-1] = false) then
begin
Up1:=true; // ...Set ''Up'' to TRUE

Inc(NumOfRoutes); // Increases the number of routes

end;

{if the enemy is not in the lowest row, and the square below is available...}
if (ey < YPlayArea) and (Occ[ex][ey+1] = false) then
begin
Down1:=true; // ...Set ''Down'' to TRUE

Inc(NumOfRoutes); // Increases the number of routes

end;

if NumOfRoutes = 1 then // If there is only one route available...

begin
if Left1 = true then TempDir:=Left; // If the Copy can only go left, make it go left

if Right1 = true then TempDir:=Right; // If the Copy can only go right, make it go right

if Up1 = true then TempDir:=Up; // If the Copy can only go up, make it go up

if Down1 = true then TempDir:=Down; // If the Copy can only go down, make it go down

end;

if NumOfRoutes = 2 then
begin
{if the Copy can go left, and didn''t already come from the left, make it go left}
if (Left1 = true) and (PTempDir <> Right) then
TempDir:=Left;

{if the Copy can go right, and didn''t already come from the right, make it go right}
if (Right1 = true) and (PTempDir <> Left) then
TempDir:=Right;

{if the Copy can go up, and didn''t already come from above, make it go up}
if (Up1 = true) and (PTempDir <> Down) then
TempDir:=Up;

{if the Copy can go down, and didn''t already come from below, make it go down}
if (Down1 = true) and (PTempDir <> Up) then
TempDir:=Down;
end;

if NumOfRoutes > 2 then // If the Copy has a choice of directions...

begin
repeat // ...randomly choose a direction

RandomNum:=Random(4);
if (RandomNum = 0) and (Left1 = true) then
TempDir:=Left;
if (RandomNum = 1) and (Right1 = true) then
TempDir:=Right;
if (RandomNum = 2) and (Up1 = true) then
TempDir:=Up;
if (RandomNum = 3) and (Down1 = true) then
TempDir:=Down;
until TempDir <> None;
Inc(CurrentMove); // Increase the number of moves the algorithm has done

if CurrentMove = NumOfMoves then // If the current move = the maximum number of moves...

begin
Finished:=true; // ...then this try has finished...

Succeeded:=false; // ...and failed

end;
end;

{End of copied code}

end;

{Move the Copy of the enemy}
case TempDir of
Left : Dec(ex);
Right : Inc(ex);
Up : Dec(ey);
Down : Inc(ey);
end;

PTempDir:=TempDir; // The tempoary direction is assigned to ''PTempDir''


If (ex = px) and (ey = py) then // If the enemy and the player meet...

begin
Finished:=true; // ...inicate that it is finished...

Succeeded:=true; // ...and that it was successful

end;

until finished;

if (Successful) and (CurrentSquare < LeastMoves) and (LeastMoves > 0) then
begin
LeastMoves:=CurrentSquare;
NewDir:=StartDir;
end;

end; // If ''CurrentTry'' has not met ''NumOfTrys'', execution jumps back.


if NewDir = None then // If the algorithm didn''t find the player...

repeat
RandomNum:=Random(4);
if (RandomNum = 0) and (Left = true) then
NewDir:=Left;
if (RandomNum = 1) and (Right = true) then
NewDir:=Right;
if (RandomNum = 2) and (Up = true) then
NewDir:=Up;
if (RandomNum = 3) and (Down = true) then
NewDir:=Down;
until NewDir <> None;
end;

Dir:=NewDir; // Now that the direction has been found, assign it to the first one


{Move the enemy}
case Dir of
Left : Dec(ex);
Right : Inc(ex);
Up : Dec(ey);
Down : Inc(ey);
end;

if (ex = px) and (ey = py) then // If the enemy and player are both in the same position...

MEET; // ...then they have met


end;

end.



There you go. Easy!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
That algorithm works, but you create a wandering enemy that way. It is possible to make AI that actually hunt you down with much greater accuracy and less of a chance of getting stuck by implimenting an AI Graph.

Basically, this uses locators at key points on the maps (for tiled based games, corners work wonders) that the AI uses to guide itself to the target. This graph can also easily be used to find the shortest path to a target and the AI can quickly change it''s heading as it''s target moves.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I''m finishing up some work on an AI Graph engine to work in a tile based game right now. I wrote it in C++ but it should be portable into VB pretty easily. What I''ve done so far is this:

We have an array of tiles and each one has a value signaling a tile type. Lets say we only have 2 types, type 0 and type 1 where 0 is walkable (I call it soft) and 1 is unwalkable (or hard).

The first part of the AI Graph is the creation of each of the locator nodes. Since paths only start or deviate at corners we''ll put a node at each corner. There are 2 types of corners, and inward corner and an outward corner.

____
|0|0|
----- This is an outward corner where 3 of the 4 tiles are soft
|0|1|
-----

____
|0|1|
-----
|1| |
-----
This is an inward corner, where each adjacent tile is opposite. The blank space is to show that that tile doesn''t matter. If it was a 1, then this block of 4 would only have 1 corner, if it was a 0, then this block would have 2 corners.

Once we place a locator node at each corner we have to link them together. A locator node has a list of a maximum of 4 other nodes (north, south, east, west), an ID (I''ll talk about this soon), and it''s coordinate location. The coordinate would be a standard (x,y) coordinate. I suggest setting up a new type which would be able to calculate the magnitude of a coordinate (the distance from the origin), be able to add coordinates, and be able to subtract coordinates. Subtraction of coordinates is needed for later operations. The ID is needed because we''re adding all the nodes to a Graph (a mesh of points). Because we dont have the ability to organize them into a tree we need a class to manage the nodes. That''s where the ID comes in. It''s helps the class manage the nodes. What I did was create a class devoted to handling this graph and the raw node is nothing more than coordinate data. If you need my linked list file just ask.

To actually make the nodes useful we''ll need to link them. This is a very basic process. Just test to see if there is a clear path between each node. We only test for a clear path if either their X coordinates match or their Y coordinates match so that we only check nodes going straight across from each other. We''ll have to keep record of the closest node with a clear path. We add these node''s to our list of the 4 closest nodes and we''ve finished building the graph.

Next we have to add functions for the AI to use to access the graph. We''ll need a function to find the nearest node from any point (working on the most efficiant way to do this now), and function to find the quickest path to a target from a given node.

The quickest path is actually very easy. What you do is find the closest node from all the nodes in your path so far (starting with the given node, then adding each closest node). For example if you start at (0,3) and you have two choices to add to the path: (0,4) and (3,3) you would add (0,4) to the path because it is closer. Then from (0,4) you have two more choices (4,4) and (0,9) you would choose (3,3) because it is the closest node to one of the nodes in your path since it was still a viable path choice. Once you have a clear path to the target, you remove any extranious path links.

To find the quick distance between two points that are straight across from each other you subtract them and find the new coordinate''s magnitude. For example, the distance between (3,3) and (6,3) would be found by subtracting (3,3) from (6,3) or (6,3) from (3,3). So (3-6,3-3) = (-3,0). The magnitude is the square root of x squared - y squared so the magnitude of (-3,0) = sqr(pow(-3,2) - pow(0,2)) or sqr(9 - 0) or just 3. You can also just use the distance formula which is Distance = sqr(pow((x1-x2),2) - pow((y1-y2),2)).

Now that your AI can navigate the map by just following points to it''s target you can focus on the actual engine it uses once it finds it''s target. I suggest some kind of stray feature which allows the AI to stray away from the graph while attacking, defending, etc. For this, just have the AI check it''s couse by seeing if the tiles infront of it are hard or soft.

This was a very brief explanation. It probably wasn''t the most comprehensable. If you need clarification just ask.

Share this post


Link to post
Share on other sites
Hello again.

I just had a lovely idea. Are you going to include a random play-area generator? I always try and get in a bit of code into all of my games now which creates random worlds, since it gives more variety to the player. You could also add a level creator for the player to cerate their own levels. Now, it may just be me (well it proberly is), but I didn't understand that algorithm much. If you did use targets, though, they would become all but useless in randomly generated mazes, or mazes that the player made themself.

Anyway, good luck.



Edited by - MarkyD on August 13, 2001 1:14:30 PM

Share this post


Link to post
Share on other sites
Hmmm... For small, single-screen levels, I''d take a different approach...

Just send the ''imaginary'' enemy in one direction, and keep storing it''s path... Go forward, and turn left, forward, or right (in this order) (not stepping on your own path) untill a) you find the player or b) can''t go firther. In case of b, go a few steps back to the first new intersection, and head forward or right. Keep doing this until you either a) find the player or b) can''t do a singe new road. In case of b, do a random move.

When your map is really small, you can just store every successfull path in a new array and keep looking, and then choose the ''shortest'' array as your best route.

Simple as hell, wouldn''t really call it an algorithm. Though there is an official name for it...

Share this post


Link to post
Share on other sites
Actually the algorithm would still work perfectly in a randomly generated maze. I assume that the maze would be generated, but then not changed during play right?

If so, you just call a function to load the graph.

I personally would not give somebody the ability to manually create the AI Graph because there is a chance that they could botch it up, however, a small algorithm can create the graph quickly.

The ''target'' I was talking about was nothing more than what the AI was chasing, be it a specific point on the map, a moving object, or something else. It''s just where the AI wants to go. I''ll probably write up a more in depth and understandable tutorial once I finish the last part of the engine.

Invader X
http://www.invadersrealm.com

Share this post


Link to post
Share on other sites
Hello, yet again. If this isn't proof that I have nothing better to do with my time, then I don't know what is.

OK, down to buisness. Firstly, those target things. I've had a think about this, and they could work well, but the problem is: how are they generated? In any random maze, the computer would have to generate them itself. The same goes for any user-created mazes, as the player probably wouldn't understand why the game is suddenly telling them to "Please mark the square near that other one over there, and inbetween these two." You may want them to follow the player, however, and then the algorithm can find the targets OR the player, making it more accurate. You might even want to send some off in the direction that the enemy is moving in. There's an idea.

Next, somebody called my algorithm 'wanderng'. If you want it more accurate, just increase the NumOfTrys or NumOfMoves more. With it set to just 10 how well do you think it will do it's job? You can even use this to adjust difficulty levels. But if you want to examine EVERY possible direction, however, I worked out that you will need 4 x 3 to the power of the Number of Moves-1. That's a lot. Just to do it with Number of Moves set to 4 you end up with 108!

Finally, I think that you should use my algorithm with Invader X's targets. Use 8 targets, say, and place two on the junctions on either side of the enemy, and then place the other 6 on the junctions around them. Then the algorithm has more chance of finding the player.

PS. Could you tell me how big the play-area is, so that I can look into this more?

Edited by - MarkyD on August 14, 2001 7:35:14 AM

Share this post


Link to post
Share on other sites
I think many people misunderstood me. I''ll write up a better explanation and include some pictures for to help out.

Invader X
[link=http://www.invadersrealm.com]Invader''s Realm[/link]

Share this post


Link to post
Share on other sites
There is a similar problem in the AI forum under ''Pathfindng'', incase you''re interested. (It''s rather old, mind)

~ There''s no substitute for failure ~

Share this post


Link to post
Share on other sites
Well, thank you all for your responses related to my problem..Needless to say after a long time of frustration and working hard on coding this enemy AI, I still haven''t gotten anywhere and haven''t a darn clue how to utilize A* or any other matematically intensive algorithm.

I''ve tried different approaches to getting around it, but whatever I try hasn''t worked so far...For now, my enemies wander around the screen like mindless globs of jello looking for something to run into...which isn''t all bad, but it would be nicer if they could go after the player for a while.

I figured out a way to make things work (possibly). I send out a copy of the enemy in the direction its facing at a high speed and if it runs into a wall, it starts over again from the current enemy position. If it runs into the player, the enemy moves towards the player (instead of moving randomly). Now that the enemy has found the player and is out of ''random walk mode'', he is currently in tracking mode. The idea behind this was to take old player x and y locations, and have the enemy go to the next oldx and oldy location, and figure out what direction to travel in, then proceed to the next oldx and oldy location. The idea is that whenever the player presses a different arrow key while the enemy is in tracking mode (thus starts moving in a completely different direction, and isn''t running into a wall) then a new oldx and oldy location is recorded for the enemy to travel to. So basically the player takes his escape route and the enemy follows the escape route for a set amount of time trying to catch up to the player.

It all sounds good, but I can''t do a few things, like getting a direction to record on just a key press...if the key is held down, then the direction change is constant...just small things that really frustrate me...I think my psuedo code is logical enough..but man is this a pain in the butt...I''m using vb6 btw.

Thanks Anyway!
-Gk2k

Share this post


Link to post
Share on other sites
In VB6, to utilize A * for your program you should do something like this:

    
Private Sub DoAStar()
Dim IsLeft As Boolean, IsUp As Boolean, IsX As Boolean
Dim i As Integer, MaxMoves As Integer

MaxMoves = 100 'This is how far the AI will move. Change it to you hearts content

If Enemy.X > Player.X Then
IsLeft = True 'The player is to the left of the enemy
Else
IsLeft = False 'The player is to the right of the enemy
End If

If Enemy.Y > Player.Y Then
IsUp = True 'The player is above the enemy
Else
IsUp = False 'The player is below the enemy
End If

IsX = True 'Will start A * moving horizantally

For i = 0 To MaxMoves
If IsLeft = True And IsX = True Then
If Tile[Enemy.X - i] = Hard Then
IsX = False 'Ran into a wall, will start going vertically now
End If
ElseIf IsLeft = False And IsX = True Then
If Tile[Enemy.X + i] = Hard Then
IsX = False 'Ran into a wall, will start going vertically now
End If
ElseIf IsUp = True And IsX = False Then
If Tile[Enemy.Y - i] = Hard Then
IsX = True 'Ran into a wall, will start going horizantally now
End If
ElseIf IsUp = False And IsX = False Then
If Tile[Enemy.Y + i] = Hard Then
IsX = True 'Ran into a wall, will start going horizantally now
End If
End If
Loop

End Sub


That is very basic. Enemy.X, Enemy.Y, Player.X, and Player.Y are in tile coordinates NOT twips or pixels. This assumes that your map is saved in an array of tiles (I named it Tiles). The array could be defined as an array of boolean values where Hard is defined at true or false or whatever you want.

You may want to save each movement in another array that your AI will use. So after each IsX = Whatever you may want to add

AIMoves[ i ] = Up, or Down, or, whatever the way it is moving. I would define the moves as an Enum and only define Up, Down, Left, Right. That way, when your AI is called it will find the next move and go that way. Then it would remove that move from the list or hold in a variable what move it is on in the list.

That should make for a decent AI.

Edited by - Invader X on August 16, 2001 6:42:05 PM

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Alright, thanks for the code...funny that it''s somewhat similar to what I originally started to do when I first did my AI routines, however there are a few differences..My scalemode has been set to pixels. I do hold my map in an array (to be exact, MAP(1 to 24, 1 to 20) and so it should be easy. The only things I don''t know how to do are saving different paths on another array or list and calling them. But I''ll give this much a shot and see if I can come up with something.

Thanks,
-Gk2k

Share this post


Link to post
Share on other sites