summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2015-08-11 01:44:51 +0200
committerFlorian Jung <flo@windfisch.org>2015-08-11 01:44:51 +0200
commit48938ea22282d7282579679a7d526e79794005a9 (patch)
treed38c6e02a439b6d9bd4cdd1775cc1ec41c4663a6
parent72de6605c7553a49d2688331dd9b2298c354ba48 (diff)
smarter runaway
-rw-r--r--interval_utils.py48
-rw-r--r--main.py35
2 files changed, 71 insertions, 12 deletions
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)))