6
4
Your task here is to write an AI for a simple robot battle. The class to be implemented is provided at the bottom of this post, and source of the controller can be found here.
Requirements
- Write a class which implements the abstract Bot class, provided at the bottom of this post
- You must provide a 0-argument constructor, this must change the value of the Name field, but may not change any other inherited fields
- Outside of the constructor, you may not change any of the inherited fields in any way
- Your action method should, when called (it will be called once per turn cycle, with a copy of the 64 by 64 map as its argument), return one of the Action enum fields:
UP to move up (towards y=0) DOWN to move down LEFT to move left (towards x=0) RIGHT to move right MINE to plant a mine and then move a random direction PASS to pass
- Within the passed map, 0 represents an empty cell, -1 represents a mined cell, and anything else denotes a cell occupied by a bot (each bot will be represented by its unique bot_id, you can get your bot's id by calling this.id())
- A bot is eliminated in any of the following situations:
- It moves out of the map
- It moves into a cell occupied by a mine
- Another bot moves into the cell it currently occupies
- Its action method takes more than 50ms to respond
- Its action method throws any exception that is not caught within its own bounds
To win
Have your bot be the last bot standing!
Additional Rules
The round is not allowed to last more than 1,000 turn cycles. If, after the 1,000th turn cycle, more than one bot is still standing, all of the surviving bots are considered to have tied that round.
Each time a new bot is submitted, it will, as soon as possible, be pitted in two two-bot, three three-bot, and three-four bot rounds; each time against randomly selected opponents.
Scoring
total score=1000*(wins+(1/3) ties - (1/12) losses)/roundsPlayed
The exceptions to this are that any bot that has played at least one round that it didn't lose is guaranteed at least one point, and no bot may have a negative score.
The class to be implemented:
import java.util.*; public abstract class Bot { public static enum Action{ UP,DOWN,LEFT,RIGHT,MINE,PASS; } public static final class Position{ public int x; public int y; public String toString(){ return "("+x+","+y+")"; } public double distance(Position p){ int dx=p.x-this.x; int dy=p.y-this.y; return Math.sqrt(dx*dx+dy*dy); } public Position(int x,int y){ this.x=x; this.y=y; } } public String toString(){return name;} public Position p; public String name=""; public abstract Action action(int[][] map); private int bot_id; public final int id(){return bot_id;} public final void register(List<Bot> a){ a.add(this); bot_id=a.size(); } }
Leaderboard
The full match log may be read here
ProtectiveBot (6 wins, 6 ties, 1 loss)- 609 points Albert (2 wins, 8 ties, 0 losses)- 467 points Frozen (1 win, 8 ties, 0 losses)- 407 points Cocoon (1 win, 3 ties, 3 losses)-250 points Wanderlust (0 wins, 3 ties, 5 losses)- 73 points MineThenBoom (0 wins, 2 ties, 11 losses)- 1 point PatientBot (0 wins, 0 ties, 13 losses)- 0 points
Sample Bots
Simple Pathfinder: http://pastebin.com/raw.php?i=aNBf00VU
RandomBot: http://pastebin.com/raw.php?i=VD8iGaHC
Minelayer: http://pastebin.com/raw.php?i=sMN1zSa0
2Maybe you could remove the Java restriction by changing the output to a letter (i.e,
UDLRMP
for up, down, left, right, mine, pass) and accepting that output as input to the controller. Only the first byte is read, and anything other than one of those six commands is counted as pass. (Just an idea, personally, I've never coded a KOTH controller.) – ASCIIThenANSI – 2015-04-13T14:23:00.470>
@SuperJedi224 OK, then. Where will the results of the matches be placed, or is the leaderboard all we will see? – ASCIIThenANSI – 2015-04-13T15:44:32.013
Why does your position class use the euclidean metric? Because of the way movement works, it would make much more sense to have the distance method return the taxicab distance rather than the euclidean distance. – AJMansfield – 2015-04-13T18:27:29.790
I want to let you know I've updated my bot (apparently it always laid down mines). Also, can the logs say whose mine blows up bot X? – ASCIIThenANSI – 2015-04-13T20:59:21.120
No, not at present. – SuperJedi224 – 2015-04-13T21:22:31.553
1@ASCIIThenANSI a while back I coded a wrapper for a java-only contest, so other entrants could just output to stdout. It wasn't very popuar :( – Sparr – 2015-04-14T04:15:29.853
1I think you need to adjust the tournament to run a lot more rounds. This is a contest with a high standard deviation of results.
Also, every bot should be in the same number of rounds, and the same number of 3 and 4 bot rounds, to keep it fair. – Sparr – 2015-04-14T14:21:25.443
Is that better? – SuperJedi224 – 2015-04-14T15:40:37.890
How do I use the controller? I would like to test my bot before submitting it. – ASCIIThenANSI – 2015-04-14T15:49:39.127
I just run it from Eclipse usually. The source code for the controller does indicate which part of it to edit. – SuperJedi224 – 2015-04-14T15:51:38.260
You'll still need a lot more competitions. The start location is random, and 9 bots currently competing (3 samples, 6 answers), so for a given bot in a two-bot battle, there are (64 * 64) positions it could start, (64 * 64 -1) positions its opponent could start, and 8 possible opponents, meaning there are 134184960 possible battles. Bot score is based on only 2 of them. – Wasmoo – 2015-04-14T16:47:38.663
How to split the bots up for matches is a complicated question, but however you do that, I think each bot should be playing in something like 100 matches, not 3-6. – Sparr – 2015-04-14T20:09:36.070
Yes, but where do I put the bots, the class
Bot
, etc.? I tried stuffing it all into one file, and it didn't work. So how do I split it up? – ASCIIThenANSI – 2015-04-15T02:06:31.277Each class definition goes to a seperate .java file with the same name as the class – SuperJedi224 – 2015-04-15T02:07:49.620
I think there is something wrong with how mines are represented. I used some code from the Minelayer, and checked to make sure it would never walk into a mine, and it did anyway. I am assuming mines are represented by -1. – ASCIIThenANSI – 2015-04-16T19:08:58.003
@ASCIIThenANSI They are. Honestly, I'm not sure where the problem is, but I'll see if I can figure it out. – SuperJedi224 – 2015-04-16T20:17:49.523
@SuperJedi224 Maybe it's storing mine coordinates wrong, for instance, the map that the bot has isn't the same controller has. – ASCIIThenANSI – 2015-04-17T13:56:53.013
@SuperJedi224 I believe I've found the problem. Around line 54 of you're controller, you write
Bot.Action s
. I assume this sets the bot's action tos
. But shouldn't that bes = Bot.Action(map)
, to set the bot's action (given the map as an argument) tos
? – ASCIIThenANSI – 2015-04-17T15:41:32.623No, that line means that variable
s
has typeBot.Action
. The line that gets its value is a few lines down. – SuperJedi224 – 2015-04-17T16:06:50.367Never mind looking for the bug, there was a typo in my bot. – ASCIIThenANSI – 2015-04-17T18:01:43.347