BotNets KotH
king-of-the-hill javascript grid
Controller, Example and Submission Template now added
flavor text not yet written
This is a web-based JS KotH where submissions have 2 parts, a Worker Bot and a Controller Bot. The goal is to have the most gold at the end of the game, by killing other bots and collecting gold found on the grid, while navigating the grid and surviving.
Worker Bots
A Worker Bot is a class(ES6 or ES5) based on this format:
class YourWorkerBot extends WorkerBot {
performAction(message) {}
sendMessage(x, y, surroundings) {}
}
Each botnet has 20 Worker Bots. For every botnet, its worker bots are
Method Descriptions:
constructor(index)
: sets the color that the controller displays the bot as
performAction(message)
: returns an action(described below).
sendMessage(x,y,surroundings)
: x
and y
are zero-indexed coordinates. surroundings
is a flat array of the 5x5 area around the bot. returns message(string) to send to controller bot
Actions
Each move is formatted as a 2 element list([action, param]
) where action
is a string
- Movement: formatted as
["move", square]
where square
is an integer that represents the square you want to move to, using the same index as the surroundings
object. You can only move one square orthogonally or diagonally. Moving onto a square with a coin will collect the coin.
- Kill: formatted as
["kill", square]
where square
is an integer that represents the square you want to attack, using the same index as the surroundings
object. You can only kill a bot one square orthogonally or diagonally. If you kill a square with no bot, you do nothing. You get half the coins(rounded down) of the bot you attacked.
- EMP: formatted as
["emp",undefined]
. It causes all bots including itself in the 7x7 surrounding area can't move next turn. This costs 3 coins.
- Any invalid action is treated as you doing nothing.
Surroundings
The surroundings
object will be a flat array of the 5x5 area around you, starting from the top left corner and going left to right and top to bottom. The grid below shows how the indexes of the array map to the actual grid area. Each square will be either a string, where "B" is a bot, "C" is a coin, "E" is an edge(not a valid move target) and "" is empty.
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
Controller Bot
A Controller Bot is a class(ES6 or ES5) that extends the following class:
class YourControllerBot extends ControllerBot{
constructor(locations){
super(locations)
this.storage=""
}
sendMessage(messages,index){
return ""
}
}
Each botnet has only 1 Controller Bot.
Method Descriptions
constructor(locations)
: locations
is an array of the initial locations([x,y]) of the worker bots.sets initial storage value
sendMessage(messages,index)
: messages
is a list of lists of the messages sent by all the worker bots(not just your own), always in the same order and grouped by botnet. returns message to its worker bots whose index is index
.
The Game
The arena will be a 100x100 grid with 100 random coins scattered around it. Each game will have 1000 rounds and will have up to 15 randomly selected botnets. Every round, 10 coins will spawn at a random unoccupied spot. Every worker bot will get 1 turn per round. Each botnet's worker bots will perform an action in the same order for the entire game, but the order in which botnets take turns is randomized every round. Every turn, all the worker bots' sendMessage
methods will be called(not just the worker bot taking the turn). After that, the controller bot's sendMessage
method will be called. Finally, the worker bot's performAction
method will be called and the action will be executed. This will repeat for every worker bot in a round.
Scoring
Each botnet's score is the sum of the coins collected by each of the worker bots. Botnets are ranked by most score.
Controller(WIP)
https://botnets-koth.firebaseapp.com
Example
function sampleBotnet() {
class SampleControllerBot extends ControllerBot {
constructor(locations) {
super(locations);
this.storage = "";
}
sendMessage(messages, index) {
let surrondings = messages.find(message => message[0] === index)[1];
let otherBot = surrondings.findIndex(
(square, i) =>
square === "B" && [6, 7, 8, 11, 13, 16, 17, 18].includes(i)
);
if (otherBot !== -1) {
return ["kill", otherBot];
}
let coin = surrondings.findIndex(
(square, i) =>
square === "C" && [6, 7, 8, 11, 13, 16, 17, 18].includes(i)
);
if (coin !== -1) {
return ["move", coin];
}
let validMoves = [6, 7, 8, 11, 13, 16, 17, 18].filter(
x => surrondings[x] === ""
);
return [
"move",
validMoves[Math.floor(Math.random() * validMoves.length)]
];
}
}
class SampleWorkerBot extends WorkerBot {
performAction(message) {
return message;
}
sendMessage(x, y, surroundings) {
return [this.index, surroundings];
}
}
return {
name: "SampleBotnet",
color: "red",
controllerBot: SampleControllerBot,
workerBot: SampleWorkerBot
};
}
#Submission Template
```javascript
/* eslint constructor-super:0,no-this-before-super:0,no-unused-vars:0*/
import ControllerBot from "./src/scripts/ControllerBot.js";
import WorkerBot from "./src/scripts/WorkerBot.js";
//copy the part below
function yourBotnet() {
class YourControllerBot extends ControllerBot {
constructor(locations) {
super(locations);
this.storage = "";
}
sendMessage(messages, index) {
return [];
}
}
class YourWorkerBot extends WorkerBot {
performAction(message) {}
sendMessage(x, y, surroundings) {}
}
return {
name: "YourBotnet",
color: "",
controllerBot: YourControllerBot,
workerBot: YourWorkerBot
};
}
Rules
- Standard Loopholes apply
- Bots cannot modify or add global variables
- Bots cannot call controller functions or other bots' methods
- Bots cannot read or modify other bots storage
- Bots may not access the internet
- I may disqualify any bot which does anything I deem to be cheating.
Sandbox
- Is the bar to entry too high?
- Can the current turn/round system be improved?
- Any better names for the 2 bots/title?
- Is there enough room for creativity?
- Would it be better if I merged the 2 classes into one class?
- Is there anything broken with the spec?