Program tanks to wipe out the opposition. This is a great little game
for teaching the fundamentals of programming. Make sure you visit the Official Site to download the
program and so you can contact Scott and tell him what a good program this
Since I still don't get a link off of the Official Site, I have decided
to put my hacking tool online! Feel free to decrypt
other people's robots!
- Bots that I Wrote
- I left them all unprotected. There's no point in hiding the code.
- Wal-Mart - Just shoots the walls.
When I first started playing GarBots, too many bots hung out around the
- Maz - Drives around and shoots randomly
around the arena. Also tends to pick on things hanging out near walls.
- Path - A pool vacuum gave me the idea to
create a robot that just drove in straight lines, killing things in front of
it. It turns when it hits a wall. Sometimes it gets hung up near corners,
but it usually gets out before dying.
- Testing Robots
- These are just simple robots that you can use to spruce things up or to
help you out with finding information.
- Bugbot - Illustrates the FIRE bug. It
just shoots off the screen and everyone dies.
- Count and Count2 - They work in conjunction to provide
timing information. Replace the comment in Count with the code you want to
test, then run Count and Count2 in a battle with the Battle Speed at 1. The
last line you see is the amount of time the command took.
- Minimum Radius - Checks to see
what radius truly can kill you. DAMAGERAD is just a bit too small when
dealing with integer math. See the code snippet above for my calculation.
- Moving Drone - Hmmm. A moving
- Other "Open" Bots
- K-Drone - Emailed to the GarBots
mailing list by cozmikforz. Provided here as a file so that nobody needs
to actually type in the code by hand. Drives around and shoots. Very
similar to Fleeter by Rudi.
- Modified Bots
- These are bots that I modified to run faster and be more aggressive.
Some I also fixed a bit. Code is protected (as they were originally).
- Cruiser2 - Originally from Rudi's Site. I combined
multiple assignments and moved some math into the scan line.
- Death Tank 4 - Originally from the
Official Site. I removed
GOSUB functions, and made the scan randomly pick the direction to get some
robots that would have been missed.
- Fleeter 2 - Originally from Rudi's Site. Very hard to
improve on this little guy. I made it so that it couldn't hurt itself, and
I made the first shot come off a little faster.
- Lord of the Rings 2 -
Originally from Rudi's
Site. A very nice robot. I made it not ever be able to damage itself,
removed GOSUB functions, had it initially drive to its starting spot without
starting in the center, and sped it up a bit. Excellent concept!
- Smack Down 2 - Originally from the
Official Site. I removed
the GOSUB functions, unnecessary assignments, and made the first shot fire
- Sniper 2 - Originally from Rudi's Site. I made it pick
a random direction, removed the WHILE loop around the program, combined
assignments, removed GOTOs (which were used like GOSUBs), and corrected the
program to think that the target is on the other side if a sub-scan missed
its mark. Works great against non-moving drones.
- Off-Site Links
- Official Site - You
have to go here.
- Rudi's Site - Several
tough bots to kill. A few were modified by me to be a bit faster.
- Yahoo GarBots Group
- Some messages, some files, some links. Nothing too fancy, but you have to
be a member before you can even see the message archive.
If you want, you can also download all of the above robots in one zip file.
As much as I don't want there to be any bugs in the program, there are a
few. However, Scott told me that several of these will be addressed in the
next release and more will be fixed later.
- Scan should scan a full radius, not just a triangle. I
don't care if the picture just shows a triangle, I want to actually scan the
full distance. I submitted some code to do this, and it should be fixed in
the next release.
- Shoot off the screen. Everyone dies. See "Bugbot."
Problem is fixed in the next release.
- Random Numbers
- The RAND function doesn't work as expected. To
counter the problem, I have a snippet of code in my Code Snippets section.
This should be fixed in the next release after 1.4.1.
- Damage Radius
- This works fine when you shoot in a N/S/E/W direction.
If you do any other angle, you're going to get hurt. To counter this
problem, I have another snippet of code that will work for you. This is due
to integer math. This should maybe get fixed in the code, so that bots
that are 6.00001 away don't get hurt. That just relies upon a better
distance function, which I submitted.
- It would be nice if >=, <=, and != (or <>)
were supported. This should be implemented in the next release after
- Auto Off
- Not only is there a spelling error next to the "Disable
Auto Off" checkbox, but it also doesn't work. Scott is working on this.
- The scrolling in the editor only scrolls one line at a
time. Additionally, the scroll bar is not updated properly after pasting in
information, causing a headache when I put in large amounts of code and then
I want to go to the end of the program. Scott is working on this. I also
suggested an optional smaller font so that I could see more code on the
- Math Functions
- SIN, COS, TAN, and ATAN are provided. It would
be nice to have the inverse of these functions available as well. That way
I could figure out how wide of an area to scan based on DAMAGERAD. a = 2 *
(INVSIN (DAMAGERAD / SCANRAD)) This may be implemented in the next
release after 1.4.1.
I have tested the various commands and figured out how long they take to
run and how long each tank has for each turn. Below are my findings.
Each robot is processed in the game alphabetically.
Therefore, if your robot comes alphabetically before the other robots, you
have an advantage. From there, each robot has five ticks, for a lack of a
better term. A tick is like a second. It's the smallest unit of measurable
time that I found.
|Linefeeds||1||Try to not have blank lines in your
|Comments||0||Comments sharing a line are good. If
they are on a separate line, the linefeed counts against them.|
||Equal amounts of time. Maybe just lobbing bombs is
good enough, if you just want to possibly hit a target. Scanning an area might
get you a robot, but the robot could move before you get a shot
|SCAN, A = SCAN||10|
||Print statements cost you time because of the linefeed.|
|Assignments (A = ...)||0
||The "A =" part is free. It's the other side that gets
you. So, for A = 2, the "A =" is free, the "2" costs you 1.|
|Calculations (2, 5-7, 2*arenax)||1|
|WHILE, IF, FOR||1
||It takes an equal amount of time to jump to the true
secion of an IF statement as it does to jump to the ELSE section or to jump
directly to the ENDIF section. Mmmmm. Logic good.|
|ELSE, NEXT, ENDIF||0|
||Test your code thoroughly. Make sure you keep logging
on to catch errors and fix them before battling your bot against
|GOTO, GOSUB, RETURN, Labels||1
||GOSUB and RETURN each cost time, so it is better for
your time if you just copy and paste instead of calling a subroutine. I
understand that it is easier to call a subroutine. Just optimise it before
you distribute it. Because labels also cost time, you should avoid them.
If I want to return to my beginning WHILE loop in my program, I replace the
WHILE with a label and just GOTO it at the end of the loop and at wherever I
want to return to the beginning of the loop.|
||Conversion to/from polar costs time. Perhaps you
could keep everything in polar instead of using coordinates. Also, using
POSX and POSY are a bit expensive, so maybe you could keep track of your
position and just move N/S/E/W to make the whole movement thing
||Nearly useless. By the time you realize that you're hit and your
motor starts moving from the expensive startup cost of DRIVE, you're likely
to be hit again, and therefore dead. Also, since you can't say if z <
DAMAGE() to shorten things up, you're stuck spending another couple
ticks before you can realize that you're hurting.|
|DRIVE||5 + (dist / drivestep)
||The (dist / drivestep) is rounded up.
Driving short distances is REALLY spendy. For peak
performance, I'd suggest you drive a multiple of drivestep with each DRIVE
Each tank gets 5 ticks to do whatever they can, then the other tanks get
their turn. If a command goes over your 5 tick boundary, it does get
executed, but it will take you a while before you can go again. Let's say a
FIRE command is the first line in your program. When your tank
gets control back, you will be able to eventually run 4 PRINT
commands or something.
When figuring out the cost for a line, take 1 for the linefeed, plus the
cost for whatever else is on that line.
A list of things that I have learned (via trial and error) is provided
here for your amusement.
- Comments and functions are good, but use up time.
- Having a counter to decide which way to scan works well, but it uses up
time. You can randomly pick a side to scan faster.
- X and Y coordinates are great for driving and shooting, but polar don't
need to be converted.
- Good coding techniques are punished. Cut and paste instead of having
- Shoot fast, shoot often.
- Damage extends past DAMAGERAD at angles.
- SCANning an area is faster than trying to shoot the entire area.
- Two direct hits at the default settings will wipe out a robot.
- Blank lines are your enemy.
- A lingering robot is a dead robot.
Below are a few code snippets that you can use in your programs if they
help you out.
' Code snippets -- Feel free to use
' Get a random 1 or 0 -- counters the RAND issue mentioned above
r = (rand 100) / 50
' Due to integer math, this is the closest you can fire
' at an arbitrary angle and not get damaged at all.
' I usually add one to this number, just in case.
' See Minimum Radius bot below for proof
d = sqrt (2 * damagerad * damagerad))
' To use it, you can do something like this
s = scan (a - 10) (a + 10)
if s > 0 then
f = fire a (max s d)
while f > 0
f = fire a (max s d)
' How to fire at robots. A comparison. The good way is
' just a little faster and a little safer. Remember to
' remove comments in your program for the sake of speed.
' Bad way ' Good way
a = rand 360 a = rand 360
b = a - 10 s = scan (a - 10) (a + 10)
c = a + 10 if s > 0 then
s = scan b c f = fire a (max damagerad s)
if s > 0 then while f > 0
f = s f = fire a (max damagerad s)
while f > 0 next
fire a s endif
next ' You can replace damagerad with d
endif ' if you use the snippet above