Compare commits

...

2 Commits

2 changed files with 45 additions and 10 deletions

View File

@ -12,6 +12,9 @@ class Entity(object):
self.radius = 10
self.col = (255, 255, 255)
self.shape = 'circle'
self.solid = False
self.movable = False
self.elasticity = 1
def physics_step(self):
x, y = self.pos
@ -40,8 +43,21 @@ class Entity(object):
pygame.draw.circle(self.env.surface, self.col,
(x*self.env.width, y*self.env.height), self.radius, width=0)
def on_collision(self, other):
pass
def on_collision(self, other, depth):
if self.solid and other.solid:
if self.movable:
self.on_crash(other, depth)
def on_crash(self, other, depth):
if other.movable:
raise Exception('Movable-Movable Collisions not implemented!')
force_dir = self.pos[0] - other.pos[0], self.pos[1] - other.pos[1]
force_dir_len = math.sqrt(force_dir[0]**2+force_dir[1]**2)
force_dir = force_dir[0]/force_dir_len, force_dir[1]/force_dir_len
depth /= other.elasticity
force_vec = force_dir[0]*depth/self.env.width, \
force_dir[1]*depth/self.env.height
self.pos = self.pos[0] + force_vec[0], self.pos[1] + force_vec[1]
def kill(self):
self.env.kill_entity(self)
@ -54,6 +70,8 @@ class Agent(Entity):
self.col = (0, 0, 255)
self.drag = self.env.agent_drag
self.controll_type = self.env.controll_type
self.solid = True
self.movable = True
def controll_step(self):
self._read_input()
@ -73,8 +91,10 @@ class Enemy(Entity):
super(Enemy, self).__init__(env)
self.col = (255, 0, 0)
self.damage = 100
self.radiateDamage = True
def on_collision(self, other):
def on_collision(self, other, depth):
super().on_collision(other, depth)
if isinstance(other, Agent):
self.env.new_reward -= self.damage
@ -82,6 +102,8 @@ class Enemy(Entity):
class Barrier(Enemy):
def __init__(self, env):
super(Barrier, self).__init__(env)
self.solid = True
self.movable = False
class CircleBarrier(Barrier):
@ -137,7 +159,8 @@ class Reward(Entity):
self.enforce_not_on_barrier = False
self.reward = 10
def on_collision(self, other):
def on_collision(self, other, depth):
super().on_collision(other, depth)
if isinstance(other, Agent):
self.on_collect()
elif isinstance(other, Barrier):

View File

@ -37,6 +37,7 @@ class ColumbusEnv(gym.Env):
self.controll_type = 'SPEED' # one of SPEED, ACC
self.limit_inp_to_unit_circle = True
self.aux_reward_max = 0 # 0 = off
self.aux_penalty_max = 0 # 0 = off
self.aux_reward_discretize = 0 # 0 = dont discretize
self.draw_observable = True
self.draw_joystick = True
@ -109,6 +110,16 @@ class ColumbusEnv(gym.Env):
self.aux_reward_discretize / 2
aux_reward += reward
elif isinstance(entity, entities.Enemy):
if entity.radiateDamage:
penalty = self.aux_penalty_max / \
(1 + self.sq_dist(entity.pos, self.agent.pos))
if self.aux_reward_discretize:
penalty = int(penalty*self.aux_reward_discretize*2) / \
self.aux_reward_discretize / 2
aux_reward -= penalty
return aux_reward
def step(self, action):
@ -142,17 +153,18 @@ class ColumbusEnv(gym.Env):
def check_collisions_for(self, entity):
for other in self.entities:
if other != entity:
if self._check_collision_between(entity, other):
entity.on_collision(other)
other.on_collision(entity)
depth = self._check_collision_between(entity, other)
if depth > 0:
entity.on_collision(other, depth)
other.on_collision(entity, depth)
def _check_collision_between(self, e1, e2):
shapes = [e1.shape, e2.shape]
shapes.sort()
if shapes == ['circle', 'circle']:
sq_dist = ((e1.pos[0]-e2.pos[0])*self.width) ** 2 \
+ ((e1.pos[1]-e2.pos[1])*self.height)**2
return sq_dist < (e1.radius + e2.radius)**2
dist = math.sqrt(((e1.pos[0]-e2.pos[0])*self.width) ** 2
+ ((e1.pos[1]-e2.pos[1])*self.height)**2)
return max(0, e1.radius + e2.radius - dist)
else:
raise Exception(
'Checking for collision between unsupported shapes: '+str(shapes))