Trademarks only apply in the domain the term is used in. So we can trademark common words already used elsewhere as long as they're not already associated with something in that domain. If I made harddrives called Banana, I could trademark Banana in that domain, but I would have no claim over it in, say, the food industry. Nor could I get a trademark on "Harddrive" in the harddrive industry.
Motorola did in fact pay Lucas to use the word. I don't think that necessarily means Lucas had a valid case against them, though; I think companies sometimes seek more clearance than they need in order to mitigate risk.
To be fair, Hpricot was created by _why. I'm sure 400 years down the road another madman will laugh, completely understanding what _why was going for :D
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)
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.
"The prize is the pleasure of finding the thing out, the kick in the discovery, the observation that other people use it. Those are the real things." — Richard Feynman
I was thinking along these lines, but not a bot. It would be nice as a helper program while playing to put the mouse over the bet buttons, to set standard cbet amounts and raise sizes, etc.
This reminds me of how I started "programming", making bots for online text-based mmorpgs with AutoIt V3 (http://www.autoitscript.com/), automating
IE. That was a great introduction to programming for me, very simple language with useful functions and great help files.
Since I switched to using Linux, I've been trying to find a Linux equivalent. Of course, a general programming language with an http library could be
used to do what I was initially doing with AutoIt, but it's kind of fun to see windows being manipulated and the mouse moving, keyboard text being
sent out, like a ghost user.
AutoPy gives me an excuse to learn python too. Totally sweet.
It looks great. I have a slight issue, though; whenever I try to import pydroid, it goes
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.
I've been trying to figure out a way to automatically do screen captures of the Stormpulse map at various intervals. Being able to use Python ... perfect. Thank you.
To use this to script applications there could be a few useful wrappers -
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
Doesn't seem to work on Python 2.5.x under WinXP. I get the DLL load failure message "This application has failed to start because python26.dll was not found."
The installer was happy finding Python 2.5.
Oh well, I should probably upgrade to 2.6 anyway ...