Introduction

So, I recently became addicted to an online game called Boggle Bash, which is pretty much the original Boggle with a couple of twists thrown in. Although I’d been playing it for a couple weeks, at the very outset I had an overwhelming urge to build a program to ‘assist’ me in playing Boggle Bash. This is the story of me finally giving into that urge.

The Rules

For those of you who haven’t played Boggle, it’s a word game where 16 die are randomly ‘thrown’ into the slots of a 4×4 grid. The goal of the game is to form as many words as you can before the timer runs out. How do you form a word? Well, you start at any slot and move to any adjacent slot (up,down, left, right, and diagonally) that you haven’t already visited. Here’s a screenshot from the Boggle Bash website to illustrate:

Screenshot of Boggle Bash from Pogo.com

In this example, you can form the word TEN by starting with the T in row 2, column 4, and moving down to the E, then diagonally down to the N. But, you can’t form the word TENSE, since you can’t use the one E twice. There’s some other weird nuances, like no words less than 3 letters long, no proper nouns, no acronyms, etc., but you get the basic idea.

Bending the Rules

Some of you out there might already begin to see how a computer program could play Boggle. One method (and, coincidentally, the one I chose) is brute force, which is a two step process:

  1. Find every single possible legal combination of letters.
  2. Check each combination of letters. If it’s a word, keep it. If not, discard it.

Simple, yet highly effective. Let’s take a look at each step.

Walking a Boggle Board

One way to look at the Boggle board is not as a 4×4 grid, but as a graph with 16 nodes (sorry, my graphviz skills suck, tilt your head to see it oriented properly):

Graph representing a Boggle board

The problem of finding Boggle-legal words now becomes the problem of finding paths on the graph that have 3 or more vertices (without visiting any vertex more than once). Fair warning: the following explanation might not make total sense, and I take full responsibility.

Building the Graph

The first thing we need to do is build a representation of the above graph by creating an adjacency list, which is just a list that tells us which vertices are connected to which.

We start with a 4×4 matrix representing the Boggle board. This matrix is then used to build the adjacency list via the following algorithm: for every vertex in the matrix:

  1. Try to move in all 8 directions (up-left, up, up-right, left, right, down-left, down, down-right).
  2. For each direction, if you haven’t walked off the matrix, add the new vertex to this vertex’s adjacency list.

So, as a quick example, starting with node 0, we see we can walk right, down-right, and down, so the adjacency list for 0 is (1, 4, 5).

Finding all valid paths

Given the adjacency list, we now need to find a list of all valid paths through the graph. We start by trying to find all valid paths of an arbitrary length, call it n. To do this, for every vertex in the graph:

  1. Use the adjacency list to find all vertices adjacent to the current one that you haven’t already visited.
  2. For each adjacent vertex, find all paths of length n – 1 from that vertex. Tack on the current vertex to each path you find and voila! You have now found all paths of length n from the given vertex.

Sound confusing? Yeah, it was to me at first too. Here’s a quick example to illustrate: say you wanted to find all paths of length three. The method above takes us through the following steps:

  1. We start at vertex 0, and the adjacency list tells us we can go to vertices 1, 4, and 5. We now look for all paths of length 2 from these vertices.
  2. We start with vertex 1. The adjacency list tells us we can go to vertices 0, 2, 4, 5, and 6. We discard vertex 0, since we’ve already visited it, leaving 2, 4, 5, and 6. We now look for paths of length 1 from each of these vertices.
  3. We start with vertex 2. Since our path length is now 1, we stop here, and record our first found path of length 3, namely (0 -> 1 -> 2).
  4. We now start with vertex 4 from step 2. Again, the path length is now 1, so we stop here, and record the second found path of length 3, namely (0 -> 1 -> 4).

Building lists of paths for every length from 3 to 16 gives us a list of every valid path through the Boggle board (yes, there are a lot of them!).

Finding Real Words

So now we’ve got this big list of paths like (0 -> 1 -> 2), (0 -> 1 -> 4), (0 -> 1 -> 5), etc. The next task is to turn these paths into strings, and check if the strings are valid words. This step is actually quite a bit easier than building the list of paths. Just substitute letters for each of numbers, put all the letters together, and then use a spell-checker to see if the string you have it a valid word. For example, using the above graph and Boggle screenshot, we can translate the path (0 -> 1 -> 2) into the string JED. Our spell-checker (hopefully) tells us that’s not a word, and so we discard it.

From Theory to Practice

And now for the punchline you’ve all been waiting for: my implementation of the above method is written in python, and consists of two classes: BoggleBoard.py and BoggleTrainer.py. BoggleBoard uses the above method to generate a list of all possible paths. BoggleBoard is actually quite a bit more flexible than is needed, as it can generate valid path lists for Boggle boards of arbitrary dimensions.

BoggleTrainer then uses this path list and a given board layout to generate a list of all possible strings. It then checks those string using the Enchant spell-checking library. Valid words are kept, invalid words are discarded.

Reality is a Harsh Mistress

I field-tested the code for about a week or so, and the results were pretty positive. Running the code with python 2.6.2 on a 3.00 GHz Pentium 4 with 2 GB of RAM, the script was able to find all valid words up to 8 letters long in a reasonable amount of time. However, although the script works as advertised, it turns out there’s a few shortcomings:

  • The script doesn’t run fast enough to be able to check every single possible string in time (a single round of Boggle Bash is 3 minutes). The bottleneck is mostly with the Enchant library, although since the script attempts to cache all possible paths in RAM, that could be a bottleneck as well. However, at longer string lengths, the odds of finding a valid word decrease rapidly. I therefore decided to make a trade-off of only scanning strings up to 8 letters long.
  • The dictionary included with Enchant doesn’t exactly match Boggle Bash’s dictionary. Most notably, names and acronyms show up as false positives, and there are words that Enchant does not recognize as valid (how is ‘online’ not a word?).
  • The script itself doesn’t interface with the actual Boggle client at all. The board layout has to be entered manually as a string of 16 characters, and words from the word list have to be entered back into the Boggle client by hand. However, interfacing with the Boggle Bash client wasn’t really the main point of this exercise, so this is more of a side-note than an actual problem.

What Now?

I’m sure there’s like a kerjillion different optimizations/tweaks/enhancements that I completely missed so please feel free to leave them in the comments. One I thought of right off the top of my head was to spread out the spell checking over multiple cores by using python’s XML-RPC for message passing. Another might be trying to speed up the spell-checker, or doing something with tries. Actually interfacing with the Boggle Bash client might be cool too.

That’s it for my end, thanks to Pogo.com for creating such an enjoyable game, and I hope you’ve had as much fun reading this article as I’ve had writing it!

This entry was posted on Tuesday, July 21st, 2009 at 12:46 am and is filed under General. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

5 Responses

  1. Simmoril’s Domain » A Solution to Facebook’s ‘Gattaca’ Puzzle says

    [...] largest sum. For this, I use a technique similar to the one used to find paths through the graph in the Boggle Bash Trainer. We start with an arbitrary interval, call it , and an ‘allowed’ list of intervals that [...]

  2. kitty says

    I just want to let you know I can’t stand cheaters of any kind. Now I happen to love words and word games, and, yep, I play BoggleBash on POGO and I go into fits of rage when morons cheat at that game..it is almost sacrilegious to me when a person cheats on a word game. Words are so amazing, not only for the way they look and sound, but ahhh since we all communicate with them. I go to play that game because I LOVE words and I also enjoy the thrill of competing against strangers, now with cheaters there is no way I, or others like me can win, how can one possibly compete against bots, cheat programs, etc?

    I truly hope all the dumb cheaters, who are far too ignorant to play fairly, well I hope bad things occur to them. And really what does one accomplish by cheating? The cheating creates anger in those who have good morals and don’t cheat and their games get screwed up as well, since the cheat programs steal the words in the non cheaters games. So I hope all bad things come to the cheaters, I truly do and I want to write a great big thank you …sarcasm there…. thank you for taking what is a fun and relaxing game and turning it into a negative energy game and ruining the fun, thank you soooo much,,, again sarcasm. May karma get all the cheaters!!! And yeah even little non important ( to cheaters) things likle cheating at games is bad energy and yes is immoral, with morals they go across the spectrum of human behavior and traits and even things like cheating at games is bad.

  3. Simmoril says

    Kitty,

    Thanks for your comment; I can see that you have some fairly strong feelings regarding this subject, so let me clear up a few details.

    First, my motivation for doing this project was not so I could cheat at BoggleBash. It was simply a problem that I found interesting, and decided to work on one weekend. You asked “What does one accomplish by cheating?”, but that question misses the point of this exercise. I’m not out to get more POGO points, I’m simply trying to gain a better understanding of AI algorithms, and further my programming skills. I don’t think there’s anything immoral about that.

    I understand your frustration regarding bots. But honestly, even if I didn’t do this project, a BoggleBash bot was going to get built. Heck, during testing, my BoggleTrainer was beaten (sometimes soundly) by other, more sophisticated bots. That’s just how it goes in the world of online gaming: it’s all an arms race. The servers build better bot detectors, so people build better bots. IMHO, being able to tell the difference between a computer operated by a human and a computer operating itself seems like a nearly impossible task.

    In the end though, I don’t think bots completely ruin games. We have computers that can play (nearly) perfect games of Scrabble and poker, yet Scrabulous and online poker are as popular as ever. When Deep Blue beat Kasparov, people didn’t up and quit playing chess en masse. In fact, computers have been helping chess players become stronger than ever by allowing them to analyze thousands of possible lines quickly, and scan through libraries containing hundreds of thousands of games.

    Anyway, I’m sorry this project got you so worked up. I hope I’ve given you a better understanding of my motivation to work on it.

  4. kitty says

    Well you seem to make it out that your motivation is not to cheat, but to see if you can cheat with a bot, but to me that is still wrong. And I am sure you and others can keep creating better cheating bots while game sites keep creating anti-cheat bots or whatever, but to me I don’t get the thrill. These cheat bots, though they might impress others with their ability to work, they still anger and annoy the non-cheaters. And if you cheat you are getting higher points, that is the purpose of the game, that may not be your intent, but it happens.

    Oh and I can tell the games that are played by bots, it’s fairly obvious, the cheater often leaves their POGO profile blank ( a true lover of words doesn’t do that) or the profile is incredibly dull and unimaginative, and as New Age weirdo as this may sound you can feel the energy of the cheater is not the same energy of a true word lover. Sometimes you feel no human energy period, so I suspect the cheater either has the program running and is not even on their computer, or maybe they are but not on POGO ( how they would do that I have no idea).

    I think you should create an anti cheat program/bot, to me that would be an honorable and, I bet, fun thing to do. Imagine the hilarity when a cheater goes into a room on POGO, particularly Boggle Bash and they sit there all smug just knowing they are going to win when aha the anti cheat program kicks in and hahahaha nothing! It no longer works! Imagine the frustration and then the anger that would arise as they keep trying to get their cheat software, or is it hardware, sorry, I am computer illiterate, but no matter what the term is, it would be quite humorous that they could no longer cheat. I say use your genius and ability for good! And having an anti-cheat bot is good! You computer geniuses should do good things, like go after cyber bullies, ( finding their personal info and sending them e-mails letting them know you know who they are, where they live etc and if they do not cease being bullies online you will out them on various message boards and chat rooms they are…. as you know vermin hide in the darkness, when the light comes on they scurry away), and you could use your talents in going after cheaters at games, and you could screw up sites that send spam, viruses, worms, etc. If I were brilliant at computers I would do those kind of things.

  5. John says

    It’s okay, I understand :)

    I am trying to write a boggle solver right now.

    What I have done so far is not to generate each possible path, but to move in each direction and see if that direction is a legal move. If it is, then I check whether the resulting “word” is (a) a prefix to a dictionary word, and (b) a dictionary word. The prefix is part is important because if it’s false, we don’t need to generate any more paths from that “word,” and that prunes some of the search space.

    The adjacency list is not something I’d heard of (still new to this) so thank you for bringing it up. I have a feeling that it’s a very useful thing in general.

    Using a real spell-checker… that is pretty clever :)
    Here is a text-file Scrabble dictionary, if you want it, 6 months after posting, even: http://www.calvin.edu/~rpruim/scrabble/ospd3.txt

Leave a Reply