For my 5th KOTH, I present to you a challenge based on the well-known game Battleship with a few twists. You'll only command one ship, whose type you'll be able to select between the 5 "traditionnal" classes, but you'll be able to undertake multiple actions each turn, including moving! This is played as a FFA (Free For All) and your goal will be to be the last ship standing.
The game is turn-based. At the start of the game, you'll have to choose the class of your ship. Then each turn, players will be able to execute several actions depending on their ship.
The game takes place on a 2D grid (X, Y) whose side is defined this way :
X = 30 + numberOfPlayer
Y = 30 + numberOfPlayer
The starting position of each ship is random.
Play order is randomized each turn, and you won't know your position in the "queue" nor the number of players. The game lasts for 100 turns or until there's only one ship left alive.
Each time you hit an enemy ship or get hit, you'll earn or lose points. The player with the highest score wins. A bounty will be awarded to the winner (value depending on the number of participants).
The controller provides you with input via command arguments, and your program has to output via stdout.
Your program will be called once without any argument. You'll have to ouput an integer between 1 and 5 (inclusive) to select your ship :
1 : Destroyer [length: 2, moves/turn: 3, shots/turn: 1, range: 9, mines: 4]
Skill : Free ship rotations (no cooldown)
2 : Submarine [length: 3, moves/turn: 2, shots/turn: 1, range: 5, mines: 4]
Skill : Can Plunge/Surface (see outputs). While underwater, you can only use "Movement" actions and can be seen only with a scan. You can't be hit by a shot, but can take damage from mines.
3 : Cruiser [length: 3, moves/turn: 1, shots/turn: 2, range: 9, mines: 2]
Skill : Can Repair (see outputs)
4 : Battleship [length: 4, moves/turn: 1, shots/turn: 3, range: 7, mines: 1]
Skill : Can Shield (see outputs)
5 : Carrier [length: 5, moves/turn: 1, shots/turn: 1, range: 7, mines: 3]
Skill : Shots deal AOE (Area Of Effect) damage to target (1 range splash damage). If the target is hit with the shot, up to 2 cells of this ship will also be damaged.
Each time your program is called, it will receive arguments in this format:
Rounds are 1-indexed.
Here, it's the 1st round, you're player 8.
Your ship is positioned on (X = 1, Y = 12) and your direction is toward the top (0 = Top, 1 = Right, 2 = Bottom, 3 = Left).
Your hull is not damaged (your ship has a length of 3, and each bit is true [1 = OK, 0 = Damaged]). You can move 1 time, shoot 2 times, have 2 mines left and your "skill" is available (cooldown = 0).
You didn't hit anything, nor have sunken any ship and you didn't get hit either.
You're not underwater, your shields (if any) are not activated and your scan isn't either.
More on the map later...
You have to output a String describing what actions you'll execute this turn. The order of the characters in your output String will define the orders of the actions. You can output the same actions multiple times if it doesn't exceed the limits of your ship. If one or multiple actions is invalid, each one will separately be considered as
W. Here's the list of available actions :
M : Move 1 cell in the direction you're facing (consume 1 move)
B : Back 1 cell from the direction you're facing (consume 1 move)
C : Rotate your ship clockwise (consume 1 move / free for Destroyers)
K : Rotate your ship counterclockwise (consume 1 move / free for Destroyers)
A : Ram your ship in the direction you're facing (works only if another ship is occupying the cell in the direction you're facing / doesn't move your ship / consume all moves)
F : Fire 1 shot to a cell in range (consume 1 shot). Must be followed by the targetted cell in this format ([+-]X[+-])Y / example :
N : Place 1 mine to a cell adjacent to your ship (consume all shots and 1 mine). Must be followed by the targetted cell in this format ([+-]X[+-])Y / example :
S : Activate your scan for the next turn (consume all shots)
R : Repair the damaged hull the closest to the "head" of your ship (consume all shots, cooldown = 3 turns / Cruiser only)
P : Plunge/Surface (consume all shots, cooldown = 3 turns, max duration = 5 turns / Submarine only)
D : Activate your shield preventing the next damage during your next turn (consume all shots, cooldown = 3 / Battleship only)
W : Wait (does nothing)
Clarification: "Consume all moves/shots" means you can only use this action if you have not used any of your moves/shots before during this turn.
MF+9-8CM : Moves 1 cell, then fires on the cell whose relative position to the "head" of your ship is (targetX = X + 9, targetY = Y - 8), turns clockwise and finally moves 1 cell again.
Here's an example grid (33 x 13) where 3 players are placed :
███████████████████████████████████ █ █ █ 00 █ █ 2 █ █ 2 █ █ 2 █ █ █ █ 11111 █ █ M █ █ █ █ █ █ █ █ █ █ █ ███████████████████████████████████
As we can see, there's also a Mine
M right next to the player 1.
Let's take player 2 to understand positioning and direction :
Player 2's position is X = 3, Y = 4, Direction = 3. Since its direction is "Bottom", the rest of his "ship cells" are positioned "over" its "head" (X = 3, Y = 3) & (X = 3, Y = 2)
The last argument each players receive is their "own" map. By default a ship detects everything in a range of 5 cells, but it can activate a Scan to increase this range to 9.
The argument is always 361 (19 x 19) characters long. It represents the square centered around the "head" of your ship, where each character corresponds to an element defined this way :
. : Empty cell
O : Your ship
M : Mines
X : Wall (cells out of the map)
U : Unknown (will be revealed by a scan)
A : Enemy ship undamaged cell
B : Enemy ship damaged cell
C : Enemy ship underwater undamaged cell (only seen with a scan)
D : Enemy ship underwater damaged cell (only seen with a scan)
W : Wreckage (dead ship)
The string is composed of 19 characters of the first line, followed by 19 charcters of the second lines ... until the 19th line.
Lets take a look at what player 2 receives with and without a scan (line breaks for better understanding, but not send to players) :
XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXX............. XXXXXX.......AA.... XXXXXX...O......... XXXXXX...O......... XXXXXX...O......... XXXXXX............. XXXXXX.......AAAAA. XXXXXX........M.... XXXXXX............. XXXXXX............. XXXXXX............. XXXXXX............. XXXXXX............. XXXXXXXXXXXXXXXXXXX UUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUU UUUUXXXXXXXXXXXUUUU UUUUXX.........UUUU UUUUXX.......AAUUUU UUUUXX...O.....UUUU UUUUXX...O.....UUUU UUUUXX...O.....UUUU UUUUXX.........UUUU UUUUXX.......AAUUUU UUUUXX........MUUUU UUUUXX.........UUUU UUUUXX.........UUUU UUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUU
The mines are triggered when a ship moves to a cell occupied by a mine or when a shot is fired on the mine. Mines can't be triggered with the action "Ram".
Mines deal AOE damage (1 range splash damage) to everyone, even to the person who placed the mine. Mines can trigger "chain" explosions if another mine is in the radius of the explosion.
The rotations are central symmetries centered on the ship's "head". Rotations will only trigger a mine if it is placed on the "destination position" (you won't trigger mines in an arc.
Area of effect
1 range splash damage (for mines and Carrier's shots) is defined by a 3x3 (9 cells) square centered on the initial shot/explosion (x, y). It hits those coordinates :
[x - 1; y - 1],[x - 1; y],[x - 1; y + 1],[x; y - 1],[x; y],[x; y + 1],[x + 1; y - 1],[x + 1; y],[x + 1; y + 1]
The scoring is defined by this formula :
Score = Hits + (Sunken x 5) - Damage taken - (Alive ? 0 : 10)
hits : number of hits on enemy ship, either by Ram, Shot or Mine explosion (1 hit by enemy ship cell damaged, including chain explosions)
sunken : number of "last hit" on an enemy ship which caused it to sink
damage : number of hits received (not decreased by Repair, but prevented by Shield)
alive : checks wether your ship is alive at the end (at least 1 hull cell undamaged)
You can find the controller on GitHub. It also contains two samplebots, written in Java. To make it run, check out the project and open it in your Java IDE. The entry point in the main method of the class Game. Java 8 required.
To add bots, first you need either the compiled version for Java (.class files) or the sources for interpreted languages. Place them in the root folder of the project. Then, create a new Java class in the players package (you can take example on the already existing bots). This class must implement Player to override the method String getCmd(). The String returned is the shell command to run your bots. You can for example make a Ruby bot work with this command : return "C:\Ruby\bin\ruby.exe MyBot.rb";. Finally, add the bot in the players array at the top of the Game class.
- Bots should not be written to beat or support specific other bots.
- Writing to files is allowed. Please write to"yoursubmissionname.txt", the folder will be emptied before a game starts. Other external resources are disallowed.
- Your submission has 1 second to respond.
- Provide commands to compile and run your submissions.
- You can write multiple submissions
I'll try and support every language, but it needs to be available online for free. Please provide instructions for installation if you're not using a "mainstream" language.
As of right now, I can run : Java 6-7-8, PHP, Ruby, Perl, Python 2-3, Lua, R, node.js, Haskell, Kotlin, C++ 11.