Difference between revisions of "Talk:Hat League/Message Format"

From Robowiki
Jump to navigation Jump to search
(migration of discussion)
 
m (Using <syntaxhighlight>.)
 
(2 intermediate revisions by 2 users not shown)
Line 15: Line 15:
 
----
 
----
  
I like the messages you have laid out there. So were you thinking of just sending strings for each thing? Alternatively, we could create a base class for everyone to extend, with (Serializable) classes for each message type, and methods for sending the messages that are customizable (i.e., not personal data or enemy scan); then create the <nowiki>onMessageReceived</nowiki> method that passes off the message types to handler methods, which you'd override like with the built in event methods. I hope I'm making sense... No other message types come to mind that you don't already have listed, but I'll rack my brain a bit. -- [[Voidious]]
+
I like the messages you have laid out there. So were you thinking of just sending strings for each thing? Alternatively, we could create a base class for everyone to extend, with (Serializable) classes for each message type, and methods for sending the messages that are customizable (i.e., not personal data or enemy scan); then create the <nowiki>onMessageReceived</nowiki> method that passes off the message types to handler methods, which you'd override like with the built in event methods. I hope I'm making sense... No other message types come to mind that you don't already have listed, but I'll rack my brain a bit. -- [[User:Voidious|Voidious]]
  
 
In my second attempt at making a team robot, I had a serializable structure that had some doubles in it, but when I tried to send it to the message broadcaster it choked.  I ended up having to break the same data into a comma delimeted string manually and reinterpreting it on the other end.  If there is some magic thing I overlooked then it would certainly be easier to send it as a structure.  Otherwise we / I can provide a complete class to compose and translate messages.  I do mostly batch processing lately so I've got routines for doing the CSV stuff already.  -- Martin
 
In my second attempt at making a team robot, I had a serializable structure that had some doubles in it, but when I tried to send it to the message broadcaster it choked.  I ended up having to break the same data into a comma delimeted string manually and reinterpreting it on the other end.  If there is some magic thing I overlooked then it would certainly be easier to send it as a structure.  Otherwise we / I can provide a complete class to compose and translate messages.  I do mostly batch processing lately so I've got routines for doing the CSV stuff already.  -- Martin
  
Sending serializable structures (with doubles) worked in my last 5 team attempts :) --[[Krabb]]
+
Sending serializable structures (with doubles) worked in my last 5 team attempts :) --[[User:Krabb|Krabb]]
  
Just FYI, I found that internal classes wouldn't serialize even if they extended Serializable. The moment I made the class external, problem solved. -- [[Skilgannon]]
+
Just FYI, I found that internal classes wouldn't serialize even if they extended Serializable. The moment I made the class external, problem solved. -- [[User:Skilgannon|Skilgannon]]
  
 
<hr>
 
<hr>
<pre>
+
<syntaxhighlight>
 
public static String[] parseCSV( String line, int count )
 
public static String[] parseCSV( String line, int count )
 
{
 
{
Line 73: Line 73:
 
return value;
 
return value;
 
}
 
}
</pre>
+
</syntaxhighlight>
 
Above is some code I've written for a batch processing application.  I am sure it could stand some optimization.  The <nowiki>ExceptionHandler</nowiki> class is just a log file recorder.  You could also use this to process tab delimeted (not shown) or some other delimeter.  Writing out comma separated values is much simpler, so I didn't bother writing any example code.<br>
 
Above is some code I've written for a batch processing application.  I am sure it could stand some optimization.  The <nowiki>ExceptionHandler</nowiki> class is just a log file recorder.  You could also use this to process tab delimeted (not shown) or some other delimeter.  Writing out comma separated values is much simpler, so I didn't bother writing any example code.<br>
 
The result of this code is a String array containing the number of elements specified by a parameter.  If there are fewer elements in the CSV string, the remaining elements in the array will be null strings. This will not be a problem since we know by the first element what type of message it is, and how many elements we are looking for. -- [[Martin Alan Pedersen|Martin]]
 
The result of this code is a String array containing the number of elements specified by a parameter.  If there are fewer elements in the CSV string, the remaining elements in the array will be null strings. This will not be a problem since we know by the first element what type of message it is, and how many elements we are looking for. -- [[Martin Alan Pedersen|Martin]]
Line 81: Line 81:
 
Possible beginning of a "base class":
 
Possible beginning of a "base class":
  
<pre>
+
<syntaxhighlight>
 
import robocode.*;
 
import robocode.*;
  
Line 213: Line 213:
 
}
 
}
  
</pre>
+
</syntaxhighlight>
  
This could be the beginning of a "base class" for all competitors, we could implement the same for <nowiki>ScannedRobotEvents and Bullet Missed(/Hit)Events</nowiki>. With this kind of implementation the bots don't have to differentiate between their own or mate bullets and events, but it might be a bit slow :/ Suggestions? --[[Krabb]]
+
This could be the beginning of a "base class" for all competitors, we could implement the same for <nowiki>ScannedRobotEvents and Bullet Missed(/Hit)Events</nowiki>. With this kind of implementation the bots don't have to differentiate between their own or mate bullets and events, but it might be a bit slow :/ Suggestions? --[[User:Krabb|Krabb]]
  
Would the 2000 byte limit still apply? Cause this code doesn't exactly look optimized for size... ---[[David Alves]]
+
Would the 2000 byte limit still apply? Cause this code doesn't exactly look optimized for size... ---[[User:David Alves|David Alves]]
  
I was under the impression there would be no CodeSize limit for this... ? -- [[Voidious]]
+
I was under the impression there would be no CodeSize limit for this... ? -- [[User:Voidious|Voidious]]
 
*That is also my understanding. -- Martin
 
*That is also my understanding. -- Martin
  
 
I'm mentioning this prematurely, as I don't have the <nowiki>JavaDoc</nowiki> written and am not really competent at packaging JAR files (which seems odd since I've done Java since 2000), but I've written a set of classes to support team communication.  They don't do automatic serialization, but rather read and write comma-separated value Strings.  I'm open to do some beta testing with anyone interested in making the Hat Tourney a reality.  -- Martin
 
I'm mentioning this prematurely, as I don't have the <nowiki>JavaDoc</nowiki> written and am not really competent at packaging JAR files (which seems odd since I've done Java since 2000), but I've written a set of classes to support team communication.  They don't do automatic serialization, but rather read and write comma-separated value Strings.  I'm open to do some beta testing with anyone interested in making the Hat Tourney a reality.  -- Martin
 
*The implementation covers all message types listed at the top of the page (hence the CSV approach), as well as a <nowiki>"CommuniqueNotAvailable"</nowiki> representing something that was unparseable.  They are packaged as wiki.team.communication.* -- Martin
 
*The implementation covers all message types listed at the top of the page (hence the CSV approach), as well as a <nowiki>"CommuniqueNotAvailable"</nowiki> representing something that was unparseable.  They are packaged as wiki.team.communication.* -- Martin
 +
 +
I wrote an implementation at [[User:AaronR/HatLeagueRobot]]. It is a fairly standard event-delegating framework, but I haven't tested it very much. « [[User:AaronR|AaronR]] « [[User talk:AaronR|Talk]] « 01:23, 15 January 2008 (UTC)

Latest revision as of 09:34, 1 July 2010

Here's my draft suggestion for a common message format. Each line in a message is a different message, prefixed by the message type, followed by comma-seperated-values:

PD,time,x,y,h,v,e	// personal data
ES,time,x,y,h,v,e,name	// enemy scan
BO,time,x,y,h,v		// bullet (origin)
EW,time,x,y,v		// enemy wave origin
MR,name			// my radar target
MB,name			// my bullet target
TR,name			// suggested radar target
TB,name			// suggested bullet target
NA,message		// custom message

-- Martin


I like the messages you have laid out there. So were you thinking of just sending strings for each thing? Alternatively, we could create a base class for everyone to extend, with (Serializable) classes for each message type, and methods for sending the messages that are customizable (i.e., not personal data or enemy scan); then create the onMessageReceived method that passes off the message types to handler methods, which you'd override like with the built in event methods. I hope I'm making sense... No other message types come to mind that you don't already have listed, but I'll rack my brain a bit. -- Voidious

In my second attempt at making a team robot, I had a serializable structure that had some doubles in it, but when I tried to send it to the message broadcaster it choked. I ended up having to break the same data into a comma delimeted string manually and reinterpreting it on the other end. If there is some magic thing I overlooked then it would certainly be easier to send it as a structure. Otherwise we / I can provide a complete class to compose and translate messages. I do mostly batch processing lately so I've got routines for doing the CSV stuff already. -- Martin

Sending serializable structures (with doubles) worked in my last 5 team attempts :) --Krabb

Just FYI, I found that internal classes wouldn't serialize even if they extended Serializable. The moment I made the class external, problem solved. -- Skilgannon


	public static String[] parseCSV( String line, int count )
	{
		final char delimeter = ',';
		final char textWrapper = '\"';
		return parseDelimetedValues( line, count, delimeter, textWrapper );
	}
	
	private static String[] parseDelimetedValues( String delimetedValues, int count, final char delimeter, final char textWrapper )
	{
		String value[] = new String[ count ];
		
		int startIndex = 0;
		int endIndex = 0;

		try
		{
			for( int i = 0; ( ( i < count ) && ( endIndex != -1 ) && startIndex < delimetedValues.length( ) ); i++ )
			{
				if( delimetedValues.charAt( startIndex ) == textWrapper )
				{
					startIndex++;
					endIndex = delimetedValues.indexOf( textWrapper, startIndex );
					value[ i ] = delimetedValues.substring( startIndex, endIndex );
					startIndex = delimetedValues.indexOf( delimeter, endIndex ) + 1;
				}
				else
				{
					endIndex = delimetedValues.indexOf( delimeter, startIndex );
					if( endIndex == -1 )
					{
						value[ i ] = delimetedValues.substring( startIndex );
					}
					else
					{
						value[ i ] = delimetedValues.substring( startIndex, endIndex );
						startIndex = endIndex + 1;
					}
				}
			}
		}
		catch( Exception ex )
		{
			ExceptionHandler.getInstance().log( ex );
			ExceptionHandler.getInstance().log( "line: " + delimetedValues );
		}
		
		return value;
	}

Above is some code I've written for a batch processing application. I am sure it could stand some optimization. The ExceptionHandler class is just a log file recorder. You could also use this to process tab delimeted (not shown) or some other delimeter. Writing out comma separated values is much simpler, so I didn't bother writing any example code.
The result of this code is a String array containing the number of elements specified by a parameter. If there are fewer elements in the CSV string, the remaining elements in the array will be null strings. This will not be a problem since we know by the first element what type of message it is, and how many elements we are looking for. -- Martin


Possible beginning of a "base class":

import robocode.*;

import robocode.Bullet;
import java.io.*;

//
// "Base Class" to share information, every bot must extend "CustomTeamRobot" 
// and call the setCustomTeamRobot(this) function
//

public class CustomTeamRobot extends TeamRobot
{
	CustomTeamRobot robot;
	
	public void setCustomTeamRobot(CustomTeamRobot robot)
	{
		this.robot=robot;
	}
	
	public Bullet setFireBullet(double p)
	{
		Bullet b = super.setFireBullet(p);
		if(b==null)
			return b;
		MessageBullet mb = new MessageBullet(b, p, this);
		if(getTeammates()!=null)
		{
			try{
				broadcastMessage(mb);}
			catch(IOException ex){
				System.out.println(ex);}
		}
		return b;
	}
	
	public final void onMessageReceived(MessageEvent ev){
		if(ev.getMessage().getClass()==MessageBullet.class)
		{
			robot.newTeamBullet(new TeamBullet((MessageBullet)ev.getMessage(),this));
		}
	}
	
	public void newTeamBullet(Bullet b){
	}
}

//class to send Bullet data
class MessageBullet implements Serializable
{
	double heading;
	double power;
	double velocity;
	double x_start,y_start;
	long time_start;
	
	public MessageBullet(Bullet b, double power, CustomTeamRobot robot)
	{
		heading=robot.getGunHeadingRadians();
		this.power=power;
		velocity=20-3*power;
		x_start=robot.getX();
		y_start=robot.getY();
		time_start=robot.getTime();
	}
	
	public double getHeading(){
		return heading;}
}


// simulates a real robocode "Bullet"
class TeamBullet extends Bullet
{
	CustomTeamRobot robot;
	MessageBullet mb;
	public TeamBullet(MessageBullet mb, CustomTeamRobot robot)
	{
		super(null);
		this.robot=robot;
		this.mb=mb;
	}
	
	public double getY() {
		return mb.y_start+Math.cos(mb.heading)*mb.velocity*(robot.getTime()-mb.time_start);
	}
	public double getX() {
		return mb.x_start+Math.sin(mb.heading)*mb.velocity*(robot.getTime()-mb.time_start);
	}
}

//=============================================================================================

/////////////////
//Test Robot:
/////////////////

import java.awt.*;
import java.util.*;
import robocode.Bullet;

public class TeamTestBot extends CustomTeamRobot
{
	ArrayList<Bullet> bullets = new ArrayList<Bullet>();
	public void run() 
	{
		setCustomTeamRobot(this);
		setTurnRadarRightRadians(Double.POSITIVE_INFINITY);
		setTurnLeft(Double.POSITIVE_INFINITY);
		setAhead(Double.POSITIVE_INFINITY);
		while(true)
		{
			Bullet b = setFireBullet(3);
			if(b!=null)
				bullets.add(b);
			System.out.println("size: "+bullets.size());
	        execute();
		}
	}
	
	public void newTeamBullet(Bullet b){
		bullets.add(b);
	}
	
	public void onPaint(java.awt.Graphics2D g)
	{
		g.setColor(Color.RED);
		for(int i=0; i<bullets.size(); i++)
			g.fillOval((int)bullets.get(i).getX()-2, (int)bullets.get(i).getY()-2, 5, 5);
	}
}

This could be the beginning of a "base class" for all competitors, we could implement the same for ScannedRobotEvents and Bullet Missed(/Hit)Events. With this kind of implementation the bots don't have to differentiate between their own or mate bullets and events, but it might be a bit slow :/ Suggestions? --Krabb

Would the 2000 byte limit still apply? Cause this code doesn't exactly look optimized for size... ---David Alves

I was under the impression there would be no CodeSize limit for this... ? -- Voidious

  • That is also my understanding. -- Martin

I'm mentioning this prematurely, as I don't have the JavaDoc written and am not really competent at packaging JAR files (which seems odd since I've done Java since 2000), but I've written a set of classes to support team communication. They don't do automatic serialization, but rather read and write comma-separated value Strings. I'm open to do some beta testing with anyone interested in making the Hat Tourney a reality. -- Martin

  • The implementation covers all message types listed at the top of the page (hence the CSV approach), as well as a "CommuniqueNotAvailable" representing something that was unparseable. They are packaged as wiki.team.communication.* -- Martin

I wrote an implementation at User:AaronR/HatLeagueRobot. It is a fairly standard event-delegating framework, but I haven't tested it very much. « AaronR « Talk « 01:23, 15 January 2008 (UTC)