Created
April 24, 2019 08:22
-
-
Save RomanSteinberg/204f8c46ebf1bd30da3fa03d779202b6 to your computer and use it in GitHub Desktop.
Toy example. Approaching mechanic and approaching after retreat mechanic.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Cat: | |
def __init__(self): | |
self.start_position = np.array([1, 1]) | |
self.velocity = 7 | |
self.reached = False | |
self.room = np.array([100, 100]) # выход за границы комнаты не критичен | |
def move_generator(self): | |
pos = self.start_position | |
while True: | |
target = yield pos | |
if target is None: | |
continue | |
offset = calc_offset(pos, target, self.velocity) | |
self.reached = reach_condition(pos, target, offset) | |
pos += offset | |
def go(self): | |
# retreat | |
g = self.move_generator() | |
external = yield next(g) | |
while not self.reached: | |
opposite = self.calc_opposite_target(external) | |
external = yield g.send(opposite) | |
print('In corner') | |
# approach | |
g = self.move_generator() | |
external = yield next(g) | |
yield from g | |
def go2(self): | |
cat = self.move_generator() | |
yield from feed_until(lambda _: self.reached, apply_to_feed(self.calc_opposite_target, cat)) | |
print('In corner') | |
yield from cat | |
def calc_opposite_target(self, target): | |
h, w = self.room.tolist() | |
y, x = target.tolist() | |
op_y = 0 if y>h-y else h-1 | |
op_x = 0 if x>w-x else w-1 | |
return np.array([op_y, op_x]) | |
def calc_offset(center, target, velocity): | |
direction = target - center | |
if direction[0] == 0: | |
return np.array([0, direction[1]], dtype=np.int16) | |
tg = direction[1] / direction[0] | |
cos = np.sqrt(1 / (tg ** 2 + 1)) | |
dy = velocity * cos * np.sign(direction[0]) | |
dx = dy * tg | |
return np.array([dy, dx], dtype=np.int16) | |
def reach_condition(character, destination, offset): | |
return np.linalg.norm(character.astype(int) - destination.astype(int)) <= 5 | |
def apply_to_feed(f, it): | |
y = None | |
while True: | |
x = yield it.send(y) | |
y = f(x) | |
def feed_until(exit_cond, it): | |
x = None | |
while True: | |
x = yield it.send(x) | |
if exit_cond(x): | |
break | |
g = Cat().go() | |
# g = Cat().go2() | |
next(g) | |
for i in range(40): | |
print(g.send(np.array([20, 100]))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment