Difference between revisions of "Robocode/Graphical Debugging"

From Robowiki
Jump to navigation Jump to search
m
Line 28: Line 28:
 
   import java.awt.Color;
 
   import java.awt.Color;
 
   import java.awt.Graphics2D;
 
   import java.awt.Graphics2D;
 
+
 
 
   public void onPaint(Graphics2D g) {
 
   public void onPaint(Graphics2D g) {
 
       // Set the paint color to red
 
       // Set the paint color to red
Line 44: Line 44:
 
=== run() method ===
 
=== run() method ===
 
So first of all, we tell our robot to do nothing else than turning the robot for ever when it is run:
 
So first of all, we tell our robot to do nothing else than turning the robot for ever when it is run:
<pre>
+
 
 
   // How to run our robot
 
   // How to run our robot
 
   public void run() {
 
   public void run() {
Line 52: Line 52:
 
       }
 
       }
 
   }
 
   }
</pre>
 
  
 
=== onScannedRobot() method ===
 
=== onScannedRobot() method ===
 
Then we save the coordinates based on the last <code>ScannedRobotEvent</code> (via the <code>e</code> parameter) we receive whenever our robot scans another robot:
 
Then we save the coordinates based on the last <code>ScannedRobotEvent</code> (via the <code>e</code> parameter) we receive whenever our robot scans another robot:
<pre>
+
 
 
   // The coordinates of the last scanned robot
 
   // The coordinates of the last scanned robot
 
   int scannedX = Integer.MIN_VALUE;
 
   int scannedX = Integer.MIN_VALUE;
 
   int scannedY = Integer.MIN_VALUE;
 
   int scannedY = Integer.MIN_VALUE;
 
+
 
 
   // Called when we have scanned a robot
 
   // Called when we have scanned a robot
 
   public void onScannedRobot(ScannedRobotEvent e) {
 
   public void onScannedRobot(ScannedRobotEvent e) {
 
       // Calculate the angle to the scanned robot
 
       // Calculate the angle to the scanned robot
 
       double angle = Math.toRadians((getHeading() + e.getBearing()) % 360);
 
       double angle = Math.toRadians((getHeading() + e.getBearing()) % 360);
 
+
 
 
       // Calculate the coordinates of the robot
 
       // Calculate the coordinates of the robot
 
       scannedX = (int)(getX() + Math.sin(angle) * e.getDistance());
 
       scannedX = (int)(getX() + Math.sin(angle) * e.getDistance());
 
       scannedY = (int)(getY() + Math.cos(angle) * e.getDistance());
 
       scannedY = (int)(getY() + Math.cos(angle) * e.getDistance());
 
   }
 
   }
</pre>
 
  
 
=== onPaint() method ===
 
=== onPaint() method ===
 
Okay, so now we just have to paint a red transparent square on top of the scanned robot:
 
Okay, so now we just have to paint a red transparent square on top of the scanned robot:
<pre>
+
 
 
   // Paint a transparent square on top of the last scanned robot
 
   // Paint a transparent square on top of the last scanned robot
 
   public void onPaint(Graphics2D g) {
 
   public void onPaint(Graphics2D g) {
 
       // Set the paint color to a red half transparent color
 
       // Set the paint color to a red half transparent color
 
       g.setColor(new Color(0xff, 0x00, 0x00, 0x80));
 
       g.setColor(new Color(0xff, 0x00, 0x00, 0x80));
 
+
 
 
       // Draw a line from our robot to the scanned robot
 
       // Draw a line from our robot to the scanned robot
 
       g.drawLine(scannedX, scannedY, (int)getX(), (int)getY());
 
       g.drawLine(scannedX, scannedY, (int)getX(), (int)getY());
 
+
 
 
       // Draw a filled square on top of the scanned robot that covers it
 
       // Draw a filled square on top of the scanned robot that covers it
 
       g.fillRect(scannedX - 20, scannedY - 20, 40, 40);
 
       g.fillRect(scannedX - 20, scannedY - 20, 40, 40);
 
   }
 
   }
</pre>
 
  
 
So now, whenever our robots scans a robot, it paints a red line from our robot to the scanned robot and also paints a red transparent square on top of it:
 
So now, whenever our robots scans a robot, it paints a red line from our robot to the scanned robot and also paints a red transparent square on top of it:

Revision as of 23:21, 10 October 2008

This page will explain how to perform graphical debugging with Robocode using the onPaint method.

Classic Debugging

One classic way of debugging code is to use System.out.println() statements in your code and read the output in the console. This classic way of debugging is excelent in most cases, especially when you want to write out information about e.g. how many times you have hit another robot compared to how many times you have missed etc.

Another form of debugging is using a debug tool, e.g. the one that comes with Eclipse, where you are able to set breakpoints and create watch points etc. in your code to see how your robot behaves. With this kind of debugging you'll be able to get a "snapshot" of the current values contained by all field values of your robot.

Graphical Debugging

However, Robocode provides an additional and very powerful way of debugging your robot. That is graphical debugging, where you can paint graphics for you robot on top of the graphics that is being rendered on the battle view. In some cases, this kind of debugging provides you with better view of how your robot "sees" the world surrounding it.

Instead of printing out for example estimated future coordinates of your robots, you can paint these coordinates as dots (or similar) on the battlefield to see how well your robot is at tracking the enemies. Basically, the can paint whatever you want on the battlefield.

Tron and Fractal firing at each other, thus creating waves with each shot

Enable Painting

NOTE: By default, the painting of all the robots is disabled. Why? Imagine 10 robots on the battlefield, who all wants to do their own paintings. The whole battle view would potentially be "polluted" with all kind of graphical stuff from each robot, which can be quite annoying, especially when you want to watch what is going on with your robot(s) on the battlefield. Therefore, you have to enable the painting of the robots, which you want to allow painting their graphics on the battlefield. However, you should expect that robots might "hide" their (debug) painting for the public, or have removed their code in order to keep the code size small.

In order to enable the painting (performed within the onPaint() method), you must open the robot console of your robot and press the Paint button to enable the painting. The painting is disabled with clicking on the same button.

Shows how to enable painting of the graphics for a robot, which is the debug.Tracker robot in this case

The onPaint() method

In order to paint anything on the battlefield, you must override the public void onPaint(Graphics2D g) method. This method is automatically called by Robocode each time the battlefield is being rendered (and the painting is enabled). Basically, the painting is performed by calling methods on the Graphics2D object given a input parameter to the onPaint method. So you can for example set the color to paint with, draw circles, rectangles etc., which can be both filled out and not filled out.

Simple Example

So, here is an simple example of how to paint a red filled rectangle on the screen:

 import java.awt.Color;
 import java.awt.Graphics2D;
 
 public void onPaint(Graphics2D g) {
     // Set the paint color to red
     g.setColor(java.awt.Color.RED);
     // Paint a filled rectangle at (50,50) at size 100x150 pixels
     g.fillRect(50, 50, 100, 150);
 }

The Coordinate System

If you are used to the "normal" coordinate system used with Awt and Swing, you should know that the coordinate system is mirrored to fit the coordinate system used in Robocode. This mean that if your robot is located on coordinate (x1,y1), and you paint a dot on this location (e.g. by fillRect(x1, y1, 1, 1)), then this dot will be put exactly on top of your robot.

The debug.Tracker robot example

In the following a more advanced example is provided to give an idea of how the onPaint() method can be used. In this example we want to put a red square on top of the last scanned robot seen by our robot, and the robot does nothing else than just scanning and painting.

run() method

So first of all, we tell our robot to do nothing else than turning the robot for ever when it is run:

 // How to run our robot
 public void run() {
     // Rotate the radar for ever in order to detect robots
     while (true) {
         turnRadarRight(360);
     }
 }

onScannedRobot() method

Then we save the coordinates based on the last ScannedRobotEvent (via the e parameter) we receive whenever our robot scans another robot:

 // The coordinates of the last scanned robot
 int scannedX = Integer.MIN_VALUE;
 int scannedY = Integer.MIN_VALUE;
 
 // Called when we have scanned a robot
 public void onScannedRobot(ScannedRobotEvent e) {
     // Calculate the angle to the scanned robot
     double angle = Math.toRadians((getHeading() + e.getBearing()) % 360);
 
     // Calculate the coordinates of the robot
     scannedX = (int)(getX() + Math.sin(angle) * e.getDistance());
     scannedY = (int)(getY() + Math.cos(angle) * e.getDistance());
 }

onPaint() method

Okay, so now we just have to paint a red transparent square on top of the scanned robot:

 // Paint a transparent square on top of the last scanned robot
 public void onPaint(Graphics2D g) {
     // Set the paint color to a red half transparent color
     g.setColor(new Color(0xff, 0x00, 0x00, 0x80));
 
     // Draw a line from our robot to the scanned robot
     g.drawLine(scannedX, scannedY, (int)getX(), (int)getY());
 
     // Draw a filled square on top of the scanned robot that covers it
     g.fillRect(scannedX - 20, scannedY - 20, 40, 40);
 }

So now, whenever our robots scans a robot, it paints a red line from our robot to the scanned robot and also paints a red transparent square on top of it:

Shows some paintings (a red line and square) on the battleview, where the robot debug.Tracker has spotted the sample.Crazy robot

References

See also

Robot API

Tutorials

News and Releases

Home pages