(ergo even all the Motorola Droid advertising actually has disclaimers. They must have a deal with Lucas)
import pydroid
INIT_COLOR = 473428
BELL_COLORS = set([12702690, 8950940, 9016477, 9017249, 9018536, 12505567,
12505568, 11715538, 10862803, 12965603, 12439776, 12834019,
14411502, 8953000, 5401724])
def find_init_color(screen, xr, yr):
for x in xr:
for y in yr:
if screen.get_color(x, y) == INIT_COLOR:
return (x, y)
def init():
while True:
screen = pydroid.bitmap.capture_screen()
first = find_init_color(screen, xrange(0, screen.width), xrange(0, screen.height))
last = find_init_color(screen, xrange(screen.width - 1, -1, -1), xrange(screen.height - 1, -1, -1))
if first is not None and last is not None:
return first, last
def check(first, last):
screen = pydroid.bitmap.capture_screen()
for y in xrange(last[1] - 1, first[1], -1):
for x in xrange(first[0] + 1, last[0]):
if screen.get_color(x, y) in BELL_COLORS:
return pydroid.mouse.move(x, y)
def main():
print 'Searching for Winterbells...'
first, last = init()
print 'Found at %s, %s. Running.' % (first, last)
while True:
check(first, last)
if __name__ == '__main__':
main()
It's far from perfect, but it's a good start. To run it, execute the script, then open the game in a resolution large enough such that the whole game is visible.All it does is find pixels with colors unique to the bells and moves the mouse there. I made the same script in C# a while ago. This script is faster (even though it's Python!) and far more concise. It was astonishingly easy to make too thanks to pydroid. The only time-consuming bit was finding the bell colors. Kudos for the nice library!
import pydroid, operator
INIT_COLOR = 473428
BELL_COLORS = set([12702690, 8950940, 9016477, 9017249, 9018536, 12505567,
12505568, 11715538, 10862803, 12965603, 12439776, 12834019,
14411502, 8953000, 5401724])
CANVAS_WIDTH = 751
CANVAS_HEIGHT = 501
CHECK_WIDTH = CANVAS_WIDTH / 2 - 50
def find_init_color(screen, xr, yr):
for x in xr:
for y in yr:
if screen.get_color(x, y) == INIT_COLOR:
return (x, y)
def init():
while True:
screen = pydroid.bitmap.capture_screen()
first = find_init_color(screen, xrange(0, screen.width), xrange(0, screen.height))
last = find_init_color(screen, xrange(screen.width - 1, -1, -1), xrange(screen.height - 1, -1, -1))
if first is not None and last is not None and last[0] - first[0] >= CANVAS_WIDTH and last[1] - first[1] >= CANVAS_HEIGHT:
return first, last
def triangle(base, width, height, top_left, bottom_right):
for i in xrange(0, height):
y = base[1] - i
diff = i * width / height
if y > bottom_right[1]:
continue
if y < top_left[1]:
break
for x in xrange(base[0] - width + diff, base[0] + width - diff):
if x > top_left[0] and x < bottom_right[0]:
yield (x, y)
def check(first, last, prev):
screen = pydroid.bitmap.capture_screen()
if prev is not None:
for y in xrange(prev[1] + 20, prev[1] - 20, -1):
for x in xrange(prev[0] - 20, prev[0] + 20):
if screen.get_color(x, y) in BELL_COLORS:
pydroid.mouse.move(x, y)
return (x, y)
for point in triangle(prev, CHECK_WIDTH, 150, first, last):
if screen.get_color(point[0], point[1]) in BELL_COLORS:
pydroid.mouse.move(point[0], point[1])
return point
for y in xrange(last[1] - 100, first[1], -1):
for x in xrange(first[0] + 1, last[0]):
if screen.get_color(x, y) in BELL_COLORS:
pydroid.mouse.move(x, y)
return (x, y)
def main():
print 'Searching for Winterbells...'
first, last = init()
prev = None
print 'Found at %s, %s. Running.' % (first, last)
while True:
prev = check(first, last, prev)
if __name__ == '__main__':
main()
It still only scores in the thousands because one of the bell colors sometimes maps to the rabbit, but it's at the point where it scores better than a newbie. Instead of looking from the bottom up for bell pixels, it tries to look in the following regions in order:1) The area near where it last looked.
2) A triangular area above where it last looked, which is a heuristic guess of where the rabbit would be able to jump to.
If those fail, then it looks from the bottom up for a bell. Okay that was fun, but it made me realize I really need a day job.
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
import pydroid
File "C:\Python26\lib\site-packages\pydroid\__init__.py", line 8, in <module>
import pydroid.bitmap
ImportError: DLL load failed: The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log for more detail.On a side-note, the name sounds a little inapropriate in Russian.
it doesn't matter if your scripts are cross platform when the apps they script aren't.
Here's a script to play basketball at http://www.onlinegames.com/basketball
I'm having trouble getting calculate_shot_pos right given the ball pos and basketball pos. My trig is pretty rusty, so if anyone wants to help me out (even with some strategy) I would love to hear it! I've learned the library, so getting it to actually play the game well is just a bonus.
Anyway, here goes:
from pydroid import mouse, bitmap
from math import floor, sqrt
import time
rim_color = 15474
ball_color = 10440243
basket_pos = (143, 365)
def is_ball_on_screen(screen):
return len(screen.find_every_color(ball_color)) > 0 and find_ball_pos(screen)[0] > basket_pos[0]
def is_basket_on_screen(screen):
return screen.get_color(basket_pos[0], basket_pos[1]) == rim_color
def average(xs):
return int(sum(xs, 0.0) / len(xs))
def find_ball_pos(screen):
coords = screen.find_every_color(ball_color)
xs = [coord[0] for coord in coords]
ys = [coord[1] for coord in coords]
return (average(xs), average(ys))
def calculate_shot_pos(basket, ball):
x = basket[0] + (ball[0] - basket[0]) / 3.0
y = basket[1] - (ball[1] - basket[1])
return (int(x), int(y))
while(True):
screen = bitmap.capture_screen()
if is_basket_on_screen(screen) and is_ball_on_screen(screen):
ball_pos = find_ball_pos(screen)
shot_pos = calculate_shot_pos(basket_pos, ball_pos)
mouse.move(shot_pos[0], shot_pos[1])
time.sleep(.5)
mouse.click()
time.sleep(1):)
AutoPy gives me an excuse to learn python too. Totally sweet.
For example: - Enumerate open windows (with names from title of each) - Get xy coords, height + width - Enumerate controls that windows knows about and their locations
The installer was happy finding Python 2.5.
Oh well, I should probably upgrade to 2.6 anyway ...