We’ll take a look today at how to write a bot for the Facebook game, Diamond Dash. We first investigate the basic version of the bot, before moving on to analyze how we can enhance this basic version to give us the final version of our bot.
Note: Visual Studio 2012 or above is required to open sources files.
Binaries run on .NET Framework 4.0, so please make sure you at least .NET Framework 4.0 installed.
Basic Version – Overview
In the basic version of the bot, a subroutine containing four main procedures are repeatedly executed in order. These 4 procedures are:
- Taking a screenshot of the game grid.
- Processing the screenshot.
- Scanning the processed screenshot to search for the first valid combination of diamonds. (Pattern searching)
- Clicking the first valid combination of diamonds.
We’ll skip procedures 1 and 4 (since they are rather trivial), and move on to take a look at how procedures 2 and 3 work.
Procedure 2 – Processing the screenshot
Let’s assume that we have taken a screenshot of the game grid, and that we are able to access the pixels of the diamond. For a specific diamond, we wish to determine its color based on its pixels. As such, we need some form of a function that samples the pixels of a specific diamond and returns its color.
For each of the pixels, its R, G, B components will be compared to determine its color. After having done some testing, we’ve found that the following mapping works pretty accurately and efficiently (in a sense that only integer comparison and integer subtraction is used):
- R > G > B AND R – B > 70 : Yellow
- R > B > G AND R – G > 70 : Red
- G > R > B AND G – B > 70 : Green
- B > R > G AND B – G > 70 : Purple
- B > G > R AND B – R > 70 : Blue
Having determined the color of the pixels of the diamond, we simply find, for each color, the number of pixels as a proportion of the sampled area. For example, let us assume that after sampling some diamond we get the results: 5.1% Yellow, 7.2% Red, 2.1% Green, 12.9% Purple, 71.2% Blue.
We then take the color with the highest proportion (71.2% Blue in this case) and do a simple check to see if this proportion exceeds a certain value (say, 60%). This is to make sure that the diamond is, in some sense, blue enough to be considered blue, red enough to be considered red, etc. If this condition is met, we can safely assume that the diamond is blue. If not, we assume that the diamond is grey.
Pretty simple, eh? Now that we’ve seen how to determine the colors of all the diamonds in a screenshot, we move on to procedure 3, where we look for the first valid combination of diamonds.
Procedure 3 – Pattern searching
Take a look at the grid above, and do pay special attention to the white boxes I’ve drawn on valid diamond combinations. Now, observe this: Regardless of where a valid diamond combination is and how big the combination is… you will always find either at least a 3-in-a-row sequence, or an “L”-shaped 3-diamond sequence.
That being said, searching the first 3-in-a-row sequence, or the first “L”-shaped 3-diamond sequence will suffice for searching for the first valid diamond combination.
Enhancement – Detecting Special Diamonds
In our basic version of the bot, we were able to search for valid diamond combinations. However, we’re missing out an enhancement : Searching for special diamonds, such as the one boxed up in white in the diagram above.
These special diamonds, recognized as grey due to their pixel distribution, will be abnormal in a sense that they will remain grey for a long period of time. As such, we count the number of consecutive iterations of our botting subroutine for which each of the positions in the grid remain grey. Should the count for some specific position exceed a certain threshold (say, 13), we can safely assume that this position contains a special diamond, and select it as our next move.
In this project we’ve looked at how to process pixels to gather useful information (I.E. image processing) efficiently, and we’ve also seen how a rather simple yet sufficienctly efficient search algorithms can be employed for solving the puzzle.
Well, that’s all I guess!