This is the 11th day of my participation in the August More text Challenge. For details, see: August More Text Challenge
I believe you are familiar with Chrome Dino, a small game in Google Chrome. When we disconnect from the Internet and visit the website, a small TYrannosaurus rex will appear. We can start the game by pressing the space bar again, or by typing Chrome ://dino/ in the address bar of Google’s Browser and pressing the space bar.
This is a simple infinite running game, it will let you jump over cactus, and dodge obstacles, the game control is very simple, press the space bar to start the game, press the space bar or up arrow ↑ jump, down arrow ↓ run down to avoid birds.
Sometimes when I get bored with writing code, I just play this game, and then I may have a bit of hand injury, and I can’t play the game over many points, so I have the idea to use the code to automatically play this game, just do it, now I will use Python to write a small program that can automatically play this dinosaur game.
Ideas:
If you look at the screenshot below, as the dinosaur is running forward, we can take the image of the front segment of the dinosaur and capture itThe color of the pixel
If the colors andThe background color
If not, it must be an obstacle (cactus or bird), and then press the button to make the correct action. Simple as it sounds, it’s not so easy to implement.
implementation
Gets the color of the specified image pixel
Since we want to get the color of the pixels, we first need to capture the image. In Python, we can use the following code to capture the image (which is a screenshot) :
import pyautogui as gui
# screenshots
sct_img = gui.screenshot(region=(x, y, width, height))
sct_img.save("name.jpg")
Copy the code
Pyautogui is a GUI automation tool library, it has a lot of functions can control graphics or mouse and so on, you can use the program to replace some mouse and keyboard operations, install command PIP install PyAutogui.
Then we can use the following code to get the color of the specified pixel on the screenshot:
def get_pixel(image, x, y) :
""" """ """ """ """ """ """ """ """ """ "
px = image.load()
return px[x, y]
Copy the code
The return value is a tuple, for example white is returned (255,255,255).
Make button action according to the color
To use programs to simulate keyboard actions, we can use the Keyboard library, which provides functions to press a key or release a key. Install the PIP install keyboard command. As we mentioned above, this dinosaur game only requires two buttons to jump up arrow ↑ and down arrow down run, so we can use the following code:
import keyboard
Press ↑ to jump
keyboard.press('up')
Press the ↓ key and run
keyboard.press("down")
# Release key "↓"
keyboard.release("down")
Copy the code
Gets the coordinates of where the obstacle is likely to appear
After playing manually for a period of time, I found that there are the following places where obstacles may appear:
According to the screenshot software, the height (y coordinate) of the place where the obstacle may appear can be obtained. Note: I have a 1920*1080 screen, so I’m taking screenshots at that resolution and determining the coordinates
Details to adjust
I found that after playing for a while, the pace of the game would speed up and the probability of misjudgment would increase greatly, so I added the logic of simulation acceleration here: To judge the time interval between two jump, if the interval and is not the same as last time, speed up the pace of it may be, we can more dinosaurs before the interval, is increasing the size of the search interval obstruction, such as the judgment in advance, will offset part because of the effects of speed up the pace of the game.
The complete code is as follows:
import pyautogui as gui
import keyboard
import time
import math
def get_pixel(image, x, y) :
""" """ """ """ """ """ """ """ """ """ "
px = image.load()
return px[x, y]
def start() :
# Screenshot image size
x, y, width, height = 0.102.1920.872
# is used to calculate time
jumping_time = 0
last_jumping_time = 0
current_jumping_time = 0
last_interval_time = 0
# Where the robot looks for obstacles
y_search1, y_search2, x_start, x_end = 557.486.400.415
y_search_for_bird = 460
time.sleep(3) # Allow 3s to switch the interface to Chrome after the program is executed
while True:
t1 = time.time()
Press the Q key to exit the robot
if keyboard.is_pressed('q') :break
# screenshots
sct_img = gui.screenshot(region=(x, y, width, height))
sct_img.save("dd.jpg")
Get the background color of the screenshot image
bg_color = get_pixel(sct_img, 100.100)
for i in reversed(range(x_start, x_end)):
# If you search for pixels in the background color of the screenshot, if the color of the pixel is different from the color of the background color, it is an obstacle
ifget_pixel(sct_img, i, y_search1) ! = bg_color \orget_pixel(sct_img, i, y_search2) ! = bg_color:Press ↑ to jump
keyboard.press('up')
jumping_time = time.time()
current_jumping_time = jumping_time
break
ifget_pixel(sct_img, i, y_search_for_bird) ! = bg_color: keyboard.press("down")
time.sleep(0.4)
# Release key "↓"
keyboard.release("down")
break
# Time between this jump and the last
interval_time = current_jumping_time - last_jumping_time
If this interval is different from the last interval, the game is speeding up and the width of the search interval should be adjusted accordingly, which is equivalent to searching ahead of time
iflast_interval_time ! =0 andmath.floor(interval_time) ! = math.floor(last_interval_time): x_end +=4
if x_end >= width:
x_end = width
Record the last jump time
last_jumping_time = jumping_time
Record the time between the last jump and the last jump
last_interval_time = interval_time
start()
Copy the code
Run the screenshot GIF below (if you’re bored) :
After several runs, the highest score is 2890 points. After optimization, it should be more. This time, the screenshot got 886 points, which shows that although THE function I want has been realized, there is still a lot of room for improvement.
There may be other details that haven’t been considered, but……
Time does not allow to do again, the score of this 886 is to imply me……
Stop it. It’s time to get back to work
It’s going to be work 886, hahaha, 886
Finally, I would like to thank my girlfriend for her tolerance, understanding and support in work and life.