Automate Google Dinosaur Game


Professional project
Python code solution and explanation
PIL, pillow, pyautogui

Introduction

The google dinosaur game has become popular among players of all ages. It’s even become a cultural icon of the internet. It’s a simple and addictive 2D side-scrolling game built into the Chrome browser. The original game is only activated when the player’s internet connection goes offline.

Playing google dinosaur can get hard the game keeps getting faster. But what if we can automate this and have a bot do it for us, all in Python? Now you can impress your siblings that you have the highest score!

Solution

I used a replica of the original chrome dinosaur game:
https://fivesjs.skipser.com/trex-game/

First, let’s import the required libraries. pyautogui will the python script to control the mouse and keyboard. PIL (or pillow) will be used for image processing.

import pyautogui
from PIL import ImageGrab, ImageOps
from time import sleep

Now when we press the play button in Python, we need to navigate to the website. To do that we can use the pyautogui.hotkey(key1, key2) to press 2 keys at once. They’re especially used for keyboard shortcuts. We can use Alt + Tab to switch to the last used window, then Ctrl + 1, to switch to the first tab.

pyautogui.hotkey("alt", "tab")
pyautogui.hotkey("ctrl", "1")

We’ve successfully navigated to the game. To start the game, we can press the Up button. pyautogui.keyDown(key) will help us do this. Then 0.001 seconds later, we can do pyautogui.keyUp(key), so it releases the key.

pyautogui.keyDown('up')
sleep(0.001)
pyautogui.keyUp('up')
sleep(0.001)

Now how will we actually detect when to jump. This is when PIL will come in handy. Our logic will be to grab the image right infront of the dinosaur to detect if a cactus is in the zone. If it is, the program can jump.

To get the image, we need to save the x and y coordinates of the top-left portion and bottom-right portion of what you want. To find the coordinates, we can screenshot the whole screen and paste that into Miscrosoft Paint. Then zoom in and zoom out. The cursor’s coordinates will show up on the bottom-left of the screen.

Then we grayscale the image. To test if the coordinates are right, we can save the image to dino.jpg.

target = (1070, 447, 1120, 473)

image = ImageGrab.grab(target)
gray_image = ImageOps.grayscale(image)
gray.save("dino.jpg")

Once our coordinates are official and everything is good to go, we have to make the code functional. Let’s save this image grabbing process into image_grab(). To get the sum of the colors in the image, we can use this:

def image_grab():
    image = ImageGrab.grab(target)
    gray_image = ImageOps.grayscale(image)
    # gray.save("dino.jpg")
    colors = sum(map(sum, gray_image.getcolors()))
    return colors

We can print the colors, and for my program, there were exactly 1547 different colors in this small image, even though it might seem only white. Your number may vary.

What should the program do if there is something in the way? Jump!

def jump():
    pyautogui.keyDown('up')
    sleep(0.001)
    pyautogui.keyUp('up')

Now for the main loop. If the sum of the colors of the little portion in front of the dinosaur is not equal to 1547, then jump.

on = True
while on:
    if image_grab() != 1547:
        jump()
Example Run
pressing run button
automation
FINAL CODE

To view my full code, please visit my GitHub repository:
https://github.com/Gursehaj-Singh/google-dinosaur-automation

# https://fivesjs.skipser.com/trex-game/

import pyautogui
from PIL import ImageGrab, ImageOps
from time import sleep

pyautogui.hotkey("alt", "tab")
pyautogui.hotkey("ctrl", "1")
pyautogui.keyDown('up')
sleep(0.001)
pyautogui.keyUp('up')
sleep(0.001)

target = (1070, 447, 1120, 473)


def image_grab():
    image = ImageGrab.grab(target)
    gray_image = ImageOps.grayscale(image)
    # gray.save("dino.jpg")
    colors = sum(map(sum, gray_image.getcolors()))
    return colors


def jump():
    pyautogui.keyDown('up')
    sleep(0.001)
    pyautogui.keyUp('up')


on = True
while on:
    if image_grab() != 1547:
        jump()

, ,