Piet: Write Programs with Images


October 30, 2022

Back to projects

4 MIN READ

Introduction

At a glance, programming and being creative might seem diametrically opposed. Programming is generally about completing some task with absolute efficiency. Art, on the other hand, is less discrete, and provides little tangible utility in our daily lives. I cannot use a painting to drive my car, nor can I use a song to pay for my meal at a restaurant. Nevertheless, I find there is a lot of overlap between the two. What makes a piece of art art, at least in my eyes, is its ability to prompt introspection and complex thought. By this logic, a clever math problem or implementation of a program in code could not just be tangential to art, but art itself. This article is about a very literal example of this: Piet. Piet(PEE-et) is a programming language named after Mondrain Piet, a 20th century dutch painter. Contrary to most programming languages, the code is not written with text, but with pixels of an image. We call groups of pixels of a single color a codel, so a program can keep the same meaning no matter the dimensions of the image. The meaning of a program is derived from different colors of codels in certain preset patterns.

Basics

Piet is a stack-based language, which means all memory is stored in a single stack of integers. There are no functions or loops, and all data manipulation is done by pushing or popping numbers off the stack, with the help of other useful functions. At its core are two essential functionalities: the direction pointer(DP) and the codel chooser(CC).

The direction pointer tells the program which codel comes next, and can point in any of the four directions adjacent to the codel. The default direction of the DP is to the right. The first codel in the direction of the DP will be where the interpreter travels. Now, this is simple for images where each color block is an equally sized square. However, if this is not the case, determining what will come next can become quite complicated. For example, if we are on the blue codel, and the DP is pointing right, which color block in the image below will run next?

As you can see there is no clear answer, as both magenta and light cyan codels are in the direction of the DP. In circumstances like these, we rely on the codel chooser. The CC can flip between two states, left or right, which determine the color block that will run next if there is no immediate answer using the DP alone. To visualize this, you can imagine yourself standing on top of your current codel facing in the direction of the DP. If the CC points left, you choose the leftmost color block to travel to, and if the CC points right, you choose the rightmost. Here is the same scenario as before, but this time we also have the CC.

Colors

Now that we understand how programs are traversed, you might still be wondering how to actually encode the meaning into the program. As stated earlier, it all depends on the difference in shade/hue of successive color blocks. In order to simplify everything, you will only ever use 18 colors(20 including black and white). The color are as follows:

Methods

There are 17 different methods that you may use while programming in Piet, most of which are quite intuitive. Notice that the methods are relative to the previous codel, not based on a single color(i.e. Yellow pushes to the stack). Here are all of the methods:

Here there are a few things to notice: you cannot go to a lighter shade, and you cannot go to a previous hue. Instead, the values wrap around, meaning the shade that comes after dark cyan is light cyan, and the hue that comes after magenta is red. This can be quite annoying and tedious to work with at first, but it becomes quite easy.

Let’s try a practice scenario: if I am currently at red, and I want to output the top of the stack as a character, what color will come next in the sequence? We need to go 2 lightness steps darker, and 5 steps for the hue, meaning the next color will be light magenta. A description of all of the methods in detail is listed here.

Special Colors

As you may have noticed, the given methods will never utilize black or white. This is because they are special, and are used differently than the other colors. White can be thought of as a comment, meaning that it is simply skipped over as if it were not there at all. Black acts as an edge of the image, which means that the program flow will be stopped and the codel chooser will be toggled.

Stopping a Program

Contrary to what you might initially think, the hardest part of writing a Piet program is terminating it. This is because there are special rules that cause a program to end. To end a program, the interpreter must first reach either a black codel or an edge. Once this happens, the CC will toggle. If there is still no new color block that can be reached, the direction pointer is iterated to its next direction. If the CC has to be toggled, and there is still no new color block, the direction pointer is again iterated, and so on until the direction pointer has been through every direction and there is still no new color block that can be moved to. This is quite complicated, so here is a gif I made to explain better:

Cool Programs + How to Run Them

This was the first program I ever made, and it prints out “hello!”.

Another one of my own programs, this prints out “hello friend!”. I made a gif that shows only the code that is actually running, which you can run just like other programs.

Here is one of my favorite programs, created by Anthony Maës. It prints out “Tetris”, and every color block is in the shape of a Tetris piece.

To run any of these, or any program you write yourself, you can use this online interpreter I found here. Thanks for reading, and have a great day!