Fork me on GitHub
Turing Drawings
Your browser does not support the canvas element.
Num states: Num symbols:


Turing Drawings uses randomly generated Turing machines to produce drawings on a canvas, as a form of generative art. The typical Turing machine formulation manipulates symbols on a one-dimensional tape. Turing Drawings uses machines that operate on a finite 2D grid, where each grid cell can contain one symbol which corresponds to a color value. This 2D grid is represented in the canvas shown at the left, which is dynamically updated as the Turing machine iterates.

You can generate new drawings by pressing the "Random" button above. If you find a drawing you like, and would like to share it online, then copy the custom URL from your browser's URL bar (at the top of this window, probably).

Addendum by Darius Bacon

This is an asm.js fork of Maxime Chevalier-Boisvert's original page (see original blog post and followup). The original code interprets the Turing machine; this code compiles it to asm.js.

(I also added the Faster/Slower/Pause buttons and the ring around the machine's head visible at slow speeds, moved the starting position to mid-canvas from upper left, and fixed a color-map entry.)

Update: Removed the sharing URL textbox in favor of the browser's URL bar.

Update: Adapted the Mutate button from ianiselsewhere, who also added cross-breeding, which you should totally check out.

Some timings on my laptop (a ThinkPad X1 Carbon running Firefox Nightly (2013 March) and Chrome 26, on Windows 7) for a particular Turing machine:

Version of the codeFirefox time (nsec/step)Chrome time (nsec/step)
Original10.569
Branch master4.56.0
Branch asm.js2.74.8
(Branch master includes some improvements that apply just as well without asm.js: using local variables in the inner loop, compiling each Turing machine to a custom Javascript function, and skipping writes to the state or the grid where they're known to already hold the new value.)

The frame rate on this page should be pretty close to the original because in both versions it's limited by design, to keep the action visible and the UI responsive. I've upped the framerate while reducing the number of steps/frame to keep the speed roughly constant, to take advantage of the faster computation. (The code doesn't account for time spent on screen update or waiting on setInterval(), in either version.) You might prefer to leave the framerate untouched and reap the advantage as a cooler CPU. (N.B. this page chews up CPU even after the grid stops changing — the Turing machine is just rewriting the same never-changing bits.)

One more change turned out to be needed: calls to the inner loop run much larger chunks (50,000 steps instead of 5,000). Each call into an asm.js function takes about 2 msec (at this writing): at the original finer granularity almost all the time was going into the asm.js trampoline, not actually computing anything.

Examples (from the README). Because the original code doesn't notice when you click to a new #fragment on the same page, and I don't want to mess with it, I've made the URL trivially different from the one you probably came in to (www.wry.me vs. wry.me). Just go back to the wry.me page to click on another example.