Talk:GFTargetingBot
I'm new to java, and my lack of understanding Java has me hung up on this key peice of code:
buffer = statBuffers[distanceIndex][velocityIndex][lastVelocityIndex];
from my understanding; buffer is an array of 25 (ints), each bin being a counter of times visited. And statBuffers is a 4dimesional array of size: 5(int), 5(int), 5(int),and 25(int) :
private static int[][][][] statBuffers = new int[DISTANCE_INDEXES][VELOCITY_INDEXES][VELOCITY_INDEXES][BINS];
so back to the problem code :
buffer = statBuffers[distanceIndex][velocityIndex][lastVelocityIndex];
so the above "indexes" (0-4) should retrieve the values in thoses locations in the statBuffers arrays. Am I wrong so far? It seems to me were assigning apples to oranges here? How does it work ? --Justin
int single[] = new int[ 5 ];
single is "an array of integers".
int double[][] = new int[ 5 ][ 5 ];
double is "an array of 5 arrays of 5 integers".
This means that each element in double[ n ]
is itself "an array of 5 integers".
Let's change int to apple. double is now "an array of 5 arrays of 5 apples."
This means that every double[ n ] is a container, and each container holds 5 apples. The container is not an apple. It is 'a container of one or more apples'. You can visualize it as a paper bag if you like.
apple triple[][][] = new apple[ 5 ][ 5 ][ 5 ];
triple is "an array of 5 arrays of 5 arrays of apples" or perhaps "5 containers of 'containers of apples'".
Going back to your original question, here is the situation: buffer is 'an array of integers'. (I deliberately did not state the size, because buffer can be assigned an array of any size of the same dimensions.) statBuffers is 'an array of arrays of arrays of arrays of integers'. Each element in statBuffers[][][] is itself an 'array of integers', and that is why the assignment works.
I hope that helped. If not, best thing is to just practice with arrays it until it sinks in.
--Martin
Addendum: Above you mentioned "statBuffers is a 4 dimesional array of size: 5(int), 5(int), 5(int), and 25(int)", and therein lies the misconception. The "5(int)" sections are not arrays of integers. They are "arrays of arrays". The integers only exist in the final array. --Martin
Yes I wasn't thinking dimesionally :), in the case of GFTargengBot code: buffer ends up being the 4 dimension of statBuffer that corisponds to the first 3 dimensions.. Correct? --Justin
Correct. Also, buffer doesn't get its own copy of the data. It just refers to the same memory location for the data that that branch of statBuffer does. I doubt that's really relevant, but it may become relevant in some other application, and just saying "Correct." alone seemed silly. --Martin
thx Martin :) --Justin
|
Old Wiki
Comments, questions, feedback:
Way cool, PEZ! It might be cool to pair this with the BasicSurfer movement and post it to the rumble, just to get a sense of a "base line" for a functioning GuessFactor gun and WaveSurfing movement. (This seems a little more polished for what it is than BasicSurfer, though...) I'm curious to hear from some other people how clear this code seems to them, as I'm already very familiar with both GuessFactorTargeting, and the PEZ style of the GF code that is found here. This should certainly be linked from a few places, including the GuessFactorTargeting/Tutorial. (I'll do some of that myself sometime soon if nobody else does.) -- Voidious
Really nice! Just a quick question what is BIN_WIDTH? It seems to be
maxEscapeAngle/MIDDLE_BIN
, because the 0.7 is not really self explanatory (to me at least). Other than that it seems fine to me. -- Florent
I think using .7 instead of a true calculation is a "MiniBot-ism", as Math.asin(8/bulletvelocity(1.9)) is about .6 in radians. -- Voidious
No, it's not really minibot-ism. It's more of an approximation of the max escape angle that works for most bullet powers. But yeah, in a micro it saves spaces. I've changed the code above to include a MAX_ESCAPE_ANGLE constant. I hope that makes the code clearer. -- PEZ
Hi. I see, that you don't store your Waves in an ArrayList or Vector. Instead your GFTWave class exdends Condition. Could someone explain this point to me in more detail? By the way; I'm an absolute Greenhorn (Robocode and Java) but for some days i like to read the conversation of the godnesses from Robocode-Olymp. Sir Drake
An AdvancedRobot lets you add CustomEvents like that - it probably uses an ArrayList or Vector internally. Every tick, Robocode automatically runs the test() method of each CustomEvent, so this setup is just making use of that capability of the RobocodeAPI to take care of the waves stuff. This setup is particularly useful in CodeSize-restricted bots, as well, as it saves you a little bit of code. -- Voidious
Hmm, it's late here, and re-reading my post, that might not have completely cleared things up for you =) It does give some links that might help clear things up, but certainly feel free to ask if it's still unclear. (This is a Tutorial type bot, after all!) Don't worry about being a Greenhorn, this site is the perfect place to be for a beginner to Robocode ;) -- Voidious
In this bot I do it for clarity. Instead of adding structural code to handle the waves I just use a built-in Robocode mechanism. As long as your somewhat familiar with Robocode and its custom events then it's less blur. Note however, that if you want complete control over the execution order you might want to manage the waves list yourself. That or figure out exactly when custom events are executed in respect to the rest of your code. In this bot though I opted for as little extra code as possible. -- PEZ
I have run a TargetingChallenge2K6 with GFTargetingBot 1.02, mainly to have a reflection of GresSuffurd against another simple GF-gun. The results are a bit less than I expected, although it is clearly stated that this bot is just a basic implementation without any advanced stuff. One thing is quite obvious, to hit a WaveSurfer you do need more than this. -- GrubbmGait
Name | Author | Gun | BFly | CC | Chk | Cig | Cya | DM | FM | Grb | RMB | Tig | Total |
GFTargetingBot 1.02 | PEZ | GF | 88.57 | 31.62 | 41.16 | 72.73 | 28.45 | 92.84 | 77.53 | 85.38 | 84.18 | 51.91 | 65.44 |
Indeed. In fact this bot is almost designed to miss a wavesurfer. Or, rather, any non-trivial WaveSurfer is designed to avoid it. Run a regular TargetingChallenge and you might see better performance from this bot. Is that a full TC2K6 run? If so, please pubish it on the appropriate results page. Good to have references like that. Especially if people base their bots on this code. -- PEZ
Results are published. I started an old TargetingChallenge, the results will be present in an hour or three. -- GrubbmGait
It has already finished, this gun is very comparable with Tityus's gun.
Name | Author | Type | DT | Asp | TAOW | Spar | Cig | Tron | Fhqw | HTTC | Yng | Funk | Score |
GFTargetingBot 1.02* | PEZ | GF | 77.58 | 89.67 | 99.55 | 96.57 | 70.94 | 86.40 | 91.03 | 88.77 | 95.09 | 85.15 | 88.07 |
Just for grins, I DID pair this with BasicSurfer and the results were surprisingly good. It is BasicGFSurfer and ranks 47th in the RoboRumble as of 10-25-06. --Bayen
Yah, I did a merger too, and i'm trying to get mine to beat it. -- Chase-san
Okay, I'm trying to understand this code and have a couple of questions. In the GFTWave, when does the information from buffer
get returned to statBuffers
? It seems to me like it only takes data from statBuffers
and never puts data back in. --Bayen
The magic is in this line from setSegmentation:
buffer = statBuffers[distanceIndex][velocityIndex][lastVelocityIndex];
After this, they 1D array "buffer" is set to point to one of the final dimensions of "statBuffers", so their cells point to the exact same data. This will save you from typing "statBuffers[index1][index2][index3]" every time you are accessing that data in that tick.
-- Voidious
Yah I had the same question, if Voidious' excellent explination wasn't enough you get my extremely confusing one, but one that comes with a visual represnetation...
Pointers 101: with visual aids
Here we have two different statBuffers, each with what data they contain displayed respecibly below them. Main Class GFTWave +-------------+ +-------------+ | statBuffers | | statBuffers | +-------------+ +-------------+ | 0 | | | +-------------+ +-------------+ Notice how the statBuffers in GFTWave contain nothing, thats considered a null state, or just null for short. Now when you assign the statBuffers from the main class to the statBuffers of the GFTWave your not actually copying the data, no for that you would need to clone() it. Now you have made a pointer! Congradulations. Main Class GFTWave +-------------+ +-------------+ | statBuffers | | statBuffers | +-------------+ same as +-------------+ | 0 | <-------- | 0 | +-------------+ this +-------------+ Now any modification you make to the data in the GTFWave class will also take place in the main class aswell. So when you assign or add or multiply or do whatever else to the data in the GTFWave it also takes place in the Main class. GFTWave:statBuffers = 1; Main Class GFTWave +-------------+ +-------------+ | statBuffers | actually | statBuffers | +-------------+ happens to +-------------+ | 1 | <--------- | 1 | +-------------+ this +-------------+ It also works in reverse. So anything you assign to the main class will also happen to the data in the other class.
I explained all that just so I could make the ascii graphics. -- Chase-san