[Home]Pulsar/Archived Chat 1

Robo Home | Pulsar | Changes | Preferences | AllPages

No diff available--this is the first major revision. (no other diffs)

!

What?

It wasn't me writing that exlamation mark. But whoever did probably meant it as a PromptingStatement. -- PEZ

Hehe ok, I should start coding on my robot instead of writing something not many are interested in ;-)

Lots and lots of people are interested to know at least some about anyone making bots. Making top-20 bots doesn't make you less interesting =). -- PEZ

Indeed. Counting PEZ, there are, at least, two people interested on what is "made of" that top 20 new bot :). The concept behind the wiki is (i think) the sharing of ideas and knowledge, and the bots pages are not only a good source to others getting inspiration/ideas from you, but also a place to receive feedback (post help requests, receive spontaneous comments, etc..). -- Axe

Well yes that I understand, but that is more for the PulsarMax page I guess? I only have one bot in the RoboRumble so this page wouldn't be very interesting for now. -- Pulsar

Now at least there's a page when one clicks your name in the Changes list. =) -- PEZ

That's more like it. =) -- PEZ


Although it's not really the right place to ask - what on earth is java reflection?? Everyone i ever asked looked at me as if it were a dirty word... --Brainfade

Reflection is a way to "look inside" java objects and classes. Check http://java.sun.com/j2se/1.3/docs/api/java/lang/reflect/package-summary.html for a somewhat dense introduction. Also look at nano's StatGrapher, which is using it to do its magic. -- PEZ

(edit conflict!) As far as i know, java reflection is something that allows the java code to "look inside" itself. Using this API, u can for example, list the names and parameters methods and attributes of a class (also execute methods using the Introspection). A little example that lists all the methods of the String class:

import java.lang.reflect.*;
public class ReflectionTeste {
    public static void main(String args[]) {
        try {
            Class c = Class.forName( "java.lang.String" );
            Method m[] = c.getDeclaredMethods();
            for (int i = 0; i < m.length; i++) {
                System.out.println( m[i].toString() );
            }
        } catch (Throwable e) {
            System.err.println(e);
        }
    }
}
But i have no idea how Pulsar could use this in robocoding, it would be interesting to hear something about... -- Axe

I use it for the guess factor targeting so I can easily redefine them and create new ones. I guess a more advanced version would do more magic.

targetings[0] = new GuessFactorTargeting(new int[] {8, 1, 3, 3, 3, 1, 1, 1, 1, 5, 1, 2, Settings.TARGETING_GUESSFACTORS});
note the int array, that defines the dimensions of one of my guess factor targetings (1 means I don't use that segment, with reflection I could remove even those but that just makes it hard to know which index is which so I don't do it ... yet... ). So for now it's just for development purposes, if I come up with a new segment I just add a number ion the above example and implement the calculation of the index in one place, done. No need to change code here and there to use one more dimension etc. I'm not using this for wave surfing (maybe later). It has one drawback, I haven't implemented a way of easily saving all that data effeciently yet. Just serializing it all takes 100kb or so per enemy compressed!! -- Pulsar

In Robocode u have 200K of space for saving data. If you r thinkin about saving data, in that kind of environment, serialization is far to be acceptable (even with CompressedSerialization - take a look at that page!). As u know, serialization is an easy-use API for persistence stuff, the problem is that easy-use cost a price: size. So we are all back to the radio-shack age, 200K for 260+ enemies... The solution that is usually adopted is to save that data compressed (like in CompressedSerialization), and give up the data "precision". As an example, i use Paulīs rolling average formula to rate my WaveSurfing segmented GFs. That kind of formula is suposed to give to me a double with something between 0-1 in each bin, when saving, i use only one byte for each bin, by a simple conversion to byte within a range 0-100. Bellow is the code that i use (nicely cleaned :):

 
public void save(String name) {
    try {
	GZIPOutputStream zipout = null;
	DataOutputStream w = null;
	zipout = AxeFiles.getGZipOutputStream(name
		+ AxeFiles.GFS_FILE_EXTENSION);
	w = new DataOutputStream(zipout);
	System.out.println("saving numAllHits=" + numAllHits);
	w.writeByte((byte) numAllHits);
	for (int i = 0; i < GF_QT; i++) {
		w.writeByte((byte) Math.round((allHits[i] * 100)));
	}
	for (int j = 0; j < DISTS; j++) {
		for (int k = 0; k < VELS; k++) {
			for (int l = 0; l < ACCS; l++) {
				for (int m = 0; m < BULL_PWR; m++) {
					w.writeByte((byte) numHits[j][k][l][m]);
					for (int i = 0; i < GF_QT; i++) {
				        	w.writeByte((byte) Math
							.round((hits[j][k][l][m][i] * 100)));
					}
				}
			}
		}
	}
	w.flush();
	zipout.finish();
	w.close();
   } catch (IOException e) {
       AxeBot.getIt().out.println("IOException trying to write: " + e);
   }
}	

public void load(String name) {
	DataInputStream r = null;
	GZIPInputStream zipin = null;
	try {
		File f = AxeFiles.findFile(name + AxeFiles.GFS_FILE_EXTENSION);
		zipin = new GZIPInputStream(new FileInputStream(f));
		r = new DataInputStream(zipin); //new FileInputStream(f));
		numAllHits = r.readUnsignedByte();
		System.out.println("loading numAllHits=" + numAllHits);
		for (int i = 0; i < GF_QT; i++) {
			allHits[i] = r.readUnsignedByte() / 100D;
		}
		for (int j = 0; j < DISTS; j++) {
			for (int k = 0; k < VELS; k++) {
				for (int l = 0; l < ACCS; l++) {
					for (int m = 0; m < BULL_PWR; m++) {
						numHits[j][k][l][m] = r.readUnsignedByte();
						for (int i = 0; i < GF_QT; i++) {
							hits[j][k][l][m][i] = r.readUnsignedByte() / 100D;
						}
					}
				}
			}
		}
	} catch (Throwable e) {
		AxeBot.getIt().out.println("IOException trying to read: " + e);
	} finally {
		try {
			r.close();
			zipin.close();
		} catch (Throwable e2) {}
     }
}        
That code was extracted from SilverSurferīs code, it is open source i there is any method that u want to seek (but i warn u: it is a messy code:).
This data saved (I use a segmentation of 3X5X3X1 and 97 bins = 4365 bins) compressed costs me ~400 bytes per enemy. -- Axe

I think that without some CribSheet thinking on Pulsar's GF structures it will never be able to store more than 10 or so enemies in the 200K limit. But fast learning techniques might gain more than data saving anyway.

I still don't quite understand how the Reflection above is applied though. Think you can post some more code snippets Pulsar?

-- PEZ

Thanks axe! I'm in no way going to do serialization of course but it is the quickest way to start with data saving. :) At work we usually do sort of a poor mans serialization for example (not even using externalizable but instead predefining a number of identifiers and then saving bytes our selves, so we sort of still keep the object-oriented stuff but have a minimum of data transfer needs) when we send stuff over the air (satellite, GSM SM, GPRS etc). I'm currently not using any rolling averages, I did so in my last bot though, thinking of trying it again, if so the above seems very nice! If I'm not using rolling averages (which I probably should start doing again) I was thinking of representing each double as a byte, with sort of an exponential mapping range. Anyway, I am indeed of course going to save some sort of byte array (whatever it represents) byte by byte instead.

Well Pez you will be amazed what knowing a few things about your data can do for your data saving needs ;-) Hm ok guess that's what you mean by crib sheet actually. I was more thinking along the lines of a byte represents 256 different possibilities and we want to use them all in a smart way, doesn't have to map directly to a guessfactor stat for example, maybe even predefine profiles, (probably a bad idea), but predefining and/or mapping things is usually effective. Quick learning indeed seems like more fun/challening though so this data saving is not a priority for now! Dynamic segmentation, thinking of automating it somehow with a few parameters here and there and then plug it in with the GF targeting and wave surfing.

For short, thanks both for again putting ideas into my head, and yes indeed bytes not serialization is the way it will be done, with a cribsheet eventually, and hopefully something even smarter, sometime... Maybe at least have different amounts of information per enemy. Dynamic data segmentation will help quick learning though as Pez says and that will fun to work out! :)

I will try and explain it further and with examples this evening maybe Pez. I should work now! So many ideas, so little time :) -- Pulsar

Ok Java reflection and guessfactors. Let's say you decide on anumber of segmentations for you guessfactor targeting/movement and come up with the following:

double[][][][] factors = new double[DISTANCE][VELOCITY][ACC][WALLS][FACTORS];
All is well, you write your code, get it all to work etc. Then one day you decide you would like to experiment/add/remove some segmentations. Youimmediately face a problem if you are passing around the factors variable, storing per enemt etc etc you have to change your code it in quite a few places. For short you can't declare an array with at runtime decided number of dimensions (just the size of each dimension). Or even simplier if you have a compile-time decided number of dimension but want to change it you have to change all your source code referring to it. Java reflection let's you do that in an easy way though. I'm just using this for targeting right now and for experimenting around with them. To make it easier I have a set number of dimensions decided at compile time actually, makes it easier to handle all possible indexes for now. I just set the ones I don't want to use to 1. The other ones I can generally pick whatever I feel like (the index calulators I have for a segmentation can handle arbitrary number of indexes in general) But it makes it extremely easy to add segmentations because only the declaration of the guess factor targeting needs updating (and the calculation of the index of course). No a big issue for non-mega bots I guess, but PulsarMax weighs in at around 20 classes now and I try to separate things in to methods here and there and not duplicate code. Global variables are bad too :) I'll add a code example or two when I get home. -- Pulsar



Congratulations! A really nice picture that too. -- PEZ

Thanks, a friend was playing around with the picture stuff, not me though, so the credits go to her, but still working on it :) -- Pulsar

Pulsar, do you remember the days that you signed your postings with something like "/Pulsar?, who will someday enter a bot to one of the competitions and get badly beaten :) ". (see http://www.robocoderepository.com/jive/thread.jsp?forum=6&thread=487&start=15) You are no. 4 right now and beating us badly! --Loki

Hehe, I remember that indeed! Thanks for bringing a smile to my face! At least I started out by solving a problem :) I'm only no. 6 right now though I think, but got lots of things to do before giving up, "only" need some more spare time!! Anyone selling some? I barely have time to chat about robocode with PEZ! Finding one of those things collectively known as SignificantOthers didn't help... ;-) --Pulsar

PulsarMax does get badly beaten by all surfers though. =) -- PEZ

PEZ you always find something to say to motivate me... By the way, the wallseg stuff and some accidental smoothing in the gun, wasn't the problem, it helps, but not all the way. Bleh. But if this all was easy where would the fun be? --Pulsar


Robo Home | Pulsar | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited July 22, 2005 17:00 EST by Pulsar (diff)
Search: