# User:Nat/WaveSurfingQuestion

From RoboWiki

< User:Nat

Hi all, I have some questions about wave surfing.

First, define some term I'll use in this question:

- Surfer: all those surfer around today.
- Wave Surfer: a surfer that log hit for every waves.
- Hit Surfer: a surfer that log hit on only hit waves.
- log hit: the operation that same as BasicSurfer's logHit function.

- Question 1
- What is the differnce between Wave Surfer and Hit Surfer? On first time I looked into surfing, the statement I found is "Surfing is exactly reverse of GuessFactor Targeting" so I understand surfer as Wave Surfer. But, when I looked into code of DussGT, Dookious, Horizona and PhonixOS, I found out that they are Hit Surfer (unless it enable its flattener which turn them into Wave Surfer). Only Butterfly I've recognize that it's Wave Surfer.

- Well, I know of NO surfer that logs non-hitting waves EXCEPT for flattener purposes. Bufferfly is included in this statement. As far as terminology, the "Wave" in "Wave Surfer" traditionally
*doesn't*refer to the capture of the data, it refers to how you generate the movement from the stats. "Wave Surfing" is any movement which has a movement that attempts to get to specific 'low danger' guessfactors as the wave passes, and by this definition does not specify whether 'low danger' is determined by hits or flattening stats, or even pattern matcher simulation. As far as the difference between surfing that logs hits verses logs one that logs non-hits equally? The difference is exactly the difference between a bullet-dodger and movement-flattener. That answer the question? --Rednaxela 04:14, 22 February 2009 (UTC)

- Well, I know of NO surfer that logs non-hitting waves EXCEPT for flattener purposes. Bufferfly is included in this statement. As far as terminology, the "Wave" in "Wave Surfer" traditionally

- Really? If that so, the statement on WaveSurfing/Tutorial should be wrong. It say like above. So now, my BlackHole will act like it always enabled its flattener, right? I am first confused by BasicSurfer code since it does not do exactly like reverse GF so I change that :) » Nat | Talk » 11:02, 22 February 2009 (UTC)

- Yep really. I'm not sure what you mean by "does not do exactly like reverse GF". --Rednaxela 17:47, 22 February 2009 (UTC)

- The point of wave surfing is to dodge enemy bullets. We cannot make the assumption that they have a strong gun, because there are many bots in the rumble with simple linear/circular/headon guns. So to avoid their bullets, we avoid GFs where we have found their bullets before. One way of finding their bullets is being hit by them, another is from bullet-hit-bullet. The only reason that one would need to dodge places where we have been, and not where they are shooting, is if they are adapting their shooting faster than we are adapting our movement. --Skilgannon 20:04, 22 February 2009 (UTC)

- Question 2
- How can I create a gradient color for wave like Phoenix does? My style of BlackHole are a bit ugly... :(

- You have to do math and work with the java.awt.Color class. For example:

Color rainbow = Color.getHSBColor(somenumber, 1, 1); Color gradient = new Color(255, somenumber*255, 255-somenumber*255);

- I suggest you experiment perhaps :) --Rednaxela 04:27, 22 February 2009 (UTC)

- Question 3
- What will act faster and less memory consume?

- Multiple buffers VCS stats with 16 segmentation.
- One Kd-Tree but difference dimension calculator.

- My new BlackHole v1 (not v2) will have around 1000 buffers and up to 16 segmentations. I ask here to develop my robot in right way.

- Compared to about 1000 VCS buffers? Definitely the Kd-Tree in that case. You could also consider an "interpolated VCS" approach like I explore in User:Rednaxela/SaphireEdge, it's rarther non-traditional but I got it working quite strong, and I think it's better in both memory and cpu requirements than many VCS buffers or a Kd-Tree. --Rednaxela 04:58, 22 February 2009 (UTC)

- What part do you want me to explain more? The interplated VCS thing? Also the statement "By default, a DC bot will slower but less memory consume, VCS usually faster but much more memory consume." on your page isn't really correct. A kd tree will not be faster than a
*small*number of VCS buffers, only faster than a very*large*number. And as far as memory consumption whie the DC uses less at the very very start of the battle it can grow larger than memory use of a small number of VCS buffers in as short as one or two rounds. --Rednaxela 17:47, 22 February 2009 (UTC)

- What part do you want me to explain more? The interplated VCS thing? Also the statement "By default, a DC bot will slower but less memory consume, VCS usually faster but much more memory consume." on your page isn't really correct. A kd tree will not be faster than a

- Yes, the interplated VCS. Actually, everything! I've read your User:Rednaxela/SaphireEdge page and get confused on what is interplated VCS? What is antialias? and many more. Also, I really mean a large VCS buffer on my user page. At nearly 100 buffers, up to 10 dimension each, containing 9999 bins a buffer. No ideas on how this run in time? I've no ideas, too

- Interpolated means spread out. So interpolated VCS is where you 'smooth' not only into nearby bins but also into nearby dimensions. --Skilgannon 20:04, 22 February 2009 (UTC)

- Well, it's not quite 'smoothing', as 'smoothing' would imply spreading it over many diferent data points, when interpolation means to only mix it between ones that the actual values of dimensions are directly inbetween. --Rednaxela 20:19, 22 February 2009 (UTC)

- To explain in more detail: the interpolated VCS works like this: Let's say for sake of discussion you have 1 dimension with 2 segments, one segment is centered on a value of 0 and the other centered on a value of 1. What do you do if the actual value is 0.5? Pretty much all previous VCS implementations will either round up or down in that case. The point of my "interpolated VCS" is to in that case, write to BOTH segments in that case, with half the value as otherwise added to each bin. What if the actual value is 0.75? What I do then is I add 0.75 to the bin centered at '1' and add 0.25 to the bin centered at '0'. Similarly, if you want to read from your data, and the actual situation is not exactly on the center of a segment, I mix data between in the same way. Note that this mixed reading is basically 'antialiasing'. I then extend this principal to multiple different axis of segmentation, which means that for a given situation I'd be writing/reading as many as 2^n different sets of bins, where n is the number of segments. This makes for far far more accurate VCS, allowing me to with a
**single**VCS buffer get scores comparable to DC or many VCS buffers. This does increase computation cost notably however takes no more memory than a single normal VCS buffer would, and the computation cost is still comparable to DC or multi-VCS-buffers that result in similar strength. --Rednaxela 20:19, 22 February 2009 (UTC)

- To explain in more detail: the interpolated VCS works like this: Let's say for sake of discussion you have 1 dimension with 2 segments, one segment is centered on a value of 0 and the other centered on a value of 1. What do you do if the actual value is 0.5? Pretty much all previous VCS implementations will either round up or down in that case. The point of my "interpolated VCS" is to in that case, write to BOTH segments in that case, with half the value as otherwise added to each bin. What if the actual value is 0.75? What I do then is I add 0.75 to the bin centered at '1' and add 0.25 to the bin centered at '0'. Similarly, if you want to read from your data, and the actual situation is not exactly on the center of a segment, I mix data between in the same way. Note that this mixed reading is basically 'antialiasing'. I then extend this principal to multiple different axis of segmentation, which means that for a given situation I'd be writing/reading as many as 2^n different sets of bins, where n is the number of segments. This makes for far far more accurate VCS, allowing me to with a

- Question 4
- What is the simple way to calculate bot width for surfing? DurssGT style is complicated. I'm now create 25px circle and calculate each bins it covered.

- The simple way? The 'simple' angular botwidth is just 2*arctan(18px/distance), convert to GF etc as you wish. Btw, "DrussGT style" was first used by Garm, then independtly rediscovered in RougeDC (I made some explaination [1] here), and then added in DrussGT. Other than those three however, EVERY bot I know essentially uses something like 2*arctan(18px/distance). Note, 36px is the width of the collision square of the bot. --Rednaxela 04:58, 22 February 2009 (UTC)

- Is you formula return a radians? My way is as simple as you can think without any knowledge on trig :) I project current bot position front and back by 25px (the distance from center to corner of bot) and convert it to GF using BasicSurfer's getFactorIndex() function. Using these as covered GF. Much simpler. Or you have any more ideas? » Nat | Talk » 11:02, 22 February 2009 (UTC)

- Yep, that formula returns a value in radians. As far as the trig: Picture a right-angle triangle, the right angle is on the far side from you and you want to calculate the angle: The line from the measured angle to the right angle is called 'adjacent', and the one far from the measured angle is called the 'opposite', and arctan works like this: "radianangle = arctan(opposite / adjacent)" by definition. But anyways, the getFactorIndex() approach isn't really simpler than the 2*arctan(18/distance) approach in terms of quantity of code it takes, and it's also a bit slower for the computer. Really, they'd give the exact same final result, except that the arctan method has less redundant calculation. In any case though, the getFactorIndex() approach is perfectly fine. I would however suggest that when calculating the covered gfs for any purpose
*except*surfing, not using 25px, because often the actual width is considerably less and I think that only in surfing is it best to err on the large side. --Rednaxela 17:47, 22 February 2009 (UTC)

- Yep, that formula returns a value in radians. As far as the trig: Picture a right-angle triangle, the right angle is on the far side from you and you want to calculate the angle: The line from the measured angle to the right angle is called 'adjacent', and the one far from the measured angle is called the 'opposite', and arctan works like this: "radianangle = arctan(opposite / adjacent)" by definition. But anyways, the getFactorIndex() approach isn't really simpler than the 2*arctan(18/distance) approach in terms of quantity of code it takes, and it's also a bit slower for the computer. Really, they'd give the exact same final result, except that the arctan method has less redundant calculation. In any case though, the getFactorIndex() approach is perfectly fine. I would however suggest that when calculating the covered gfs for any purpose

- OK, I have problem on converting between radians <-> GF <-> bin index. Does it use (radians/MEA * (BINS/2)) + MIDDLE_BIN? and ((INDEX-MIDDLE_BIN)/(BINS/2))*MEA? Also, I've seen many bot check their VB with 25px radius. Phoenix circle it's current target with radius 25px, too. (Not know in it's internal stats) » Nat | Talk » 18:20, 22 February 2009 (UTC)

- Yep, those radian <-> GF <-> bin index calculations are correct I believe. --Rednaxela 20:31, 22 February 2009 (UTC)

- If you want to be very precise, take the four corners of the bot (+-15 to x and y) and call getIndex on each. The reason I have a complicated method in DrussGT is because I have to account for the movement as the wave passes over the bot, since my precise prediction doesn't access the wave, or know where it is or what it does or anything. --Skilgannon 20:04, 22 February 2009 (UTC)

- Erm... I'm very sure it's 18, not 15, but otherwise yeah, that's a good method. --Rednaxela 20:31, 22 February 2009 (UTC)

- It's 18 actually... 13:48, 23 February 2009 (UTC)

- Then do max and min on these value to get covered guess factors, right? I've some idea on fancy bot-width using this now. Do this every turns that the wave intersect with bot, keep the old max/min in account, too. That shall result in the simplest of the fancy bot-width right now I think. Only one problem, it expensive :) » Nat | Talk » 13:48, 23 February 2009 (UTC)

- Question 5
- What is better:

- Surf the wave until it pass rear edge of the robot.
- Surf the wave until it pass middle of the robot.
- Surf the wave until it reach front edge of the robot.

- ?

- Well, ideally, you use a mix. What I do in RougeDC, is I use the crazy precice botwidth calcuation, and as the wave passes through the bot, I set guessfactors that already would have
*already*hit the bot to 0 danger, and keep surfing the remaining parts of the wave that aren't zero'ed out. If you're not using that kind of fancy botwidth though, I'd suggest near the middle, maybe leaning towards the front. --Rednaxela 06:01, 22 February 2009 (UTC)

- Well, ideally, you use a mix. What I do in RougeDC, is I use the crazy precice botwidth calcuation, and as the wave passes through the bot, I set guessfactors that already would have

- Well, that can happen, however usually if the bot is so close to a bullet that it would move onto it sideways, then it didn't really have a good idea where it was to begin with. Also, consider this: If you surf until it reaches the rear edge, then your bot may not get the front edge out of the way in time. I don't know any bots that do this, but one solution to make this situation better without using fancy botwidth calculations, is to when the wave is far away, only consider how far the bot can move till the wave hits the front, BUT once the wave begins to intersect the bot, start making calcuations with regards to when it would pass the rear edge. --Rednaxela 17:47, 22 February 2009 (UTC)

- I surf until the wave hits the front edge, and then take into account what the danger would be for me to start decelerating once it hits me. Out of all the options I've tried it worked best, and I have no idea why. --Skilgannon 20:04, 22 February 2009 (UTC)

## Round 2

- Question 1
- If I create WS-GT bot that almost has 0 velocity at fire time, will it act like StopNGo for LT and CT? If do so, I'll implements this in Galaxy... » Nat | Talk » 18:20, 22 February 2009 (UTC)

- Unless you have complete stop an fire time it's not quite good enough. After all my tweaking the Stop And Go with Waylander and later Toolkild this is one thing that has stuck with me. --Skilgannon 20:04, 22 February 2009 (UTC)

- OK, that seem to be clear for me. I've test with your BasicGTSurfer. Instead of removing 1 points, I removed 3. Now, test with David's LinearTargetingNot and CircularTargetingBot result them firing HOT in almost situation :) » Nat | Talk » 13:48, 23 February 2009 (UTC)

- When you have a velocity near 0 at fire time, it will act like Stop And Go for LT and CT (see for example Gruwel). However, the rigid and clean implementation of a real Stop And Go, like Skilgannon said, will be more effective. --GrubbmGait 22:24, 23 February 2009 (UTC)

## Round 3

- Question 1
- Drive Protection is designed to avoid moving close to enemy, right? It is (mostly) implements by divide danger by distance. Now, I come up with some corner avoidance. if we divide danger by
`Math.max(dist2wallN, dist2wallS) + Math.max(dist2wallE, dist2wallW)`

. Will it avoid getting cornered? (PS. I'm writing the test bot now) » Nat | Talk » 03:59, 2 April 2009 (UTC)- Well I don't have any similar implementation for distance protection, so I pulling ideas out of my head only. But I would guess it makes more sense to use
`Math.min(...)`

instead of`Math.max(...)`

. - Another thing is that I usually don't like additions for something like that. But I have no ideas to help out there, try it and see. Tweak it using multiplication, or dividing danger against the North/South distance on one side and against West/East on the other and them add those results instead.
- I really have no idea what could be better, but maybe you can try some and see which gives you better results. But as you have it I believe the center of the field is more dangerous than the corners. In a 800x600 field, assuming danger as 1 always.

- 1 / (400 + 300) = 0.001... for the center of the field.
- 1 / (782 + 582) = 0.0007... for the lower left corner (18, 18)

- Well I don't have any similar implementation for distance protection, so I pulling ideas out of my head only. But I would guess it makes more sense to use

Hope it helps/ --zyx 05:04, 2 April 2009 (UTC)

- Oh wait! It should be min, not max :-) So lower left should have danger of 0.027.... I'm now think of multiply of each min dist squared. For that way distance protection, I believed it was first use in Dookious, then Komarious. Also DrussGT. Thanks for your comment. » Nat | Talk » 05:31, 2 April 2009 (UTC)

- Yes, with min it is better for sure :). But it will in my opinion it will avoid walls too much, and being close to a wall, but
*parallel*to it isn't so bad I believe. Maybe using the angle to the wall can be helpful also, I would only divide if say both min wall distances are below some threshold, so it won't try to keep aways from a wall instead of corners. --zyx 06:46, 2 April 2009 (UTC)

- Yes, with min it is better for sure :). But it will in my opinion it will avoid walls too much, and being close to a wall, but