Archived talk:User:Pulsar 20050722

From Robowiki
Revision as of 16:29, 21 May 2009 by Robobot (talk | contribs)
Jump to navigation Jump to search
Pulsar Sub-pages:
PulsarArchived Talk 20050722
       Archive        This is an archive of past discussions. Do not edit the contents of this page. If you wish to start a new discussion or revive an old one, please do so on the current talk page.     

!

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

  • Ah....I remember fondly the days of my coding ideals. No byte saving techniques. Crisp clear code. Everything commented. Yes I remember it like it was yesterday. Then I started to write MiniBots. Now all of that is gone. Come to the dark side, Luke. Your anger makes you stronger. =^> -- jim
  • You might consider looking at the FloodGrapher robot to see one way of using reflection and organized classes to have a variable-dimension stats array. -- Kawigi
    • Bah and I who thought I was first in robocode to do that. :-) -- Pulsar
    • Ah ok you use it to load configured classes (reflection to find the constructors). Anything during the fights? I was more thinking of doing it on the fly later on. What I'm doing right now could as well be done using a List with Lists as elements, but then I would need to convert back and forth between Objects and primitives all the time (until Java 1.5). I'll explore all this more when I have gotten to the pint when it is time for dynamic data segmentation of some sort. -- Pulsar
      • Well, an early version of FloodHT tried every possible combination of segmentations, too, and did so fairly efficiently, if I do say so... But this also led to an obscene number of VG's (especially since I had another 5 or 10 aside from that, for a total of almost 30). And it wasn't very good. I swapped it out when I made a version of FloodMini that was clearly better than it, and made the current version which is quite similar to FloodMini as far as functionality. -- Kawigi
        • Although people have suggested otherwise, i can't see (other than the problem of choosing between them, and possibly excution speed) how having loads and loads of virtual guns could be a disadvantage, surely you just eventually you just end up using a gun, or a small selection of guns against a particular bot. Is it just that it hampers you over short battles, and that you cant save all your data?? if so you surely just save the data on either which guns are better, or just save the data on the best gun(s) --Brainfade
          • I think the problom is to always select the best gun (PEZ correct me now If I'm wrong). It's not as easy as it seems. One can only emualte the gun not currently used with for example virtual waves. But an enemy that is adapting its movment depending on where it gets hit for example might screw up all those stats. Just one example. So basically you would have to run a couple of matches with each gun. I still think it can be of use though, especially against a big majority of the enemies. :)
            • Actually, while on paper it looks good, in practice it doesn't work even if your enemy isn't adapting its movement or even attempting to dodge your bullets. I think the problem is that the "best gun" you'll pick is always the one you should have picked before, not the one you should pick now (because you pick the gun based on past performance, and you can't pick it based on future performance). I experimented with a lot of virtual guns and with a few virtual guns, and the obvious result was that against any enemy, the results were not as good as they would be with the best gun. The less obvious result is that if I have several solid guns that aren't especially specialized (i.e. say two guessfactor guns or a GF gun and a PM or something) that the overall performance is less than either of the original guns, although the performance against certain bots for which one is clearly better than the other may be more in-between (not worse than the worse gun against that robot). So it could be argued that you can exchange performance for less specialization. -- Kawigi



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

  • i am glad i made your day :-) --Loki

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

  • and by bots featuring a PM-gun (like eg. Fenrir). But those bots are a problem for all WaveSurfers... --Loki
  • I disagree. If you sort a PM-bots details sheet you'll find that it will have surfers as its worst enemies. Don't confuse PBI with problem. -- 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

You cannot post new threads to this discussion page because it has been protected from new threads, or you do not currently have permission to edit.

There are no threads on this page yet.