Skip to content

Instantly share code, notes, and snippets.

@RomanSteinberg
Created April 24, 2019 08:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RomanSteinberg/204f8c46ebf1bd30da3fa03d779202b6 to your computer and use it in GitHub Desktop.
Save RomanSteinberg/204f8c46ebf1bd30da3fa03d779202b6 to your computer and use it in GitHub Desktop.
Toy example. Approaching mechanic and approaching after retreat mechanic.
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