Last Good Quote: Son's are the seasoning on our lives. - Someone on Facebook

Friday, January 29

A Test in AI

I've been doing a lot of reading up on AI and I got to thinking...

Question: Is it possible to "grow" code that acts in an intelligent fashion?

So, I thought I'd walk a little test and see "what happens". However I have a "goal" that at some point watching these bots interact together should be 'interesting'.

I started with a map, a bot and a set of actions that the bot can perform.

Map:
  • 20 x 20 square
  • Going off one side of the map brings the bot to the other side of the map. (much like pacman)
Available Actions:
  • Move Up one square
  • Move Down
  • Move Left
  • Move Right
  • Look Left returns true if another bot is to the immediate left
  • Look Right
  • Look Up
  • Look Down
  • If(a, b, c)

  • a, b c - can be replaced by any other action except if
  • if a is true then b will be performed
  • if a is not true then c will be performed
  • Fight - Kills any bot within one square
  • Breed - See below
An example bot:

(This bot moves in a circle attempts to fight, then breed then it runs south)
0: Move("E")
1: Move("N")
2: Move("S")
3: Move("W")
4: Fight()
5: Breed()
6: Move("S")
7: Move("S")
8: Move("S")
9: Move("S")


How they Grow
Populate the map with 20 bots. Each of them selects 10 random actions from the list above. They then perform the actions in sequence. We are looking for some type of intelligent behavior from these bots.

Breeding
Breeding is the key to the bots learning something. Any time a bot attempts to breed the following sequence takes place:
  1. Look for another bot within 1 square
  2. 5 times, take a random code from this bot and replace it with a random code from the other bot.
  3. Find a bot that is dead and has a lower score than either parent bot.
  4. Give the new code to this bot.

The primary bot, sometimes called father, is the bot that started looking to breed. (Hey, I'm a dude what can I say.)

The secondary bot, sometimes called the mother, is the bot that was found close by. (Sorry ladies)

Gross huh? or Cool, depends on how you look at it.

The other form of breeding could take place after the bot is dead for a given number of turns. When this is the case, the bots code is randomly mixed with random code and the bot is set alive again.


Scoring

So, I needed a way to identify "good" behavior. I'm still on the fence if I can call it intelligent behavior. Either way, this is how I scored each bot.
  • +1 for Killing another bot (Survival of the fittest)
  • +1 for Breeding (father)
  • +1 for Help Breeding (mother)
  • +.25 for each tick that the bot stayed alive
Keep in mind that during breeding a bot can only breed if there is a dead bot of a lesser score on the board. This keeps a "dumb" breeder from taking over the board.

Other Notes

Age - Keeps track of the number of times the bot's code was "messed with"

Kids - Number of successful breeding attempts

Parents - The last two parent bots of the current bot.

Bots will block each others path, unless dead.

When a bot is re-spawn or the child of another bot, they are respawned at a random location on the map.

What's happening?
OK, so I ran the simulation with the following parameters:
  • 1,000 iterations (steps)
  • 20 Bots
  • Respawn after 20 seconds
  • +1 for Killing another bot (Survival of the fittest)
  • +1 for Breeding (father)
  • +1 for Help Breeding (mother)
  • +.25 for each tick that the bot stayed alive
These were the top 3:

Bot 12: 5 iterations, 18 kills, 1 kid, score: 248

This bot tried to fight, breed then moved east a little and tried over
  • 0: fight([BOT_ID])
  • 1: look('S', [BOT_ID])
  • 2: fight([BOT_ID])
  • 3: look('S', [BOT_ID])
  • 4: fight([BOT_ID])
  • 5: look('S', [BOT_ID])
  • 6: findMate([BOT_ID])
  • 7: move('E', [BOT_ID])
  • 8: move('E', [BOT_ID])
  • 9: fight([BOT_ID])
Bot 19: 2 iterations, 10 kills, 4 kids, score: 260
This bot moved diagonal across the board mating and fighting as it went. Died a lot while I was watching.
  • 0: look('E', [BOT_ID])
  • 1: fight([BOT_ID])
  • 2: move('N', [BOT_ID])
  • 3: findMate([BOT_ID])
  • 4: move('W', [BOT_ID])
  • 5: look('S', [BOT_ID])
  • 6: look('N', [BOT_ID])
  • 7: fight([BOT_ID])
  • 8: move('W', [BOT_ID])
  • 9: look('N', [BOT_ID])
Note: During this round the bot with the most code changes (13) had the following line of code:
5: ifOnly(look('S', [BOT_ID]),"move('S', [BOT_ID])","move('W', [BOT_ID])", [BOT_ID])
6: fight([BOT_ID])

Intelligence? He looks south if he sees something he moves south and then attacks. Otherwise he moves west.
Bot 12: 5 iterations, 13 kills, 1 kid, score: 230Very similar to the first test. This bot tried to fight, breed then moved east a little and tried over
  • 0: fight([BOT_ID])
  • 1: findMate([BOT_ID])
  • 2: look('S', [BOT_ID])
  • 3: look('S', [BOT_ID])
  • 4: look('S', [BOT_ID])
  • 5: look('N', [BOT_ID])
  • 6: findMate([BOT_ID])
  • 7: look('N', [BOT_ID])
  • 8: move('E', [BOT_ID])
  • 9: findMate([BOT_ID])
Bot 15: 4 iterations, 13 kills, 1 kid, score: 249
Moved a little differently, but overall moved east...a pattern might be emerging.
  • 0: ifOnly(look('E', [BOT_ID]),"findMate([BOT_ID])","look('E', [BOT_ID])", [BOT_ID])
  • 1: move('E', [BOT_ID])
  • 2: fight([BOT_ID])
  • 5: fight([BOT_ID])
  • 6: move('W', [BOT_ID])
  • 7: move('E', [BOT_ID])
Bot 7: 4 iterations, 27kills, 0 kid, score: 262
Very efficent use of code, notice how he spawned to kids to compete with him. Thus giving him the high score.

  • 0: fight([BOT_ID])
  • 1: move('N', [BOT_ID])
  • 2: move('S', [BOT_ID])
  • 3: findMate([BOT_ID])
  • 4: ifOnly(move('S', [BOT_ID]),"fight([BOT_ID])","fight([BOT_ID])", [BOT_ID])
  • 5: ifOnly(move('S', [BOT_ID]),"move('E', [BOT_ID])","look('N', [BOT_ID])", [BOT_ID])
  • 6: move('N', [BOT_ID])
  • 7: fight([BOT_ID])
  • 8: look('N', [BOT_ID])
  • 9: move('W', [BOT_ID])

0 comments:

Post a Comment

Followers