Let's get you up and running!
Welcome to the exciting world of the CeneBotBattle! In this tutorial, we will embark on a playful journey where you will learn the art of bot creation and get your system up and running. Get ready to unleash your coding prowess and dive into the thrilling realm of competition. So, buckle up and let's embark on this exhilarating adventure together!
To be able to develop your very own bot that plays Bonk, you'll need to prepare your system with the necessary software and dependencies... Just kidding, you don't need to install anything!
As of this year, we've created an online editor that you can use to create bots and play games all from your browser. You can edit the code of all 6 bots on the field, step through their execution and log important information to debug your code. Additionally, the code you write will automatically be saved with your account if you're logged in.
So go ahead and open the web editor using the button below in another tab or window, so you can experiment with the code fragments in this tutorial while you're reading through it!
The default code that you see popping up in the web editor may seem quite complicated and intimidating. But don't worry, it's all not as bad as it seems. That said, you'll need to have some background knowledge to help you feel more at ease. So let's dive in for a quick tour!
Bonkbly is a JavaScript simulated instruction set, the documentation for which can be found here. A program written in Bonkbly is made up of instructions that are executed one after eachother. Each instruction takes a certain number of game ticks or time to be finished. Having lots of time-consuming instructions in your code will slow down your bot!
Instruction sets can be challenging to create complex programs for. Bonkbly doesn't have functions, and then there is for/while loops, lists, dictionaries and more. In order to help you develop a great bot, this file will contain examples for loops, lists, conditions and more.
The complete documentation of Bonkbly can be found by clicking the button below:
Let's start with moving around on the game field.
As a first demonstration, we will run around the field in a clockwise direction.
We'll use the fwd
(forward), turnl
(turn left), and turnr
(turn right) instructions to move our bot.
fwd
, FWD
, Fwd
, FWd
, FwD
, fWD
, fWd
and fwD
.
To start, we need to define an entry point for our bot, so the game knows where to start executing our code.
This is done by creating a label called main
.
Our bot always starts facing the center of the field. However, as we want to run alongside the edge of the game field, we must first turn left once before moving forward and rotating right at the next corner. Here's the code for this algorithm:
-- Entry point of the application
label main:
-- Turn left once
turnl
-- Move forward 6 times
fwd
fwd
fwd
fwd
fwd
fwd
-- Turn right once
turnr
If you press the play button in the web editor, you'll see that our bot is doing what we expect it to do! That said, it stops already after moving along one edge.
Copying this code 20 or more times to keep moving around, does not seem like an efficient option. The solution for this is a loop. Let's take a look at it!
To keep our bot moving, we need to repeat the instructions we defined in the previous step.
We can do this by using a jmp
(jump) instruction to jump back to a label elsewhere in the code.
We will first define a label loop
at the start of the instructions we want to repeat.
At the end of the code, we then add a jmp instruction.
-- Entry point of the application
label main:
-- Turn left once
turnl
-- Start of the loop
label loop:
-- Move forward 6 times
fwd
fwd
fwd
fwd
fwd
fwd
-- Turn right once
turnr
-- Jump back to the start of the loop
jmp loop
Time to introduce variables! Bonk allows you to store integers in registers/variables that you can name yourself. These can later be used as arguments with other instructions, like with e.g. turnl en turnr.
Variables are defined by prefixing the variable name with $
.
Variable names can contain letters, numbers and underscores.
Variable names are case-insensitive (like all of bonkbly).
Let's move away from the edge of the game field, because after approximatelly 1 minute, walls will start to fall down from the outer most tiles. To prevent getting crushed by these walls, let's move around the game area at random. In this example, we will choose a random integer number between 0 and 2 and turn left or right that many times.
To generate a random number, we use the rand
instruction.
It takes 3 arguments: the minimum value, the maximum value and the variable to store the random number in.
We can now use this variable as an argument for the turnr and turnl instructions.
-- Entry point of the application
label main:
-- Let's move forward, and then turn randomly left
fwd
-- Write to variable random_value
rand 0 2 $random_value
-- Supply variable random_value as argument to turnl
turnl $random_value
-- We can do the same, but turning to the right now
fwd
-- Write to variable random_value
rand 0 2 $random_value
-- Supply variable random_value as argument to turnr
turnr $random_value
-- And jump back to loop
jmp main
Time to introduce conditional statements. In Bonkbly, it is somewhat harder to implement complex conditional statements as you would find in other higher-level programming languages. A basic statement like
if <condition>:
<code-block>
can be implemented as follows:
-- Start of statement
label condition:
<condition>
jfalse condition_false
<code-block>
label condition_false:
Bonkbly allows you to compare integers using the cmp
, gt
, lt
, gte
and lte
instructions.
Calling one of these instructions will automatically allow you to make a conditional jump with the jtrue
and jfalse
instructions.
On top of that, the and
, or
, xor
and not
instructions will also allow you to make conditional jumps.
But more on that later.
Let's implement a simple if statement. If the random value is 0, we move forward, if it is 1, we turn left, and if it is 2, we turn right.
-- Entry point of the application
label main:
-- Get a random value
rand 0 2 $random_instruction
-- Compare the random value to 0, equivalent to pythons 'if random_instruction == 0:'
cmp $random_instruction 0
-- Jump if true, meaning we will move fwd
jtrue fwd
-- Compare the random value to 1, equivalent to pythons 'elif random_instruction == 1:'
cmp $random_instruction 1
jtrue turnl
-- Optionally you can write jfalse turnr here, but it is not necessary since the next instruction is the one after label turnr
-- Turn right
label turnr:
rand 0 2 $turn_value
turnr $turn_value
-- Loop around
jmp end_of_condition
-- Turn left
label turnl:
rand 0 2 $turn_value
turnl $turn_value
-- Loop around
jmp end_of_condition
-- Move forward
label fwd:
fwd
-- Loop around
jmp end_of_condition
label end_of_condition:
jmp main
As you may have noticed, our bot will hit its head against walls. We want to avoid this, because bonking into walls damages our bot and reduces its health. If we keep walking into walls, we'll eventually die. Therefore, it is time to take a look at the field around us and prevent the bot from hitting walls.
To observe the field, the instructions fsens
, nsens
, lsens
en rsens
can be used.
Each of these is used to look at a different direction of tiles around our bot.
In this tutorial, we will use fsens
, which will give us information about tiles in front of the player.
The instructions lsens
and rsens
work very simularly, but look left and right respectively.
The nsens
instruction works completely different however, this is described in detail in the documentation.
In short, the fsens
instruction will take a look at the tiles in front of the player, which are less than 2 tiles away.
When calling fsens
, the type of the tile just ahead of the player will be written in the variable $br2
(bonk register 2).
This value can be 1 (out of the field), 2 (wall), 4 (bot), 8 (empty), 16 (powerup).
We want to walk forward only if the tile is empty, a bot or a powerup.
-- Move forward
label fwd:
-- Look at some tiles in front of the bot
fsens
and $br2 0b11 $_
-- Abort moving if it's a wall
jtrue main
-- Move forward
fwd
-- Loop around
jmp main
Here, we use an and
instruction to compare the value of the tile in front of the bot to the ones we allow.
The and
instruction will perform a bitwise and operation, and it will store the value into the variable $_
, which is used as a dummy placeholder here.
If the result is not 0, the jtrue instruction will jump.
If it is 0, it will not jump.
Thus, if the tile in front is a wall (0b10), or out of bounds (0b01), the result of the and instruction will not be 0.
and
instruction, you can compare the value of a variable with any combination of tile values.
In this case, we could also have used lt $br2 3
to check if the tile is a wall or out of bounds.
We hope this tutorial has given you a good starting point for creating your own bots in the CeneBotBattle.
Remember, practice makes perfect, so keep experimenting and refining your strategies. We can't wait to see what you've come up with! Go ahead and start coding your bot in the web editor! Once you're ready, submit your code and watch your bot battle!
More information about the game can be found in the gameplay description. More information about the instructions are available in the editor, or in the documentation.
The complete code of the bot we created in this tutorial can be found below.
-- Entry point of the application
label main:
-- Pick a random movement
rand 0 2 $random_instruction
-- Compare the random value
cmp $random_instruction 0
-- Jump if true, meaning we will move fwd
jtrue fwd
cmp $random_instruction 1
jtrue turnl
-- Turn right
label turnr:
rand 0 2 $turn_value
turnr $turn_value
-- Loop around
jmp main
-- Turn left
label turnl:
rand 0 2 $turn_value
turnl $turn_value
-- Loop around
jmp main
label fwd:
-- Take a look at the world
fsens
-- Check if value is wall (0b10) or out of bounds (0b1)
and $br2 0b11 $_
-- Abort moving if it's a wall
jtrue main
fwd
-- Loop around
jmp main