Self-Playing Asteroids


Asteroids Screen View


The following demo self-plays an Asteroids game created by another programmer. It's probably my final experiment where domain level information is provided for code to play against a 2D game. Next I plan to pursue a project where the code is self-directed. Basically taking raw pixel data or the raw sensory stream data of things to classify or recognise and act upon.


The code is a basic reactive agent which runs against the Asteroids game. Its purpose is to play the game better. It cannot function beyond the task it was designed for and would be considered a low level Type I AI.


The Reactive Agent loops through an array-like object of the asteroids and calculates the distance between the ship and each asteroid. Then it calculates the ship angle and shoots at the asteroid in focus. It will temporarily protect the ship if it detects an asteroid approaching too close, creating a force field that flashes bright red on impact as the asteroid is destroyed.


Try the demo ( For best results let it run 3-4 minutes ) >>   Self-Playing Asteroids Demo



Playable Canvas Asteroids Game

The game source is implemented in HTML5/JavaScript by Jeff Ibacache. To download the source code or play the actual game go here: Playable Canvas Asteroids .



Project File


index.js


Reactive Agent Code

The following modifications were added to the original game code to implement the Reactive Agent.


First, add a call to the detectAsteroids function which controls the ship.

 
detectAsteroids(); 

Next iterate repeatedly through the array-like object of asteroids and calculate the distance between the ship and each asteroid.

 var shipx;
 var shipy;
 var recalcrads;
 
function detectAsteroids()   
{
var i = asteroids.length - 1; 

for(i; i > -1; --i)
	{
var a = asteroids[i];	 
var astx = a.pos._x;
var asty = a.pos._y;
shipx = ship.pos._x;
shipy = ship.pos._y;
var mdx = astx - shipx;
var mdy = asty - shipy;

Temporarily protect the ship if it detects an asteroid approaching too close. The force field flashes bright red when it sustains an asteroid impact.

var vec = Vec2D.create(mdx, mdy);
var trackdistance = vec.getLength(); 
if (trackdistance < 70 )  
{
//Display force field on impact
context.beginPath();  
context.strokeStyle = "Red";
context.lineWidth = 10;
context.arc(shipx, shipy, 70, 0, 2 * Math.PI, true);
context.stroke();

destroyAsteroid(a);
}

Calculate the angle and rotate ship then shoot the current asteroid object.

var radians = Math.atan2(mdy, mdx);
var degrees = radians * (180 / Math.PI);
if (degrees < 0 ) {
degrees = degrees + 360;
}

Convert radians to degrees then convert to 0-359 eliminating negatives, then convert back to radians.

Next rotate the ship and shoot at the asteroid

recalcrads = degrees * (Math.PI / 180);   
ship.angle = recalcrads;
ship.shoot(); 

Draw a line connecting the ship to each asteroid just to help visualize what is happening.

context.beginPath();
context.strokeStyle = "#2E4053"; //"#283747" //"DarkSlateGray";
context.lineWidth = 1;
context.moveTo(shipx,shipy);
context.lineTo(astx,asty);
context.stroke();
context.closePath();

  }   // END FOR	
}	  // END detectAsteroids()