Some of you may know of the Facebook application ‘Word Challenge’. After one f my friends wrote an application that does most of the work of playing the game, I decided to one-up him and write a bot that plays the game entirely automatically. Writing this bot required three major parts: Determining which characters were on the screen, which words to send, and actually sending said words.
To determine which letters are displayed, I just used a few command-line programs, executing them using the c function ’system’. I use ’scrot’ to take a screenshot of the entire screen, ‘convert’ to cut out the images of the letters, and then ‘tesseract’ to OCR each letter individually. This is unfortunately not very portable; the Firefox window must be in the same place each time you run the bot, and if you are running the bot on a different computer you will have to change which parts of the screenshot you cut out with ‘convert’. I found some letters did not scan well (specifically p, m, i, r, and s), so a few hacks had to be done to ensure that words could be matched even if these letters were incorrectly scanned.
Once you have found which letters are available, you need to find which combinations of words to send. For this, you first need a list of valid words. I just downloaded the corncab dictionary and stripped out all words with more than six characters; you could also probably reverse-engineer the Flash client and get the dictionary from it. Once you have this dictionary, there are several ways of determining which words to be able to send. The first, and easiest, is to scan through the words in the dictionary one at a time and check if they can be created using the given letters. The more efficient way is to find all permutations of the letters and check if those were in the dictionary. As it turns out, either way works well enough for this application.
Once which words to send are determined, only the matter of actually sending them is left. To send keys to the application, I used XTestFakeKeyEvent. This function adds a key press to X’s normal event queue, to be processed as any key would be. You need to use it twice per key press, once to send a key down and once for key up. For example, to send a ‘A key press, you would need to do the following:
XTestFakeKeyEvent( display, XKeysymToKeycode( display, XK_A ), True, 0 ); XTestFakeKeyEvent( display, XKeysymToKeycode( display, XK_A ), False, 0 )
To send a word, you just need to send all the characters in it, followed by and ‘ENTER’ press. Once all the words have been transmitted, the bot sends a ‘CONTROL’ press in order to cycle to the next set of letters and waits for several seconds in order to allow the application to finish processing. The program then loops, generating an arbitrarily high score until you stop it.
There were a few other technical issues that had to be dealt with, such as what to do when the application did not finish processing all the key presses before a new cycle began, but this is the entire structure of the bot. All in all, the bot ended up being 191 lines of c.