A simple bot for the game "Bejeweled Blitz" in C ++ and Qt
Recently, there have been many articles about writing bots for flash games. I want to share my experience writing a bot for Google+ game "Bejeweled Blitz".
I did not replace the answers to the server or intercept flash functions. As it seems to me, writing a player emulator, and then watching the game of the bot is more fun.
In addition, there is a “semi-honest” mode in the bot, when only hints of the move are displayed on the playing field, and the player must perform the move himself. ')
Despite the fact that the bot is written in the Qt multiplatform library, it contains some platform-specific code for Windows.
The full source code of the bot is attached.
A little bit about the game
The essence of the classic game “Bejeweled” lies in the fact that on the playing field of 8x8 cells in random order are crystals of seven colors of different shapes.
The task of the player is to swap neighboring crystals in such a way that after moving, a series of three or more crystals of the same color is obtained. If a series of crystals is not formed, then no movement occurs.
If a series of three (or more) crystals is formed as a result of the player’s actions, or accidentally while filling the field, the row of monochrome crystals disappears, and in its place new crystals fall from above.
In the game “Bejeweled Blitz” everything is the same, only one minute is given to the game, for which you need to score as many points as possible.
There are three types of bonuses in the game: “fiery” crystals, “ice” crystals and “universal” crystals. Bonuses are given for lining more than three colors in a row or for lining up different shapes of the same color that are not lying in the same row. Bonuses explode when triggered, or otherwise destroy part of the crystals on the field.
Also in the game there are several assumptions that simplify the task of the bot:
no penalty points are charged for attempting an incorrect move
you can swap fixed crystals at the same time when new ones are still falling on top
during the operation of the bonus game timer stops.
Defining a game window
The method “drag the target to the desired window” is used: to indicate the bot of the game window, click on the target and, without releasing the mouse button, drag the cursor to the game window area, then release the button. For convenience, the bot can enable the “Stay on top” mode so that the window always stays on top of the other windows. In the process of moving the mouse cursor with the target in the bot window, the name of the window class for control is displayed.
Calculate the position of the game in the window
I really didn’t want to screw any area recognition library on the image, so I just added to the settings the ability to set the game offset relative to the window. When you first start the bot will have to configure the coordinate offsets. I tried to make this process a little easier, which can be found below in the section “How to start”.
Interception of the playing field
To recognize the location of the crystals used the color value of one pixel. The screen area with the game field is copied to the array, then the pixel color is selected according to the specified coordinates of the field cell.
A small problem arises with the definition of some bonus crystals and crystals in the form of points multiplier. The fact is that in the game resources images of such crystals are not stored, but are generated at runtime. So I had to write a procedure that, on a hot key, saves a screenshot of the field and intercepted color values ​​to disk. Then catch in the game the appearance of such crystals and reset the values ​​in the file. Well, the screenshot at the same time, so as not to forget what the crystals were, and in what places are located.
The worst situation is with animated bonuses, because of which the table of correspondence of the type of crystal to the color of the captured pixel grows greatly, because ideally you should list the colors from each frame of the animation. The coverage does not have to be complete, sooner or later the color of the frame will coincide with the one in the array, but there is no need for extra delays. I thought about solving this problem, but I haven’t yet come up with a faster solution.
Implementing the search for the right moves
The search for the correct move is implemented through the position patterns. There are a finite number of arrangements of crystals on the field - patterns, namely 16:
For each color of the crystals is built its own list of the location on the playing field, which is transferred to the class Solver. Solver sequentially enumerates all possible options for the location patterns at all possible coordinates, in case of coincidence, immediately stops working, while maintaining the two coordinates of the cells with crystals that need to be changed.
Progress
So, Solver found us the coordinates for the replacement. Now you need to consistently click on the field with these coordinates with the mouse. The coordinates of the cells in the array are recalculated on screen, then, if the “Auto play” mode is on, a method is called twice, which sends a message to the window with the game that the mouse is pressed first on one and then on another chip. In this case, the game window does not have to be in focus. The mouse is also not blocked, so you can help the bot by making his own moves to heighten the fun. If the “Show helper” mode is enabled, then small red bars between the fields that correspond to the correct course will be shown on the playing field. Such a kind of hint to a human player, which crystals can be changed.
What can be improved
The first thing you want to do is to remove the need to fit the coordinates to find the game on the screen. The easiest way is to use the WebKit part of the Qt library. We get almost complete control over the web page, we know the exact position of all elements. It remains only to specify the offset for the playing field inside the game. Automatically, we get cross-platform, since there will be no need to emulate mouse clicks and look for handle windows.
There is also an idea to calculate the correct course for each color in a separate stream. Perhaps this will speed up the bot, but so far have not reached out to try.
It is quite possible to make a fully automatic self-match from a bot. It is enough to write the recognition of the dialog boxes of the game, as well as the crystals, by the colors of the dots in the key places, then “click” the mouse on the appropriate place for the button.
How to start
Start the bot and turn on the “Stay on top” button so that the bot window is always visible. Then run the game in the browser. I recommend opening the browser window to full screen in order not to constantly adjust the offset. When the game loads, turn off the “Auto play” checkbox and turn on the “Show” checkbox in the “Mini field” area. Next, drag the target from the line "Window class", holding the left mouse button on the window with the game and release the mouse button. Click the "Start / stop" button, then start the game in the browser. Set the required offset values ​​in the “Game client offset” line so that the playing field fits entirely into the bot preview window. When the offset values ​​are correct, the indicator near the offset values ​​turns green. Enable the “Auto play” checkbox, and the bot should start making moves.
A sample view of the correct settings is shown in the screenshot:
You can adjust the offset and when the checkbox "Auto play" is on, then the bot will start to play when the coordinates coincide automatically. When the bot will play confidently, you can turn off the field view in the bot to speed up the execution a bit. Turning on and off the bot is hung on the global hot key Alt + A. The “Show helper” checkbox turns on the hint mode - the red line between the cells. In the “Timeout (ms)” field you can change the time in milliseconds between the timer triggers (when the automatic game mode is turned off). Experiments have shown that the best results are obtained in the range of 100-200 milliseconds. Too small values ​​increase the bot's false alarms when crystals fall. Having tested the bot on different browsers that I have, I discovered a strange feature of IE9: if the offset on the green indicator is set correctly, the bot does not work. It is necessary to reduce the offset of X by one, then the bot works correctly. What is the reason I have not figured it out yet. If this happens to you, configure the bot with the “Auto play” checkbox turned on, not paying attention to the indicator readings.
Video demonstration of the game bot
Program Information
The program is completely autonomous, does not make any entry in the registry. The program writes its settings to the text file “settings.conf” in the folder from which it was launched, therefore, for the correct operation of the settings it requires the rights to write to its folder.
Attention! As you know, you can easily hit trouble if you click the wrong way. The bot program is engaged in having to click a lot with the mouse button, so be careful when pointing the game window to the bot; Make sure that if the bot starts to desperately click the mouse somewhere in another window, you will not have an unforeseen situation.
The author does not bear any responsibility for possible moral or material damage.
The bot is compiled with the Qt 4.7.3 library with the MinGW compiler.