0

I'm trying to make a bot which plays "Don't tap the white tile". The code I have so far works just fine, but it's a bit slow and as the game speeds up the bot fails.

Right now I'm grabbing 4 images using PIL's ImageGrab.grab():

image_r = ImageGrab.grab(bbox=(160, 500, 180, 900))
image_cr = ImageGrab.grab(bbox=(600, 500, 620, 900))
image_cl = ImageGrab.grab(bbox=(1020, 500, 1040, 900))
image_l = ImageGrab.grab(bbox=(1440, 500, 1460, 900))

image_r ⇒ right image
image_cr ⇒ center right image
image_cl ⇒ center left image
image_l ⇒ left image

Below you can see the game with boxes indicating the images (approximately)

enter image description here

Then for each one, I check for black pixels with:

def get_black_px(image,x):
    for y in range(image.size[1]-5, 5, -10):
        R , G, B = image.getpixel((x,y))
        if R < 40 or G < 40 or B < 40:
            R, G, B = image.getpixel((x, y+2)) #this is done since the lines
            if R < 40 or G < 40 or B < 40:     #between the tiles are also black
                return y

If this detects a tile, the mouse is moved there and clicked

if get_black_px(image_r, 10) != None:
    Mouse.position = (170, get_black_px(image_r, 10)+500)
    Mouse.click(Button.right, 1)
elif get_black_px(image_cr, 10) != None:
    Mouse.position = (610, get_black_px(image_cr, 10)+500)
    Mouse.click(Button.right, 1)
elif get_black_px(image_cl, 10) != None:
    Mouse.position = (1030, get_black_px(image_cl, 10)+500)
    Mouse.click(Button.right, 1)
elif get_black_px(image_l, 10) != None:
    Mouse.position = (1440, get_black_px(image_l, 10)+500)
    Mouse.click(Button.right, 1)

As I said before, this works but even when the game is slow it clicks at the middle of the tiles and not the bottom. So if you know of a faster way to do this or see a mistake or something please let me know.

Edit: added picture

martineau
  • 119,623
  • 25
  • 170
  • 301
Jack
  • 77
  • 9
  • Kindly add images so we know what you are referring to please. – Mark Setchell Mar 24 '19 at 12:01
  • @MarkSetchell I added a picture don't know if this is what you meant though – Jack Mar 24 '19 at 12:16
  • What are `Rn`, `r`, `cr`, `cl` and `l`. Your question is hard to understand. – Mark Setchell Mar 24 '19 at 12:20
  • Rn is just right now; image_r is the right image; image_cr is center right; image_cl is center left and image_l is the left one – Jack Mar 24 '19 at 12:27
  • It seems that the location of the black pixels is determined by a relatively small number of equations and inequalities. Test against those, not individual pixels. – John Coleman Mar 24 '19 at 12:33
  • Rather than iterate through, pixel by pixel, use Numpy or OpenCV to calculate the mean. If the mean is zero, the pixels are all black. If the mean is 255, they are all white. Everything else in between is linear. – Mark Setchell Mar 24 '19 at 12:48
  • If the mean is say 34, you can tell if the white pixels are at the top or bottom of the image simply by looking at the top left pixel. If it is white, the white ones are at the top, else they are at the bottom. – Mark Setchell Mar 24 '19 at 12:51
  • Also, given that the tiles do not vary across their width, there is no need to make them more than 1 pixel wide. – Mark Setchell Mar 24 '19 at 13:24
  • `getpixel()` is the bottleneck. You could access the pixels much more quickly using `Image.getdata()` — something like what what is done in [this answer](https://stackoverflow.com/a/40729543/355230) (which works for color images, too). – martineau Mar 24 '19 at 14:26

0 Answers0