From 48938ea22282d7282579679a7d526e79794005a9 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Tue, 11 Aug 2015 01:44:51 +0200 Subject: smarter runaway --- interval_utils.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 35 +++++++++++++++++++++++------------ 2 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 interval_utils.py diff --git a/interval_utils.py b/interval_utils.py new file mode 100644 index 0000000..4c3f8e2 --- /dev/null +++ b/interval_utils.py @@ -0,0 +1,48 @@ +from functools import reduce +from math import pi +import math + +def merge_intervals(intervals): + sorted_by_lower_bound = sorted(intervals, key=lambda tup: tup[0]) + merged = [] + + for higher in sorted_by_lower_bound: + if not merged: + merged.append(higher) + else: + lower = merged[-1] + # test for intersection between lower and higher: + # we know via sorting that lower[0] <= higher[0] + if higher[0] <= lower[1]: + upper_bound = max(lower[1], higher[1]) + merged[-1] = (lower[0], upper_bound) # replace by merged interval + else: + merged.append(higher) + + return merged + +def clean_intervals(intervals): + return list(filter(lambda i : i[0]!=i[1],intervals)) + +def canonicalize_angle_interval(i): + a=i[0] % (2*pi) + b=i[1] % (2*pi) + + if a <= b: + return [(a,b)] + else: + return [(0,b),(a,2*pi)] + +def invert_angle_intervals(intervals): + flattened = reduce(lambda a,b:a+b, (map(lambda a: [a[0],a[1]], intervals))) + return clean_intervals(list(zip([0]+flattened, flattened+[2*pi]))[::2]) + +def find_largest_angle_interval(intervals): + if (intervals[0][0]==0 and intervals[-1][1]==2*pi): + # these two intervals actually are one. + intervals_ = intervals[1:-1] + [(intervals[-1][0], intervals[0][1]+2*pi)] + else: + intervals_ = intervals + + return max(intervals_, key=lambda p:p[1]-p[0]) + diff --git a/main.py b/main.py index aa1430c..4fc3e88 100644 --- a/main.py +++ b/main.py @@ -9,6 +9,7 @@ import time import gui import random from subscriber import DummySubscriber +from interval_utils import * sub = DummySubscriber() c = client.Client(sub) @@ -23,10 +24,10 @@ except: # connect c.connect(addr,token) -c.send_facebook( - 'g2gDYQFtAAAAEKO6L3c8C8/eXtbtbVJDGU5tAAAAUvOo7JuWAVSczT5Aj0eo0CvpeU8ijGzKy/gXBVCxhP5UO+ERH0jWjAo9bU1V7dU0GmwFr+SnzqWohx3qvG8Fg8RHlL17/y9ifVWpYUdweuODb9c=') +#c.send_facebook( +# 'g2gDYQFtAAAAEKO6L3c8C8/eXtbtbVJDGU5tAAAAUvOo7JuWAVSczT5Aj0eo0CvpeU8ijGzKy/gXBVCxhP5UO+ERH0jWjAo9bU1V7dU0GmwFr+SnzqWohx3qvG8Fg8RHlL17/y9ifVWpYUdweuODb9c=') -c.player.nick="test cell pls ignore" +c.player.nick="so mal sehen" c.send_spectate() @@ -41,19 +42,29 @@ while True: gui.draw_frame() if len(list(c.player.own_cells)) > 0: + runaway=False + my_smallest = min(map(lambda cell : cell.mass, c.player.own_cells)) - runaway_x, runaway_y=(0.0,0.0) + forbidden_intervals = [] for cell in c.world.cells.values(): - dist = math.sqrt((cell.pos[0]-c.player.center[0])**2 + (cell.pos[1]-c.player.center[1])**2) - if dist < cell.size*4 and cell.mass > 1.25 * my_smallest: - runaway_x += (c.player.center[0] - cell.pos[0]) / cell.mass / dist - runaway_y += (c.player.center[1] - cell.pos[1]) / cell.mass / dist + relpos = ((cell.pos[0]-c.player.center[0]),(cell.pos[1]-c.player.center[1])) + dist = math.sqrt(relpos[0]**2+relpos[1]**2) + if dist < cell.size*4 and cell.mass > 1.25 * my_smallest: + angle = math.atan2(relpos[1],relpos[0]) + corridor_width = 2 * math.asin(cell.size / dist) + forbidden_intervals += canonicalize_angle_interval((angle-corridor_width, angle+corridor_width)) + runaway=True - runaway_r = math.sqrt(runaway_x**2 + runaway_y**2) - if (runaway_r > 0): - runaway_x, runaway_y = (c.player.center[0]+int(100*runaway_x / runaway_r)), (c.player.center[1]+int(100*runaway_y / runaway_r)) + + if (runaway): + forbidden_intervals = merge_intervals(forbidden_intervals) + allowed_intervals = invert_angle_intervals(forbidden_intervals) + + (a,b) = find_largest_angle_interval(allowed_intervals) + runaway_angle = (a+b)/2 + runaway_x, runaway_y = (c.player.center[0]+int(100*math.cos(runaway_angle))), (c.player.center[1]+int(100*math.sin(runaway_angle))) c.send_target(runaway_x, runaway_y) print ("Running away: " + str((runaway_x-c.player.center[0], runaway_y-c.player.center[1]))) @@ -75,4 +86,4 @@ while True: c.send_target(rx, ry) gui.debug_line(c.player.center, (rx, ry),(0,255,0)) gui.update() - print("Nothing to do, heading to random destination: " + str((rx, ry))) \ No newline at end of file + print("Nothing to do, heading to random destination: " + str((rx, ry))) -- cgit v1.2.1