Assignment 2: Robotanks


Screen Shot 2014-01-28 at 4.42.03 PM.png



Information

This assignment is to write a decision tree implementation to control a tank which will battle another tank controlled by a decision tree written by another student.

Tank Controls


Your decision tree is passed a value store with the following keys and values:
  • MyPositionX - Your tank's X coordinate on screen as a float
  • MyPositionY - Your tank's Y coordinate on screen as a float
  • MyRotation - Your tank's rotation around the Z axis in degrees as a float
    (Note: 0 degrees is facing right like the blue
    tank above.)
  • MyPower - Your tank's current power as a float
  • MyVelocity - Your tank's current velocity as a Vector2 (use Vector2.magnitude to get the velocity "forward").
  • MyAngularVelocity - Your tank's current rotational velocity as a float
  • HisPositionX - The other tank's X coordinate on screen as a float
  • HisPositionY - The other tank's Y coordinate on screen as a float
  • HisRotation - The other tank's rotation around the Z axis in degrees as a float
    (Note: 0 degrees is facing right like the blue tank above.)
  • HisPower - The other tank's current power as a float
  • HisVelocity - The other tank's current velocity as a Vector2 (use Vector2.magnitude to get the velocity "forward").
  • HisAngularVelocity - The other tank's current rotational velocity as a float
  • TankControls - Your interface to your tank as an object of class TankControls.
    You control your tank by calling the methods on this object

    Note: Velocity is given to you in pixels per second, whereas when you set velocity you do it as a normalized 0 - 1.0 value. I did this because I assumed the actual movement speed would be more useful for AI purposes. Angular velocity is in degrees per second.


The TankControls object defines the following methods:


code format=csharp


<summary>
/ /Sets the foward veocity of the tank.
Valid values are 0 for stop to 1.0 for full throttle
/ /Values beyond this will be clamped
</summary>
/ /<param name="speed">0 to 1.0.</param>
public void SetSpeed(float speed);

<summary>
Sets the rotational vecolity of the tank
Valid valuse are -1.0 for full speed counetr clockwise to
/ /to 1.0 for full speed clockwise
Values beyond this will be clamped
</summary>
<param name="rotationalSpeed">-1.0 to 1.0.</param>
public void SetRotation(float rotationalSpeed);

<summary>
Shots the gun
</summary>
public void Fire();
<summary>
The gun takes time to reload after firing.
This tells you that the gun is reloaded and ready to fire
</summary>
<returns><c>true</c> if this instance can fire; otherwise, <c>false</c>.</returns>
public bool CanFire();


<summary>
Returns the maxmimum linear velocity of the tank
/ /</summary>
<returns>The speed.</returns>
public float MaxSpeed();

<summary>
Returns the maximum positive rotational velocity of the tank
/ /</summary>
<returns>The rotation.</returns>
public float MaxRotation();
/ /<summary>
Casts a ray at the absolute angle give from the tank's position.
If the ray hits an obstacle (not a tank) or a wall it returns the hit
location as a Vector2 otherwise it returns null.
</summary>
<returns>The hit location or null if no object hit.</returns>
<param name="angle">Angle.</param>
public Vector2? CastRay(float angle);


<summary>
/ /Casts a ray at the absolute angle give from the tank's position.
If the ray hits an obstacle (not a tank or a wall) it returns the hit
location as a Vector2 otherwise it returns null.
</summary>
<returns>The hit location or null if no object hit.</returns>
/// <param name="angle">Angle.</param>
public Vector2? CastRayIgnoreWall(float angle)



code


Power Consumption


Each tank has a power reserve that starts at 500. The first tank to go to 0 or negative power loses. Power is consumed in the following ways:
  • Linear Movement: Linear Movement costs 1 power point per second for maximum velocity movement (1.0) Fractional speeds cost the fraction of 1 point equal to the fraction of total movement. For instance, a speed of 0.5 costs 0.5 points per second
  • Rotational Movement: Rotational movement costs 1 power point per second for maximum rotational velocity. Fractional rotation speeds cost a fractional amount per second like Linear Movement.
  • Shooting your gun: Shooting you gun costs 5 power points per shot
  • Getting hit by a bullet: Getting hit by a bullet costs 50 power points per bullet hit

Developing your AI


Readying your development environment


First download Unity3D 4.3 or later. You may use the PC, OSX or Linux versions.
If you do not have it you can get it here:
Unity3D Download

After you install Unity you will need to make an account. If you like you can then select the 30 day pro trial or the free Community version. Everything we do in class you will be able to do with the free version.

Note that if you try Pro you will be have to be careful not to use pro features in personal projects you wish to save unless you intend to buy a license. If you would like a 1 year academic student license to Unity Pro, you can get that for about $150 here:
Unity Store at Studica.com

Once you have Unity installed, you will need the Robotanks project. Download it from the link below:

After you have it downloaded the project, unzip it someplace safe and then start Unity. After the initial welcome and licensing screen you should see a chooser that looks like this:

Screen Shot 2014-01-28 at 5.21.57 PM.png

Make sure you have the Open Project tab selected at the top.

Click Open Other... and you should see a dialog that looks something like this:

Screen Shot 2014-01-28 at 5.23.55 PM.png

Navigate to where you unzipped the Robotanks folder. Select it and click Open and after a bit of loading you should see this:
(Note that the dark theme of the windows is pro mode, your will probably be lighter grey.)

Screen Shot 2014-01-28 at 5.25.59 PM.png

If you do not see the game board then you do not have the scene open yet. In that case, select Two tank scene in the Project pane on the bottom left of the screen and you should see the proper scene object in the Assets window like this:

Screen Shot 2014-01-28 at 5.27.37 PM.png

Double click the Scene icon in this folder and you should now see the play field.

You can press the play icon at the top of the Unity window and watch the default Ai play (it isn't very good).

Writing your decision tree


Now that you are in the project, navigate to the Tank Brains folder in the Project Pane and you should see the sample script and prefab both called SimpleTankBrain.

Screen Shot 2014-01-28 at 5.33.12 PM.png


Screen Shot 2014-01-28 at 5.34.53 PM.png



The prefab is simply a GameObject that has the SimpleTankBrain as its only component.
You will make a similar prefab to hold your own tank brain.

Start by creating a new C# script and give it your own name. Then copy SimpleTankBrain.cs into your script and rename the class name to your class. Change the GetPlayerName() function to return your name. Then modify the GetTreeRoot() method to return your own decision tree, using the existing code as an example.






Testing your decision tree


In order to test your decision tree you must make a prefab of your own like the prefab for the sample. Please refer to the Unity documents or ask a classmate if you have any questions on how to make a prefab.

One you have a prefab, you will deploy your tank brain by replacing one of the existing brain prefabs in the Tilemap.
If you click on the Tilemap in the Hirearchy window on the left hand side of the Unity screen, the components of the Tilemap will be displayed in the inspector on the right like this:

Screen Shot 2014-01-28 at 5.42.25 PM.png

Notice that the last component in the list is called Tank Game(Script). It has an exposed property called brains that is an array to prefabs that have TankBrain components. It is set for 2 entires. Leave it at 2 but replace one of the slots with your prefab by either

A) Dragging and dropping your prefab from the Assets window onto that slot
OR
B) Clicking the little circle to the right of the slot, selecting the Assets tab from the chooser that pops up, and selecting your prefab.

IF it will not let you drop your prefab into the slot, or your prefab doesn't show up in the Assets tab of the choser, it means your prefab does not have a component that is a sub class of TankBrain. Double check your code to make sure your brain is a subclass of TankBrain , and check your prefab to make sure your component is included in the prefab.

Now run the game and one tank should be replaced in name and action by your brain.

Turning in your tank brain

Important: Please make sure you have named your script and prefab something unique. I recommend including your name.



Create a package from your prefab by right clicking it and choosing "Export Package..."

Screen Shot 2014-02-01 at 2.24.43 PM.png


That will show the export screen. By default, all dependancies are included. Thats fine, so just click the "Export" button.

Screen Shot 2014-02-01 at 2.25.39 PM.png

Name your package as per the hand in naming scheme, this is assignment 2. (e.g."IMGD4100_jkesselman_2"). Zip the package up to reduce its size and upload it to the Robotanks assignment in Turnin.


A note on cheating:

Unity does not have a way to sandbox components. Any component has access to the whole system. You are on your honor to ONLY use the information in the valuestore that is passed to you.

If you find you would like additional information that is not in the value store, and its not a huge amount of work, let me know and I can add it.