ARTIFICIAL INTELLIGENCE CODING

There will come a time in every coder's life when they will need to code some Artificial Intelligence. Enemies need to do more than walk back and forth on a path and shoot on a timer. In a pong game, you will want your opponent to follow the ball, but not always be able to hit it. So how do you achieve this? The following is a few examples. Please note, that by no means are these the only way to code each particular type. In fact, there's barely ever only one way to do anything.

I've added a description under each event or group of events that explains what it's for. That way, you're not just copying the events, you can also understand how they work and why. Once you have a good understanding of the events, you can alter them to your liking.

Simply scroll down until you find the bold heading you're looking for. If it's not there, email me or DC mail me and I'll try to come up with something for you. Alternatively, copy this whole article and paste it into a notepad or word document for future reference.

NB. An X instead of an o an the start of a condition/event indicates a 'negate' line.

Pong Opponent

This covers:
- Moving to intercept the ball
- Priority of interception (when there's more than one object to stop, which one the CPU goes for)
- Firing a laser with possibility of inaccuracy

You will need:
- The CPU's paddle (set the hot spot to the center)
- The Player's paddle (again, set the hot spot to the center)
- The ball (set the hot spot to the center)
- A detector about 3x3 pixels big (set the hot spot to the center)
- A laser for the player, and a laser for the CPU (for the inaccuracy and interception priority scripts)
- An object for the player to protect, placed behind his paddle (for the inaccuracy script)

The method:
To start with, you will want to place everything down. In this example, the CPU will be up the top, and the player will be down the bottom. They will be moving left and right. If your paddles are on the left and right sides instead, just replace all the Y's and X's in the instructions with their opposite (ie. change X's to Y's and visa versa), and make sure to adjust the 'greater than' and 'less than' lines based on where your computer opponent is.

* Please note, obvious events like making the ball bounce when it hits a paddle or the side of the screen are not included. Nor is a scoring system or the player's events.

Alright, once you've got everything down, you want to make the computer able to move. That's where its detector comes in. Make the following event:

Conditions
o - Start Of Level
Events
o - Set position of Detector to (0,0) of CPU Paddle
o - Make Detector invisible

This event will make sure that the detector is in the right spot, so your opponent doesn't do all wierd things like move downwards to catch the ball. Also, it hides the detector so it looks like the CPU is moving of its own accord.

Conditions
o - Always
Events
o - Set X position of Detector to X position of Ball

This will make the detector follow the ball left and right.

Conditions
X - CPU Paddle is overlapping Detector
Events
o - Set speed of CPU Paddle to <Slower than Ball, but not too much. About 10 or 15 units slower>

If the speed of the CPU Paddle is greater than the ball's, then the CPU will probably be too fast to beat. You want the CPU to be able to miss. A good way of making sure this can happen is to make the ball's speed gradually increase over time, say add 1 to speed every 1-5 seconds or so.

Conditions
o - CPU Paddle is overlapping Detector
Events
o - Set speed of CPU Paddle to 0

This makes the CPU stop when it's in the right spot to hit the ball.

There you have it. The CPU Paddle will now move to intercept the ball. Notice how when the ball is near the edge, the computer's paddle will leave the screen partly? The Player's paddle will more than likely not be allowed to do this, so you will want to stop the CPU's also. That's when we add the next event.

Conditions
o - X position of CPU Paddle is less or equal to <half of paddle's pixel length>
Events
o - Set speed of CPU Paddle to 0

Conditions
o - X position of CPU Paddle is greater or equal to <X in screen size - half of paddle's pixel length> (For example, 640x480 resolutions would use 640 - half of paddle's pixel length)
Events
o - Set speed of CPU Paddle to 0

This will make the computer stop when it reaches the edges of the screen.

To add some spice to the mix, instead of just protecting your side of the screen, you have an object behind to you protect (eg. a crystal or a block), and both players are able to fire lasers at the object in an attempt to destroy it. I will leave out the player firing laser event because it's obvious how you can make it. Also, in this game the lasers will be destroyed when they hit an opponent's paddle, so I won't add that event. Make sure that you have two laser objects, one that the player fires, and one that the computer fires. If you don't have seperate laser objects for each paddle then they will probably destroy it as soon as it's fired.

Before you start, remove the following event that you added earlier:

Conditions
o - Always
Events
o - Set X position of Detector to X position of Ball

This is because you don't want the computer to always just follow the ball, or you can hit whatever he's protecting with a laser while he's busy with the ball.

Conditions
o - Number of Player Laser is greater than 0
o - Y position of Player Laser is less or equal to Y position of Ball
o - Y position of Player Laser is greater than Y position of CPU Paddle
Events
o - Set X position of Detector to X position of Player Laser

This makes the CPU Paddle move to intercept the laser if it's closer to him than the ball, and the laser is not behind him.

Conditions
o - Number of Player Laser is greater than 0
o - Y position of Ball is less or equal to Y position of Player Laser
o - Y position of Ball is greater than Y position of CPU Paddle
Events
o - Set X position of Detector to X position of Ball

This is the opposite to the last event, making the CPU go for the ball when the ball's closer.

Conditions
o - Number of Player Laser is greater than 0
o - Y position of Player Laser is greater or equal to Y position of Ball
o - Y position of Ball is less than Y position of CPU Paddle
Events
o - Set X position of Detector to X position of Player Laser

This event means that if the ball is behind the paddle, then the CPU will go for the laser.

Conditions
o - Number of Player Laser is greater than 0
o - Y position of Ball is greater or equal to Y position of Player Laser
o - Y position of Player Laser is less than Y position of CPU Paddle
Events
o - Set X position of Detector to X position of Ball

The opposite of the last event. The CPU will go for the ball if the laser is behind him (He can't get the laser if it's behind him).

Conditions
o - Number of Player Laser equals 0
o - Y position of Ball is greater than Y position of CPU Paddle
Events
o - Set X position of Detector to X position of Ball

This means that when there's no laser fired from the player, the CPU will go for the ball (as long as it's not behind him).

That's all the events needed to make the CPU get both the ball and the laser. But what happens when you want the computer to fire back? You don't want him to have deadly accuracy (unless it's on hard mode). Let's say that you want him to be able to miss, like any real opponent. To do this, add the following events:

Conditions
o - Internal flag 0 of CPU Paddle is OFF
o - Internal flag 1 of CPU Paddle is OFF
Events
o - Set alterable value A of CPU Paddle to random(200)

Conditions
o - Internal flag 0 of CPU Paddle is ON
Events
o - Add 1 to alterable value B of CPU Paddle

These events determine the firing rate of the CPU. To make the CPU attack more likely, decrease the random number in the first event. To make it less likely, increase it.

Conditions
o - Alterable value A of CPU Paddle equals 1
Events
o - Set alterable value A of CPU Paddle to 0
o - Set Internal flag 1 of CPU Paddle to ON
o - Set X position of Detector to ((X position of Player Protected Object+ random(40)) - 20)

For greater miss variation, increase the random number. Make sure the underlined number is half of the random one.

Conditions
o - Internal flag 1 of CPU Paddle is ON
o - CPU Paddle is overlapping Detector
Events
o - Set internal flag 1 of CPU Paddle to OFF
o - Set internal flag 0 of CPU Paddle to ON
o - Have CPU Paddle fire CPU Laser down at speed of <your choice>

When all firing rate requirements are met and the CPU has 'aimed', it will fire.

Conditions
o - Alterable value B of CPU Paddle equals 200
Events
o - Set alterable value B of CPU Paddle to 0
o - Set internal flag 0 of CPU Paddle to OFF

Determines the minimum time the CPU can wait before it fires another shot. Increase the 200 for a longer wait, and decrease it for a shorter one.

There it is. The CPU will now move to stop your lasers and the ball, and will also fire at your protected object, with a possibility of poor aiming.

- This concludes the Pong Opponent section -

Platformer Enemy

This covers:
- Movement variation
- Avoiding attacks
- Multiple weapons

You will need:
- Your platform engine so the player can move and test events (download one from DC if you can't make them yourself)
- An enemy (with stopped, walking and ducking animations)
- A player bullet
- An enemy bullet
- An enemy grenade
- A 'sight detector' object for your enemy (a circle of about 5x5 pixels big)
- A 'left marker' and a 'right marker' (used to lay out the enemy's movement boundary)

The method:
This section assumes that you've got your platform engine sorted out, and the player can move, walk on platforms, etc. Make sure the enemy is standing on a platform, and place him so his feet are standing on the platform. Place the 'left marker' so that its right edge is on the left edge of the plaftorm. Do the opposite with the 'right marker'. In this section, the enemy does not have gravity and instead has a 'bouncing ball' movement. Set his initial direction to either directly left or right. You will want the enemy's platform to be at least long enough for him to take about 3-5 seconds to travel the whole platform. Start with the following:

Conditions
o - Enemy collides with Left Marker
Events
o - Set direction of Enemy to RIGHT

Conditions
o - Enemy collides with Right Marker
Events
o - Set direction of Enemy to LEFT

This will make the left and right markers the boundary for your enemy's movement. When he touches one, he goes the other way. With this you can use the same enemy multiple times in the level, but they can each patrol a different sized area.

Conditions
o - Every 00'20
Events
o - Have Enemy shoot Sight Detector at speed 50 (in his current direction)

Conditions
o - Number of Sight Detector is greater than 0
Events
o - Add 1 to alterable value A of Sight Detector

Conditions
o - Alterable value A of Sight Detector equals 10
Events
o - Destroy Sight Detector

The events above will make the enemy look ahead of him, up to a certain range. To increase his visual range, increase the alterable value A number in the third event. Inversely, decrease it to make the visual range shorter.

Conditions
o - Sight Detector collides with Player
o - Internal flag 0 of Enemy is OFF
Events
o - Set internal flag 0 of Enemy to ON

The enemy's internal flag 0 will be his awareness. If he is aware of your presence, it will be ON. If not, it will be OFF.

Conditions
o - Sight Detector collides with Player
o - Internal flag 0 of Enemy is ON
Events
o - Set alterable value A of Enemy to 0

Conditions
o - Internal flag 0 of Enemy is ON
Events
o - Add 1 to alterable value A of Enemy

Conditions
o - Alterable value A of Enemy equals 20
Events
o - Set alterable value A of Enemy to 0
o - Set internal flag 0 of Enemy to OFF

The above events make the enemy's awareness disappear if he hasn't seen you for a while. To make this 'while' longer, increase the 20 in the third event. To make it shorter, decrease it.

Conditions
o - Internal flag 0 of Enemy is ON
Events
o - Set speed of Enemy to 0

Conditions
o - Internal flag 0 of Enemy is OFF
Events
o - Set speed of Enemy to <your choice - whatever speed you want the enemy to walk at>

This makes the enemy stop when he is aware of your presence. When he is not, he will simply walk

Try your level out now. You will notice that if you jump in front of the enemy, he will stop. If you get out of his way, he will continue walking once his awareness period is up. Now we will make him shoot at you. The bullet's collision events will not be covered, nor will the player's lives/health. You can do these yourself.

Conditions
o - Internal flag 0 of Enemy is ON
o - Alterable value B of Enemy equals 0
Events
o - Set alterable value B of Enemy to 20
o - Have Enemy shoot Enemy Bullet at speed <whatever's appropriate for your game>

Conditions
o - Alterable value B of Enemy is greater than 0
Events
o - Subtract 1 from alterable value B of Enemy

The enemy will shoot you when he sees you. Also, he has a firing rate of 20. To make his firing rate slower, increase the 20 in the first event. To make it faster, decrease it. You will probably want to add a sound effect for his weapon.

Now if you test the level out, you will notice that the enemy will continually shoot at you when he knows you're there. What if we want him to toss a grenade every so often? I will not cover the grenade trajectory events, or the grenade's explode events.

Conditions
o - Internal flag 0 of Enemy is ON
o - Alterable value C of Enemy equals 0
Events
o - Set alterable value C of Enemy to 40

Conditions
o - Alterable value C of Enemy is greater than 0
Events
o - Subtract 1 from alterable value C of Enemy

Conditions
o - Internal flag 0 of Enemy is ON
o - Alterable value C of Enemy equals 1
Events
o - Set alterable value C of Enemy to 0
o - Create Grenade from Enemy at (0,0) (If you can't program trajectory, simply have him shoot it. This will, however, look very gay. You don't throw a grenade in a perfectly straight line forwards)

Conditions
o - Internal flag 0 of Enemy is OFF
Events
o - Set alterable value C of Enemy to 0

The first three events determine the actual throwing of the grenade and the rate of fire for throwing. To make the rate of fire slower, increase the 40 in the first event. To make it faster, decrease it. The final event cancels the grenade throwing process when the enemy loses awareness of your presence. As stated before, you will need to make your own event for the grenade exploding, or if it's on a timer, etc.

Now when you test your level, you will notice that not only does the enemy move around, see you and shoot at you, but he will occasionally toss a grenade. You don't have to have a grenade, obviously... it was just an example. You could have the enemy activate a shield or place a land mine in place of the other event.

The last part of this section will discuss making the enemy avoid your attacks. Obviously, you won't want him to duck every attack you make. The following events show how to make him duck attacks only if he is facing you.

Conditions
o - Internal flag 0 of Enemy is ON
o - Number of Player Bullet is greater than 0
Events
o - Change animation of Enemy to CROUCHING
o - Set internal flag 2 of Enemy to ON

Conditions
o - Number of Player Bullet equals 0
o - Internal flag 2 of Enemy is ON
Events
o - Restore animation sequence for Enemy
o - Set internal flag 2 of Enemy to OFF

(You will need to make sure the crouching animation is low enough for him to avoid your bullet. Adjustments will probably be required, unless the enemy is a blob and can duck into a pixel-high form)

The enemy will duck attacks that come at him when he is aware of your presence. However, you may want him to be unable to fire while in the crouched state. If this is the case, simply edit the shooting events you made for the enemy and add the line 'Internal flag 2 of Enemy is OFF' to the conditions.

If you would like to have the enemy duck only occasionally, instead of every time he's facing you, have the following events instead of the above two:

Conditions
o - Internal flag 0 of Enemy is ON
o - Number of Player Bullet is greater than 0
Events
o - Set alterable value A of Player Bullet to random(5)+1

Conditions
o - Alterable value A of Player Bullet equals 1
o - Number of Player Bullet is greater than 0
Events
o - Change animation of Enemy to CROUCHING
o - Set internal flag 2 of Enemy to ON

Conditions
o - Number of Player Bullet equals 0
o - Internal flag 2 of Enemy is ON
Events
o - Restore animation sequence for Enemy
o - Set internal flag 2 of Enemy to OFF

These events will give the enemy a 1 in 5 chance of ducking a bullet. If you want to change this, like a 1 in 10 chance, for example, change the 5 in the first event into the number you want, eg. random(10)+1 will make it a 1 in 10 chance.

- This concludes the Platformer Enemy section -

Top Down Opponents

This covers:
- Enemy detection and pursuit
- Enemy loss of interest

You will need:
- The player's character (set the hot spot in the center)
- An enemy (set the hot spot in the center)
- Several (invisible) active objects for pathfinding purposes (explained later)

The method:
This is an easy one. All you have to do is place the player and the enemy on screen. Give your player character 8-directional movement (or make your own) and give the enemy a bouncing ball movement. You will want to add your own events to make the enemy do more than bounce around like a pinball. Then, do the following:

Conditions
o - Pick one of Enemy
o - Y position of Player is greater or equal to Y position of Enemy - 80
o - Y position of Player is less or equal to Y position of Enemy + 80
o - X position of Player is greater or equal to X position of Enemy - 80
o - X position of Player is less or equal to X position of Enemy + 80
Events
o - Set internal flag 0 of Enemy to ON
o - Set alterable value A of Enemy to 0

Conditions
o - Internal flag 0 of Enemy is ON
Events
o - Have Enemy look at (0,0) relative to Player
o - Add 1 to alterable value A of Enemy
o - Set speed of Enemy to <higher than normal> (optional)

Conditions
o - Alterable value A of Enemy equals 30
Events
o - Set alterable value A of Enemy to 0
o - Set internal flag 0 of Enemy to OFF

Conditions
o - Internal flag 0 of Enemy is OFF
Events
o - Have Enemy look in random direction (have an arrow on all of them)
o - Set speed of Enemy to <normal> (if you included the optional event)

The first event determines the enemy's viewing radius. In fact, radius is the wrong word, because it is a square in actuality. To get a circle, you'll need to dabble in the advanced mathematics function. Alternatively, if you have only one enemy, or all enemies are seperate objects, you can have a circular active object follow them and have a collision event instead of dimensions. The bottom three events will make the enemy lose interest if he can't see you in a short while. To make this period longer, increase the 30 in the third event. To make it shorter, decrease it.

UPDATE: Don't forget to include the 'Pick One Of' event, otherwise the game will assume that the Enemy in question is the first one you placed on the playing field. Special thanks to mikefarktard@hotmail.com for helping me find this.


- This concludes the Top Down Opponent section -

You've now got a basic understanding of Artificial Intelligence programming, for the most basic of game types. In future I may make a more advanced one, based on demand.

I hope this has helped at least one person!

- Rick