Melee Strategy - Understanding Gruweltje (and Gruwel)
This tutorial is focussed on Gruweltje, as it is the lean and clean variant of Gruwel, which has a lot of outcommented code in it. If necessary, the differences between the two are mentioned. Any direct references I make to code will be from Gruweltje 0.2 or Gruwel 0.1. The format for this page is lent from Kawigi.
I do not see Gruweltje
as a specific meleebot, because the only melee-specific thing it has is its radar. It is a very good melee-capable bot and that it performs so well in melee is only due to the fact that there are not many melee-specific bots out there.
only has a main robot class, while Gruwel
also has a Scan class. This is a remnant of the teamcode of Troodon
and I am too lazy to replace it. Only the basic things (name, position, distance, energy) are kept here.
the few global variables are pretty self-explanitory (and the code is commented). The 'oldheading' is needed for the targetting to calculate at which curve the target is moving.
Gruwel uses a lot more globals, most of them for wallavoidance and some for locking and scanning.
does two radarsweeps at startup, and thereafter only performs a sweep after firing. It uses a simple nano-style radarlock in between. When it finds a more attractive target, it locks immediately without finishing the sweep. When no more-attractive target is found, it locks again on its current target. The radarcode can be found in line 52 and 154.
Gruwels radar is a bit more complicated, but seems less effective. It does one sweep at startup, it always finishes the sweep before locking onto the (new) target, and it also has a timeout of 20 ticks for a sweep. See line 130-142 and 216. (Note that I have a development version with improved radar and 100 bytes spare which performs slightly better.)
Both bots share the same movement except for near-wall handling. The normal movement is a double oscillator (see Oscillators
) with a small random element added. During a radarlock the movement is purely perpendicular, but during a sweep this is not possible. This gives the movement a small 'hick-up' which is barely noticable, but gives about 10-15 points in one-on-one.
Gruweltje bounces of the wall without touching it, and can get stuck in corners. The complete movement code can be found in line 59-70 and line 99.
Gruwel uses a wall-smoothing technique which checks for two sides if the BlindMansStick or remaining distance (whichever is shorter) fits within the battlefield. If not, the angle is increased with 5 degrees and checked again until it does fit. Furthermore Gruwel will bounce when hitting another bot.
The attractivity of the target has a one-on-one relation to the distance. Gruweltje
only switches targets when the new target is 20% closer, except when the current target is closer than 70 pixels, see line 87-96. Gruwel
gives an additional 25% attractivity when the target has less than 20 energy left, hoping for the finishing blow, see method doChangeTarget?
(). Both bots override the onRobotDeath?
method to mark the current target very unattractive.
The aiming and firing is done in the OnScannedRobot
method. Both use a quite simple iterative circular targetting gun. Whenever the next calculated point is outside the battlefield, the bulletpower is adapted to intercept the target at the previous point. This still gives a change of hitting the target regardless if it bounces or does wallsmoothing. If the calculated point can't be reached in time by a 0.1 power bullet, Gruwel
will hold its fire. The code can be found in Gruweltje.java at line 113-146
The initial bulletpower is: 3.0 at < 250, 1.9 at < 700, 0.5 at < 850 and 0.1 at > 850. Furthermore both will adapt bulletpower just enough to kill the target or max 1/5 of its own energy. This leaves room for enemies to rise from the grave but I think it is the most efficient. Both will fire until it is not possible anymore without disabling themselves. Due to the nature of the movement, most of the time a power 1.9 bullet will be fired and this seems quite effective.
One question remains: How is it possible that both bots perform so well in melee?
While most good meleebots try to get far away from the others, it does not matter to Gruweltje if it is close to others or not. While being close or at midrange, it can take advantage of its gun which is at its best at closerange and midrange.
When looking at the details of the RobocodeLittleLeague, two things catch the eye:
- the inflicted bulletdamage is the highest
- relatively low number of 2nd and 3rd places
This indicates the scenario below when following the different stages of a meleebattle.
7-10 bots on the battlefield: Hitting and killing alot of 'simple' bots, because most of them are close enough.
4-6 bots on the battlefield: The better meleebots are in place and although Gruweltje still hits alot, its location is probably not so good. Relatively it is killed most in this stage.
2-3 bots on the battlefield: The better one-on-one performance of Gruweltje against the remaining good meleebots gets the upperhand here, resulting in high number of first-places and lower number of second and third places.
You see, it is possible to create a good meleebot without specific melee-movement, see also DoctorBob. As long as you have an efficient radar, a good gun and an adequate movement, you can get far. As soon as more melee-specific bots enter the competition, Gruweltje and Gruwel will not be able to keep their position.
Don't forget target selection. I'm sure these bots would also go down significantly (particularly in the bullet damage area maybe) if they didn't normally target the closest enemy. -- Kawigi
You're right. Selecting the most attractive enemy (mostly the closest) is important. The point I want to make with this page is that you must have a well-suited combination of radar, gun, movement en target selection to make a competitive meleebot. I have the feeling that fitting my gun into for example Coriantumr will not do significantly better than Gruweltje itself, because my gun (close and midrange) and your movement (getting far away) do not support eachother. -- GrubbmGait