Projects

Below is a selection of the projects I've worked on. Mostly, they're software that I've released for free.

Name/linkTypeDescriptionMore info
Emojipasta GeneratorwebConvert text to emojipasta.goto
PixelatewebMake images pixely, add dither, make them black & white, etc.goto
Tiny MetronomewebMobile-friendly, 981-byte metronome.goto
Tiny Guitar Tunerweb903-byte EADGBE guitar tuner.goto
bsdesktopCLI tool for quick number base conversion.goto
pseudesktopCLI tool with random number utilities.goto
TokiPonaPoemBotwebBot that tweets random poems in toki pona.goto
GoLfinddesktopCommon Lisp software for tinkering with the Game of Life.goto
Collision CalculatorwebCalculate hash collision probabilities.goto
kadesktopCalculator tool with a CLI and GUI.goto
Slingshot ChesswebChess game where you fire your pieces at the enemy.goto
sketchesdesktopGenerative art in Common Lisp.goto
noisydesktopPerlin noise library for Common Lisp.goto
cl-bittorrentdesktopBitTorrent client.goto
cloroforthdesktopForth interpreter (WIP).goto

Emojipasta Generator(link: kevingal.com) ^

Add word-relevant 🤖 emojis ✨ to text with sometimes hilarious results. Based on AnEmojipastaBot, which I unleashed on Reddit a few years ago.


Pixelate(link: kevingal.com) ^

Make images more pixely, make them black & white, resize them, or add a dithering effect. I used it for this blog post.

dog from CIFAR-10, I thinkpixelated versionblack & white version


Tiny Metronome(link: kevingal.com) ^

A mobile-friendly, 981-byte metronome. I made it because most of the metronome web apps I found on the internet were bloated, or clunky on mobile. I also wrote about this app in a blog post.


Tiny Guitar Tuner(link: kevingal.com) ^

The sibling of Tiny Metronome. EADGBE tuning app for guitars, in 903 bytes.


bs(link: github.com) ^

A Python CLI tool that converts numbers between bases with as little typing as possible. If you don't specify the base, it does all valid conversions between common ones.

Installation:

pip3 install base-convert-cli

Examples (more in the README):

$ bs FFFE
[from hexadecimal]
  decimal     65534
  binary      1111111111111110
  octal       177776
$ bs -t d F
15

pseu(link: github.com) ^

A Python CLI tool that randomly generates numbers, shuffles, picks, and rolls dice. Possible uses: picking someone to do a shitty job; relieving yourself of the agony of deciding which movie to watch; making life choices.

Installation:

pip3 install pseu-cli

Examples (more in the README):

$ pseu pick "good life choice" "bad life choice"
bad life choice
$ pseu pick --n 2 </tmp/movies.txt
Boogie Nights
The Hunt for the Wilderpeople
$ pseu roll 1d6
3
$ pseu rand 100
42
$ pseu shuffle alice sue bob
bob
sue
alice

TokiPonaPoemBot(link: twitter.com) ^

I wrote about a poem generator that I made for the toki pona language, then turned it into a Twitter bot. It tweets poems like this on a daily basis:

soweli wawa,
pi tomo suli ala,
e ni li tawa.

a a mi kala.


GoLfind(link: github.com) ^

Common Lisp code that searches for Game of Life states that turn into a given picture. It can also be used to create GIFs of the Game of Life. Write-up here.

Goes well with Pixelate, because you can: (1) take your own picture, (2) shrink it and turn it black & white (using Pixelate), and then (3) pass it to GoLfind to find a Life state that turns into your picture. Or just run your picture as a Life simulation, which is also cool.

Example of a Game of Life state turning into a picture of Mona Lisa's face after 1 state change.


Collision Calculator(link: kevingal.com) ^

If you put 'k' balls in 'N' buckets, what's the probability that at least 2 balls will end up in the same bucket? In other words, what's the probability of a hash collision?


ka(link: github.com) ^

ka is a small calculator language. It supports various useful features for day-to-day calculations, such as:

There are 3 ways to interact with it: executing individual expressions through the CLI (ka '1+1'), a CLI interpreter (ka), and a GUI (ka --gui).

>>> 2 * (1/2)
1
>>> 1 metre + 1 foot to feet
4.28084
>>> p=.7; N=10; sum({C(N,k)*p^k*(1-p)^(N-k) : k in [0,4]})
0.047349
>>> sin(90 deg)
1 
>>> e^pi
23.1407
>>> X = Binomial(10, 0.3); P(3 <= X < 7)
0.6066

Installation:

pip3 install ka-cli

Slingshot Chess(link: kevingal.com) ^

A version of chess where you fire your pieces at the enemy and try to knock their king off the edge of the board.

Picture of two kings and some pawns crowded together in the center of a chess board.


sketches(link: github.com) ^

Experiments in generative art using Common Lisp and the Sketch graphics playground. I'm also involved in the development of Sketch itself.

A randomly generated tree. Reddish-pinkish background, trunk is made up of thin brown lines, and leaves are all the same image, along the branches, randomly rotated and shifted randomly too.


noisy(link: github.com) ^

Perlin noise library for Common Lisp. Supports an arbitrary number of dimensions.

Here it is in 2 dimensions:

A comparison of low-resolution (smoother) noise and higher-resolution (more detailed / chaotic) noise

Usage:

CL-USER> (ql:quickload 'noisy)
CL-USER> (use-package 'noisy)
CL-USER> (noise-seed 7)
CL-USER> (noise-detail :lod 2 :falloff 0.4)
CL-USER> (noise 0.02 0.3)
0.39439920179571514d0
CL-USER> (defparameter *N* (make-noise 2 :seed 7 :lod 1 :falloff 1.0))
CL-USER> (set-noise-detail *N* :lod 2 :falloff 0.3)
CL-USER> (noise-gen *N* 0.04 0.09)
0.17510623096285327d0

cl-bittorrent(link: github.com) ^

A barely-functioning BitTorrent client, written in Common Lisp. Will require a non-insignificant amount of TLC to be useful for practical purposes.


cloroforth(link: github.com) ^

🚧 🚧 🚧

A work-in-progress Forth interpreter.