So I’m not the most diligent blogger. Doesn’t mean I haven’t been doing stuff, on the contrary; I actually have a neat little hack to brag about. So something like this has been on my mind for a while now, but the actual implementation isn’t purely original.
Let me preface this by saying that my girlfriend plays a LOT of Bejeweled Blitz. You know, that Facebook flash game that gives you 1 minute on a Bejeweled board to try and get the highest score possible? Well, she averages in the 200k range, and I can muster a solid 10k on a really good run. It’s upsetting to say the least; here is this very simple game, and I just can’t think fast enough to match up some stupid colors! I mean, it’s so simple I could probably program an AI to do it for me! … wait a second…
Pulling from resources like http://mikevallotton.wordpress.com/2009/08/19/i-cheat-at-bejeweled-blitz/ and http://www.charlesrcook.com/archive/2010/09/05/creating-a-bejeweled-blitz-bot-in-c.aspx I was able to formulate a basic idea. Coders are notoriously bad at explaining things, and these documents weren’t any different. Snippets of code with references to functions that aren’t defined elsewhere in the post, lack of an organizational structure… It got out some good ideas, but definitely not a copy-and-paste dealy.
So I cracked out the C# VS Express (’cause it’s free) and started hacking together my own. As of last night, I have it solving simple patterns, but the code is still pretty ugly. So I won’t post any code yet! I can, however, detail what I’ve done at a high level, and what problems I’ve faced.
Step 1: Where the #*)@% is the game board?
So the first step was to try and find the actual flash window on the screen. I’m sure there are some fancy ways to find it automatically, but for now I’m just using manually-entered coordinate fields on the form. Type in some numbers, click Preview… almost aligned… change numbers again, click Preview… got it!
Turns our Charles Cook found a way to detect the game board on the screen, but used a compiled bit of Matlab (which I don’t have) to do the image processing. Maybe I can find something similar in C#?
Step 2: Duh, what color is red?
This part gave me a good bit of trouble, and I definitely had to come back several times to this part to make it more accurate. The solution I’ve decided on is relatively simple, but much more complex than I thought it had to be. Turns out that if you pick a single centered pixel of each piece on the board, there’s a slight chance that the pixel that’s chosen is on an edge of the gem, or in a shadow. As a result, I needed to pull in a selection of pixels, determine their color and then average them. Guess what?! That doesn’t work either. Or rather, it works, but if the shape of the gem is too small, it will get a lot of the background and throw the bias of color into purple.
The best means I found was to pick a small square inside the piece (10×10 centered) and randomly pick a few pixels out of that. It eliminates the issue with the background, as well as averages out the gem edges and highlights. Plus, since there’s an element of randomness, even if the board reads it incorrectly one time, it might read it correctly the next.