#!/usr/bin/env python3 # This is for Linux to play Piano Tiles 2 on Genymotion (1 month free trial) # https://docs.genymotion.com/latest/Content/01_Get_Started/Installation.htm # To install app, google for the x86 Piano-Tiles-2 .apk file then drag and drop the file onto the virtual window! # The app installs but will not open. It is July 2019. # I tried to get Anbox to work # https://anbox.io/ # Then I had to install the x86 Piano Tiles 2... # https://linuxconfig.org/how-to-install-anbox-and-run-android-apps-in-linux # But the game would not open. # I then tried Android-x86. # https://www.howtogeek.com/164570/how-to-install-android-in-virtualbox/ # Even after allowing the virtual machine to have 4 GB of memory and all my CPU cores, Piano Tiles 2 was VERY slow. # You will likely have to change y and tileWidth in this code. # This code will stop on its own after you lose. # To prematurely stop Piano Tiles 2, you can press "esc" during run. # I mostly want to use this on the Master hall, # which means that I don't have to worry about programming long clicks for long tiles # because time (not score) is important, and I don't have to worry about things # like slider tiles! # For Pianist Challenge... # Orange slidey tiles, starburst tiles, and huge multi-click tiles cause problems. # Songs that produce sparkly graphics for every tap can cause problems. from Xlib import display, X from Xlib.ext.xtest import fake_input # I referenced... # https://stackoverflow.com/questions/69645/take-a-screenshot-via-a-python-script-on-linux/16141058#16141058 # https://stackoverflow.com/questions/10257019/how-do-i-simulate-mouse-clicks-with-xlib-on-python # https://gist.github.com/emilssolmanis/2656401 from PIL import Image # tap mindlessly (True) or intelligently (False) # mindless tapping should allow the rare combo (tap-many-times) tiles to be completed mindlessTaps = False # start with Piano Tiles 2 (in BlueStacks) on upper-left of screen # x increases left to right from 0 to width-1 (measured in pixels) # y increases top to bottom from 0 to height-1 (measured in pixels) y = 450 + 60 #y = 800 tileWidth = 90 x1 = 15 # don't start at center of tile else long tiles can give problems x2 = x1 + tileWidth x3 = x1 + 2*tileWidth x4 = x1 + 3*tileWidth W = 3*tileWidth+1 H = 1 # since rgb aren't exactly 0 on tiles (partly due to BlueStacks and also due to long tiles), # set a tolerance that is an integer less than 256 cap = 20 # After how many cycles to stop? # Set this high if game in BlueStacks often pauses for a few moments. # I usually don't have to wait for this since the code can stop in other ways. # Having this is VERY important else you can stuck not being able to use your computer! stopCounter = 1000 # prepare a few Xlib things d = display.Display() root = d.screen().root # my tap/click function def clickk(xx,yy): root.warp_pointer(xx,yy) d.sync() fake_input(d, X.ButtonPress, 1) d.sync() fake_input(d, X.ButtonRelease, 1) d.sync() print("It may be wise to fully restart the Piano Tiles 2 app or BlueStacks!") print("Put Piano Tiles 2 in BlueStacks on upper-left of screen!") response = int(input("Where is the start tile (1, 2, 3, or 4)?: ")) if response == 1: xs = x1; elif response == 2: xs = x2; elif response == 3: xs = x3; elif response == 4: xs = x4; else: print("script terminating") quit() # tap the start tile! clickk(xs,y) state = [0,0,0,0] counter = 0 while counter < stopCounter: counter += 1 # capture screen raw = root.get_image(x1,y, W,H, X.ZPixmap, 0xffffffff) im = Image.frombytes("RGB", (W, H), raw.data, "raw", "BGRX") #im.save("temp.png","PNG") # grab pixel info r1, g1, b1 = im.getpixel((0, 0)) r2, g2, b2 = im.getpixel((tileWidth, 0)) r3, g3, b3 = im.getpixel((2*tileWidth, 0)) r4, g4, b4 = im.getpixel((3*tileWidth, 0)) #print((r1, g1, b1), (r2, g2, b2), (r3, g3, b3), (r4,g4,b4)) stateNow = [0,0,0,0] if (r1+g1+b1)/3 < cap: stateNow[0]=1; if mindlessTaps: clickk(x1,y) if (r2+g2+b2)/3 < cap: stateNow[1]=1; if mindlessTaps: clickk(x2,y) if (r3+g3+b3)/3 < cap: stateNow[2]=1; if mindlessTaps: clickk(x3,y) if (r4+g4+b4)/3 < cap: stateNow[3]=1; if mindlessTaps: clickk(x4,y) # quit right away if things look weird (because waiting for counter is annoying) if sum(stateNow)>2: print("More than 2 tiles were found, so quitting!") print("This is likely due to the screen going black for a moment at end of game.") quit() # A minor fix to deal with slow screen update when tapping double tiles. if (state==[0,1,0,1] and stateNow==[0,0,0,1]) or (state==[1,0,1,0] and stateNow==[0,0,1,0]): stateNow = state if (stateNow != state and stateNow != [0,0,0,0]): print(stateNow, counter) counter = 0 if not mindlessTaps: if stateNow[0]: clickk(x1,y) if stateNow[1]: clickk(x2,y) if stateNow[2]: clickk(x3,y) if stateNow[3]: clickk(x4,y) state = stateNow print("Timed out!")