We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.

Turtlefuck

From Esolang
Jump to navigation Jump to search

Turtlefuck is an esolang based on brainfuck that allows you to do simple graphics with a turtle. It's invented by User:None1.

Memory

Turtlefuck uses an unbounded tape with wrapping bytes. All cells are initialized to zero.

Unit for angles

Because Turtlefuck can't represent numbers larger than 255, angles in Turtlefuck are represented using Turtlefuck degrees (td). One lap is 256 td, so 1 td=1.40625 degrees≈0.02454 rad.

Commands

Turtlefuck has all the commands in brainfuck and some extra commands.

%

Toggles pen. Pen is down initially.

^

Moves the turtle current cell pixels forward.

v

Moves the turtle current cell pixels backward.

`

Rotates the turtle counterclockwise current cell td.

c

Let r,g,b be the cell before the current cell, current cell and the cell after current cell. Changes the pen color to (r,g,b).

a

Draws an arc with a radius of current cell pixels and an extent of the cell after current cell td. If the cell after current cell is 0, draws a full circle. The center is radius units left of the turtle.

s

Sets the speed of the turtle to current cell mod 10 + 1.

;

Terminates the program.

Examples

Draw a square

++++++++++[>++++++++++<-]>>++++++++[>++++++++<-]<^>>`<<^>>`<<^>>`<<^>>`

Draw a circle

++++++++++[>++++++++++<-]>a

Implementations

Python

import sys
import turtle as t
def tf(code):
    s1=[]
    s2=[]
    matches={}
    tape=[0]*2000000
    for i,j in enumerate(code):
        if j=='[':
            s1.append(i)
        if j==']':
            m=s1.pop()
            matches[m]=i
            matches[i]=m
    cp=0
    p=1000000
    d=True
    t.pendown()
    t.colormode(255)
    while cp<len(code):
        if code[cp]=='+':
            tape[p]=(tape[p]+1)%256
        if code[cp]=='-':
            tape[p]=(tape[p]-1)%256
        if code[cp]==',':
            tape[p]=ord(sys.stdin.read(1))%256
        if code[cp]=='.':
            print(chr(tape[p]),end='')
        if code[cp]=='<':
            p-=1
        if code[cp]=='>':
            p+=1
        if code[cp]=='%':
            d=not d
            if d:
                t.pendown()
            else:
                t.penup()
        if code[cp]=='^':
            t.forward(tape[p])
        if code[cp]=='v':
            t.backward(tape[p])
        if code[cp]=='`':
            t.left(tape[p]*1.40625)
        if code[cp]=='c':
            t.pencolor(tape[p-1],tape[p],tape[p+1])
        if code[cp]=='a':
            if tape[p+1]:
                t.circle(tape[p],tape[p+1]*1.40625)
            else:
                t.circle(tape[p])
        if code[cp]=='s':
            t.speed(tape[p]%10+1)
        if code[cp]==';':
            break
        if code[cp]=='[':
            if not tape[p]:
                cp=matches[cp]
        if code[cp]==']':
            if tape[p]:
                cp=matches[cp]
        cp+=1
    t.done()
fn=sys.argv[1]
tf(open(fn).read())

See also