brainlife

What is brainlife?

Brainlife is a esoteric programming language that iterates on a 2-D grid of spaces. Each cell is a byte, containing a value between 0 and 255. In this implementation, brainlife-js, the grid is 32 x 32 wide.

In addition to the grid, there is a single byte of memory call the register. You can write values to the register directly, or read values from the grid into the register.

In brainlife, you write two statements. Statements are separated with a semicolon ;.

The first statement decides the initial state of the grid. All spaces start at 0. There is a helper for randomly initialising the board g?. This will randomise every space in the grid.

The second statement is run for every grid space. You may manipulate the grid freely during this operation. The value of the space for the next tick, is determined by the value in the register at the end of the statement.

All commands in brainlife are written with a single character. The commands are listed in the table below. Most commands can either be standalone, or take a number. To give a command a number, simply write the number before the command, like 12x or 255+.

Char Command Effect Takes number
x Move right Moves the grid pointer to the right yes
X Move left Moves the grid pointer to the left yes
y Move down Moves the grid pointer down yes
Y Move up Moves the grid pointer up yes
+ Increment Increments the cell at the grid pointer yes
- Decrement Decrements the cell at the grid pointer yes
r Read With a number, puts that number into the register.
Without a number, puts the cell at the grid pointer's value into the register
yes
w Write With a number, writes that number to the cell at the grid pointer.
Without a number, writes the value in the register to that cell.
yes
s Swap Swaps the value in the register and the cell at the grid pointer no
? Random Puts a random integer between 0 - 255 into the cell at the grid pointer. Can take g to apply this to every cell. no
= Equality With a number, if the cell at the grid pointer is equal to the number given, increments the register.
Without a number, if the cell at the grid pointer is equal to the value in the register, increments the register.
yes
> Greater than With a number, if the number is greater than the cell at the grid pointer, increments the register.
Without a number, if the register's value is greater than the cell at the grid pointer, increments the register
yes
< Less than With a number, if the number is less than the cell at the grid pointer, increments the register.
Without a number, if the register's value is less than the cell at the grid pointer, increments the register
yes
[ Open loop If the value in the register is 0, skip to the matching ] no
] Close loop If the value in the register is >0, decrement the register and return to the matching [ no

Here is an example program, which implements Conway's Game of Life.

g?;
r2yw2Y0r
X128<Y128<x128<x128<y128<y128<X128<X128<Yx
w0r3<[1r2y255-2Y]2>[1r2y255-2Y]3=[1r2y255+2Y]2yr

To step through the instructions:

First the initialisation.
g?; Globally sets all cells to random values to initialise, and ends the statement with a semicolon.

We then enter the cell by cell instructions.
r2yw2Y0r First reads the value at the cell, move 2 spaces down and writes a copy there. Move 2 spaces back up and clear the register by setting it to 0.

X128<Y128<x128<x128<y128<y128<X128<X128<Yx

This checks all neighbouring cells, and tests them against 128, counting them as alive if the cell is greater than 128, and incrementing the register if so. This will count all neighbouring alive cells.

w0r Write the count to the cell, and clear the register.

3<[1r2y255-2Y] If the cell is greater than 3, it will increment the register, and enter the loop. The loop sets the register to 1, moves down 2 spaces to the copied original value, and decrements 255 from it, making it 0. It then moves back up 2 cells.

2>[1r2y255-2Y] This does the same thing, but checks against the cell being less than 2.

3=[1r2y255+2Y] This checks that the cell is exactly 3, and increments by 255, setting it to the maximum value.

2yr Finally, this moves two spaces down and reads the value into the register, ensuring that that value will be the value of the cell in the next tick.