Back Original

1Crossword: crosswords for your password manager

I made a game. It’s called 1Crossword. It generates crosswords using the passwords in your 1Password vault. The crosswords are fun, simple, and perfect for sharing on social media once you complete them.

some of my favorite passwords are in this one

I made 1Crossword because the password manager games space has stagnated. There’s The Password Game - which I use to generate all my passwords - but nothing that lets me play with the passwords that I already have.

You can check out the code over here.

How does this work

1Crossword is really simple. It’s a single ~650 line Python script with no (python) dependencies - although it does need the 1Password CLI installed to get all your passwords.

Having no dependencies was important to me - some people seem to jealously guard their passwords (?) and I thought they’d feel more comfortable playing this game if they could easily read all of the code.

You can break the code into 3 components:

I’ll quickly go over how each works.

Fetching passwords from 1Password

Turns out this is pretty easy!

The 1Password CLI has support for listing logins (op item list) and for fetching a username and password for that login (op item get --reveal).

The hardest parts here are:

  1. Users have to tell 1Password “yes, it’s ok to give this program my passwords”
  2. You have to fetch passwords one at a time

I think I handle (1) fine - my code works on my macbook but I haven’t tested on all platforms.

(2) just means that my code is a little slow. I could have parallelized the fetching, but that’s annoying to do and since the password manager games space is weirdly uncompetitive I figured I’d just get this out the door instead.

Generating a crossword from passwords

This part was pretty fun and kinda tricky - I needed to write code that, given a list of words, generates a crossword for that set of words.

Some research showed me that:

Since I was committed to writing all the code for 1Crossword myself I couldn’t just pull in existing crossword-construction software. After a couple of false starts I set out to write my own naive approach:

Now, this doesn’t generate a very good crossword! But it’s pretty fast and pretty easy. And with the introduction of a few more steps you start to get somewhere:

The big simplification my code makes is that it never allows the crossword to enter an invalid state. I’ll explain what I mean using part of the grid from today’s New York Times mini crossword:

B A G E L
A
L
E

grid by Christina Iverson, edited by Sam Ezersky

If my software was trying to create a “dense” crossword, it might place “AROSE” below BAGEL, understanding that “AR” is not a word - but that it could likely be turned into a word later. This process of slowly building up a crossword while tracking which invalid words are the hardest to complete is the crux of generating dense crosswords.

But I just skipped that! My software will only place words such that any ancillary words generated are already valid. This prevents the need for backtracking and instead lets us get away with generating a lot of crosswords and picking the good ones.

So what was hard here? Well, crosswords have a whole lot of rules, and it can be finicky to keep track of them. My favorite edge case by far was that sometimes I would go to place a word, and in placing that word accidentally form it again somewhere else in the grid! This was very confusing until I figured out what was happening (here’s the code).

Anyway. All my crossword constructing logic is ~250 lines and I found it to be a pretty satisfying problem.

A UI for solving crosswords

This bit came together pretty quickly as well. I haven’t built a text-based interface in a few years and it was pretty satisfying! The basic logic is:

There are a few touches that make it a little nicer, like:

Wrapping up

This all came together super quickly and to be honest it was all pretty straightforward. I wish I had some better technical stories for you, but I guess the bar for password-manager based games is just low enough that I didn’t need to solve anything particularly tricky.

I hope you enjoy 1Crossword! Please send your best passwords my way.