📜 ⬆️ ⬇️

Writing a class in php to interpret BrainLoller


(Example of a Brainloller code enlarged several times)

BrainLoller is a visual dialect of the Brainfuck language, in which character commands are replaced with pixels of different colors, readable from an image in * .png format.
Brainloller was coined in 2005 by Lode Vandevenne.
The colors of the teams were chosen as combinations of 0xFF and 0x80 for three RGB components. As a result, the following command table was obtained:

Two additional commands have also been added to Brainloller - 0x00FFFF (turn the instruction pointer counterclockwise) and 0x008080 (turn clockwise). Thus, the “code” can be written not in one line of pixels, but in a two-dimensional image. Before starting the program execution, the instruction pointer is located in the upper left pixel and is directed to the right. The image is processed pixel-by-pixel, after each command Brainfuck instructions instructions are shifted by one pixel in the direction in which it points. Program execution ends as soon as the instruction pointer goes outside the image. ( source )

Unfortunately, the original set of tools for working with Brainloller was lost and we will try to fill the gap in this article)

')

Write class


To create a class, we need:

Now we need some class for processing Brainfuck on php (there’s no need to fence bicycles, our class will simply turn the pixels into a set of ordinary Brainfuck commands (we will not consider the option when an infinite loop goes on the image)), for example, I saved this one and saved like brainfuck.class.php. This class issued a warning, so I recommend placing error suppression @ on line 79
You can proceed to coding. We need to create a brainloller.class.php and index.php . The first file will be the class that we are writing, the second will run it with a specific image.

Now we proceed to the description of the class.
Open brainloller.class.php and add
<?php class BrainLoller { protected $picture; //    function __construct($picture){ //   $this->picture = imagecreatefrompng($picture); } function __destruct(){ imagedestroy($this->picture); //    } } 

We create a class with a constructor and destructor in which we initialize the GD image. The picture will be stored in $ picture.
Now we need a function that will pass through the image getting the code, let's call it for example getCode ().
After adding this function, the class will look like this.
 <?php define('DIRECTION_UP', 0); define('DIRECTION_RIGHT', 1); define('DIRECTION_DOWN', 2); define('DIRECTION_LEFT', 3); /*  - - 0 - - */ class BrainLoller { protected $picture; //  BrainLoller protected $pointer = DIRECTION_RIGHT; //       (0 = 'up', 1 = 'right', 2 = 'down', 3 = 'left') function __construct($picture){ //    $this->picture = imagecreatefrompng($picture); //    $size = getimagesize($picture); $this->size['w'] = $size[0]; $this->size['h'] = $size[1]; } public function getCode(){ $current_pixel = array(0, 0); //   (x, y) $this->pointer = DIRECTION_RIGHT; $code = ''; for(;;){ if($current_pixel[0] > $this->size['w'] or $current_pixel[1] > $this->size['h'] or $current_pixel[0] < 0 or $current_pixel[1] < 0) break; //        $pixel_color = imagecolorat($this->picture, $current_pixel[0], $current_pixel[1]); //    $pixel_color = array( ( ($pixel_color >> 16) & 0xFF ), // Red ( ($pixel_color >> 8) & 0xFF ), // Green ( $pixel_color & 0xFF ), // Blue ); //      ,    ,      $code switch($pixel_color){ case array(0, 255, 0): // + $code .= '+'; break; case array(0, 128, 0): // - $code .= '-'; break; case array(255, 0, 0): // > $code .= '>'; break; case array(128, 0, 0): // < $code .= '<'; break; case array(255, 255, 0): // [ $code .= '['; break; case array(128, 128, 0): // ] $code .= ']'; break; case array(0, 0, 255): // . $code .= '.'; break; case array(0, 0, 128): // , $code .= ','; break; case array(0, 255, 255): // <- if($this->pointer + 1 > DIRECTION_LEFT) $this->pointer = 0; else $this->pointer += 1; break; case array(0, 128, 128): // -> if($this->pointer - 1 < DIRECTION_UP) $this->pointer = 3; else $this->pointer -= 1; break; } switch($this->pointer){ case DIRECTION_UP: $current_pixel[1] -= 1; break; case DIRECTION_RIGHT: $current_pixel[0] += 1; break; case DIRECTION_DOWN: $current_pixel[1] += 1; break; case DIRECTION_LEFT: $current_pixel[0] -= 1; break; } } return $code; } function __destruct(){ imagedestroy($this->picture); //    } } 

There is an infinite loop in the function that processes each pixel.
First, we check if we have gone beyond the limits of the image, because by the condition the image output is the end of the program.
Then we get the color of the pixel in the RGB format, and check which command it is attached to.
If the color is attached to the brainfuck code command, then we add this command to the final listing code, if the color is a rotation command, then turn the pointer.
Then looking at which direction the pointer is looking at - move the pixel address (move further in the direction of the pointer's look).
When the cycle ends, it means that we have gone beyond the image and we need to return the resulting code for further interpretation by another class.

Create a handler in index.php
 <?php require 'brainloller.class.php'; require 'brainfuck.class.php'; $brainloller = new BrainLoller('hello-world.png'); $brainfuck = new Brainfuck($brainloller->getCode(), 1); $brainfuck->run(); 

Here we load both classes and create instances of them. After that, we receive a brainfuck code from our class and pass it on to an interpretation to another class, from a third-party author (Again, I recommend at least not reinventing bicycles, as much as possible to improve existing solutions if they are written correctly and the author goes to contact)

The final code can be uploaded to the githab. ( mirror )

PS


What else can you play with?

Source: https://habr.com/ru/post/128539/


All Articles