def __init__(self, ctx): super(SelfxBillardEye, self).__init__(ctx) self.x_threshold = XTHRESHOLD // 4 self.y_threshold = YTHRESHOLD // 4 self.drawer = OpencvDrawFuncs(w=self.x_threshold, h=self.y_threshold, ppm=1.0) self.b2 = b2World(gravity=(0, 0), doSleep=True)
def __init__(self, ctx, aname): super(SelfxBillardWorld, self).__init__(ctx, aname) self.x_threshold = XTHRESHOLD self.y_threshold = YTHRESHOLD self.x_pos = self.x_threshold // 2 self.y_pos = self.y_threshold // 2 self.drawer = OpencvDrawFuncs(w=self.x_threshold, h=self.y_threshold, ppm=1.0) self.b2 = b2World(gravity=(0, 0), doSleep=True) self._state = self.available_states()[0] self._action = self.available_actions()[0]
class SelfxBillardWorld(selfx.SelfxWorld): def __init__(self, ctx, aname): super(SelfxBillardWorld, self).__init__(ctx, aname) self.x_threshold = XTHRESHOLD self.y_threshold = YTHRESHOLD self.x_pos = self.x_threshold // 2 self.y_pos = self.y_threshold // 2 self.drawer = OpencvDrawFuncs(w=self.x_threshold, h=self.y_threshold, ppm=1.0) self.b2 = b2World(gravity=(0, 0), doSleep=True) self._state = self.available_states()[0] self._action = self.available_actions()[0] def action(self): return self._action def state(self): return self._state def reset(self): self.drawer.clear_screen() for b in self.b2.bodies: self.b2.DestroyBody(b) def render(self, mode='rgb_array', close=False): if mode == 'rgb_array': self.drawer.clear_screen() self.drawer.draw_world(self.b2) return self.drawer.screen else: return None def add_obstacle(self): if 30 < self.x_pos < self.x_threshold - 30 and 30 < self.y_pos < self.y_threshold - 30: self.b2.CreateStaticBody( position=(self.x_pos, self.y_pos), shapes=circleShape(radius=20), linearDamping=0.0, bullet=True, userData={ 'world': self.b2, 'type': 'obstacle', 'ax': 0, 'ay': 0, 'color': (192, 128, 128) }, ) def add_candy(self): self.b2.CreateDynamicBody( position=(self.x_pos, self.y_pos), linearVelocity=(np.random.normal() * 500 + 500, np.random.normal() * 500), angle=random.random() * 360, linearDamping=0.0, bullet=True, userData={ 'world': self.b2, 'type': 'candy', 'ax': 0, 'ay': 0, 'color': (128, 255, 128) }, ).CreateCircleFixture(radius=5.0, density=1, friction=0.0) def up(self): self.y_pos += 10 self.y_pos = self.y_pos % self.y_threshold def dn(self): self.y_pos -= 10 self.y_pos = self.y_pos % self.y_threshold def lf(self): self.x_pos -= 10 self.x_pos = self.x_pos % self.x_threshold def rt(self): self.x_pos += 10 self.x_pos = self.x_pos % self.x_threshold def random_walk(self, times): for _ in range(times): d = int(random.random() * 4) if d == 0: self.up() elif d == 1: self.dn() elif d == 2: self.lf() elif d == 3: self.rt()
class SelfxBillardEye(selfx.SelfxEye): def __init__(self, ctx): super(SelfxBillardEye, self).__init__(ctx) self.x_threshold = XTHRESHOLD // 4 self.y_threshold = YTHRESHOLD // 4 self.drawer = OpencvDrawFuncs(w=self.x_threshold, h=self.y_threshold, ppm=1.0) self.b2 = b2World(gravity=(0, 0), doSleep=True) def reset(self): self.drawer.clear_screen() for b in self.b2.bodies: self.b2.DestroyBody(b) self.ownbody = self.b2.CreateStaticBody( position=(self.x_threshold / 2, self.y_threshold / 2), shapes=circleShape(radius=5.0), linearDamping=0.0, bullet=True, userData={'color': (255, 255, 0)}) def view(self, world, center, direction): self.reset() x0, y0 = center rx, ry = direction theta = np.arctan2(ry, rx) rx, ry = np.cos(theta), np.sin(theta) px, py = np.cos(theta + np.pi / 2), np.sin(theta + np.pi / 2) for b in world.b2.bodies: x, y = b.position dx, dy = x - x0, y - y0 alngr = rx * dx + ry * dy alngp = px * dx + py * dy if -self.x_threshold / 2 < alngr < self.x_threshold / 2 and -self.y_threshold / 2 < alngp < self.y_threshold / 2: bx, by = self.ownbody.position if b.userData['type'] == 'candy': self.b2.CreateStaticBody( position=(bx - alngr, by - alngp), shapes=circleShape(radius=5.0), linearDamping=0.0, bullet=True, userData={'color': (128, 255, 128)}) if b.userData['type'] == 'obstacle': self.b2.CreateStaticBody( position=(bx - alngr, by - alngp), shapes=circleShape(radius=20.0), linearDamping=0.0, bullet=True, userData={'color': (192, 128, 128)}) self.drawer.install() self.drawer.draw_world(self.b2) return self.drawer.screen def available_states(self): return itertools.product('01', '01', '01') def state(self): outer = self.ctx['outer'] agent = self.ctx['agent'] view = self.view(outer, agent.center(), agent.direction()) w, h, _ = view.shape fl = view[:w // 2, :h // 2, :] fr = view[w // 2:, :h // 2, :] b = view[:, h // 2:, :] fl = fl * (fl < 255) fr = fr * (fr < 255) b = b * (b < 255) fl = np.max(fl) > 128 fr = np.max(fr) > 128 b = np.max(b) > 128 bits = '%d%d%d' % (fl, fr, b) return bits