def reset(self): self._destroy() self.reward = 0.0 self.prev_reward = 0.0 self.t = 0.0 self.human_render = False self.robots = {} while (True): a_0, x_0, y_0 = -np.pi / 2 + np.pi * random.random( ), 0.5 + 7 * random.random(), 0.5 + 4 * random.random() a_1, x_1, y_1 = -np.pi / 2 + np.pi * random.random( ), 0.5 + 7 * random.random(), 0.5 + 4 * random.random() if (ICRAMap().check_coincident_with_obstacle(x_0, y_0) and ICRAMap().check_coincident_with_obstacle(x_1, y_1)): break self.robots['robot_0'] = Robot( self.world, a_0, x_0, y_0, # self.world, -np.pi / 2, -0.1, 4.5, 'robot_0', 0, 'red', COLOR_RED) # cv2.waitKey() self.robots['robot_1'] = Robot(self.world, a_1, x_1, y_1, 'robot_1', 1, 'blue', COLOR_BLUE) self.map = ICRAMap(self.world) self.bullets = Bullet(self.world) self.buff_areas = AllBuffArea() self.supply_areas = SupplyAreas() self.state_dict["robot_0"] = { "pos": (-1, -1), "angle": -1, "health": -1, "velocity": (0, 0), "robot_0": (-1, -1), "robot_1": (-1, -1) } self.state_dict["robot_1"] = { "pos": (-1, -1), "angle": -1, "health": -1, "velocity": (0, 0), "robot_0": (-1, -1), "robot_1": (-1, -1) } self.actions["robot_0"] = None self.actions["robot_1"] = None # return True return self.step(None)[0]
def shoot(self, aim_x_position, aim_y_position): if aim_y_position != 0 and aim_x_position != 0: bullet = Bullet(self.position["x"], self.position["y"], aim_x_position, aim_y_position) return bullet else: return None
def fire_bullet(self): if self.can_shoot: self.room.fire_bullet_sound.play() new_bullet = Bullet(self.room, self.rect.centerx, self.y) new_bullet.x -= 4 self.room.add_room_object(new_bullet) self.room.set_timer(15, self.reset_shooting) self.can_shoot = False
def Update (self): for e in pygame.event.get(): if e.type == pygame.KEYDOWN: if e.key == pygame.K_SPACE: self.scene.AddObject(Bullet(self.scene, self.GetForward(1), self.rot))
def reset(self): self._destroy() self.reward = 0.0 self.prev_reward = 0.0 self.t = 0.0 self.human_render = False self.robots = {} ''' avaiable_pos = [ [0.5, 0.5], [0.5, 1.5], [0.5, 2.5], [0.5, 3.5], [1.5, 0.5], [1.5, 4.5], [1.5, 3.5], [2.5, 0.5], [2.5, 1.5], [2.5, 2.5], [2.5, 3.5], [4.0, 1.5], [4.0, 3.5], [5.5, 0.5], [5.5, 1.5], [5.5, 2.5], [5.5, 3.5], [6.5, 0.5], [6.5, 1.5], [6.5, 4.5], [7.5, 0.5], [7.5, 1.5], [7.5, 2.5], [7.5, 3.5] ] ''' avaiable_pos = [ [0.5, 0.5], [0.5, 2.0], [0.5, 3.0], [0.5, 4.5], # 0 1 2 3 [1.5, 0.5], [1.5, 3.0], [1.5, 4.5], # 4 5 6 [2.75, 0.5], [2.75, 2.0], [2.75, 3.0], [2.75, 4.5], # 7 8 9 10 [4.0, 1.75], [4.0, 3.25], # 11 12 [5.25, 0.5], [5.25, 2.0], [5.25, 3.0], [5.25, 4.5], # 13 14 15 16 [6.5, 0.5], [6.5, 2.0], [6.5, 4.5], # 17 18 19 [7.5, 0.5], [7.5, 2.0], [7.5, 3.0], [7.5, 4.5] # 20 21 22 23 ] connected = [[1, 2, 3, 4], [0, 2, 3], [0, 1, 3, 5], [0, 1, 2, 6], [0, 7], [2, 9], [3, 10], [8, 9, 10, 4], [7, 9, 10, 11], [7, 8, 10, 5, 12], [7, 8, 9], [8, 14], [9, 15], [14, 15, 16, 17], [13, 15, 16, 18, 11, 11, 11, 11, 11], [13, 14, 16, 12, 12, 12, 12, 12], [13, 14, 15, 19], [13, 20], [14, 21], [16, 23], [21, 22, 23, 17], [20, 22, 23, 18], [20, 21, 23], [20, 21, 22, 19]] random_index = random.randint(0, 23) #random_index = 5 init_pos_0 = avaiable_pos[random_index] init_pos_1 = avaiable_pos[random.choice(connected[random_index])] self.robots['robot_0'] = Robot(self.world, np.pi / 2, init_pos_0[0], init_pos_0[1], 'robot_0', 0, 'red', COLOR_RED) self.robots['robot_1'] = Robot(self.world, -np.pi, init_pos_1[0], init_pos_1[1], 'robot_1', 1, 'blue', COLOR_BLUE) self.map = ICRAMap(self.world) self.bullets = Bullet(self.world) self.buff_areas = AllBuffArea() self.supply_areas = SupplyAreas() self.state_dict["robot_0"] = { "pos": (-1, -1), "angle": -1, "health": -1, "velocity": (0, 0), "angular": 0, "robot_0": (-1, -1), "robot_1": (-1, -1) } self.state_dict["robot_1"] = { "pos": (-1, -1), "angle": -1, "health": -1, "velocity": (0, 0), "angular": 0, "robot_0": (-1, -1), "robot_1": (-1, -1) } self.actions["robot_0"] = None self.actions["robot_1"] = None return init_pos_1
class ICRAField(gym.Env, EzPickle): metadata = { # 'render.modes': ['human', 'rgb_array', 'state_pixels'], 'render.modes': 'human', 'video.frames_per_second': FPS } def __init__(self): EzPickle.__init__(self) self.seed() self.contactListener_keepref = ICRAContactListener(self) self.world = Box2D.b2World( (0, 0), contactListener=self.contactListener_keepref) self.viewer = None self.invisible_state_window = None self.invisible_video_window = None self.robots = {} self.map = None self.buff_areas = None self.bullets = None self.supply_areas = None self.detect_callback = detectCallback() self.reward = 0.0 self.prev_reward = 0.0 self.state_dict = {} self.actions = {} def seed(self, seed=None): self.np_random, seed = seeding.np_random(seed) return [seed] def _destroy(self): for robot_name in self.robots.keys(): self.robots[robot_name].destroy() self.robots = {} if self.map: self.map.destroy() self.map = None if self.bullets: self.bullets.destroy() self.bullets = None def reset(self): self._destroy() self.reward = 0.0 self.prev_reward = 0.0 self.t = 0.0 self.human_render = False self.robots = {} ''' avaiable_pos = [ [0.5, 0.5], [0.5, 1.5], [0.5, 2.5], [0.5, 3.5], [1.5, 0.5], [1.5, 4.5], [1.5, 3.5], [2.5, 0.5], [2.5, 1.5], [2.5, 2.5], [2.5, 3.5], [4.0, 1.5], [4.0, 3.5], [5.5, 0.5], [5.5, 1.5], [5.5, 2.5], [5.5, 3.5], [6.5, 0.5], [6.5, 1.5], [6.5, 4.5], [7.5, 0.5], [7.5, 1.5], [7.5, 2.5], [7.5, 3.5] ] ''' avaiable_pos = [ [0.5, 0.5], [0.5, 2.0], [0.5, 3.0], [0.5, 4.5], # 0 1 2 3 [1.5, 0.5], [1.5, 3.0], [1.5, 4.5], # 4 5 6 [2.75, 0.5], [2.75, 2.0], [2.75, 3.0], [2.75, 4.5], # 7 8 9 10 [4.0, 1.75], [4.0, 3.25], # 11 12 [5.25, 0.5], [5.25, 2.0], [5.25, 3.0], [5.25, 4.5], # 13 14 15 16 [6.5, 0.5], [6.5, 2.0], [6.5, 4.5], # 17 18 19 [7.5, 0.5], [7.5, 2.0], [7.5, 3.0], [7.5, 4.5] # 20 21 22 23 ] connected = [[1, 2, 3, 4], [0, 2, 3], [0, 1, 3, 5], [0, 1, 2, 6], [0, 7], [2, 9], [3, 10], [8, 9, 10, 4], [7, 9, 10, 11], [7, 8, 10, 5, 12], [7, 8, 9], [8, 14], [9, 15], [14, 15, 16, 17], [13, 15, 16, 18, 11, 11, 11, 11, 11], [13, 14, 16, 12, 12, 12, 12, 12], [13, 14, 15, 19], [13, 20], [14, 21], [16, 23], [21, 22, 23, 17], [20, 22, 23, 18], [20, 21, 23], [20, 21, 22, 19]] random_index = random.randint(0, 23) #random_index = 5 init_pos_0 = avaiable_pos[random_index] init_pos_1 = avaiable_pos[random.choice(connected[random_index])] self.robots['robot_0'] = Robot(self.world, np.pi / 2, init_pos_0[0], init_pos_0[1], 'robot_0', 0, 'red', COLOR_RED) self.robots['robot_1'] = Robot(self.world, -np.pi, init_pos_1[0], init_pos_1[1], 'robot_1', 1, 'blue', COLOR_BLUE) self.map = ICRAMap(self.world) self.bullets = Bullet(self.world) self.buff_areas = AllBuffArea() self.supply_areas = SupplyAreas() self.state_dict["robot_0"] = { "pos": (-1, -1), "angle": -1, "health": -1, "velocity": (0, 0), "angular": 0, "robot_0": (-1, -1), "robot_1": (-1, -1) } self.state_dict["robot_1"] = { "pos": (-1, -1), "angle": -1, "health": -1, "velocity": (0, 0), "angular": 0, "robot_0": (-1, -1), "robot_1": (-1, -1) } self.actions["robot_0"] = None self.actions["robot_1"] = None return init_pos_1 #return self.step(None)[0] def getStateArray(self, robot_id): robot_state = self.state_dict[robot_id] pos = robot_state["pos"] velocity = robot_state["velocity"] angle = robot_state["angle"] angular = robot_state["angular"] health = robot_state["health"] robot_0 = robot_state["robot_0"] robot_1 = robot_state["robot_1"] return [ pos[0], pos[1], velocity[0], velocity[1], angle, angular, robot_0[0], robot_0[1], robot_1[0], robot_1[1] ] def stepCollision(self): collision_bullet_robot = self.contactListener_keepref.collision_bullet_robot collision_bullet_wall = self.contactListener_keepref.collision_bullet_wall collision_robot_wall = self.contactListener_keepref.collision_robot_wall for bullet, robot in collision_bullet_robot: self.bullets.destroyById(bullet) if (self.robots[robot].buffLeftTime) > 0: self.robots[robot].loseHealth(25) else: self.robots[robot].loseHealth(50) for bullet in collision_bullet_wall: self.bullets.destroyById(bullet) for robot in collision_robot_wall: self.robots[robot].loseHealth(10) self.contactListener_keepref.clean() def stepAction(self, robot_name, action): # gas, rotate, transverse, rotate cloud terrance, shoot self.robots[robot_name].moveAheadBack(action[0]) self.robots[robot_name].turnLeftRight(action[1]) self.robots[robot_name].moveTransverse(action[2]) self.robots[robot_name].rotateCloudTerrance(action[3]) #print(int(self.t * FPS) % (60 * FPS)) if int(self.t * FPS) % (60 * FPS) == 0: self.robots[robot_name].refreshReloadOppotunity() if action[5] > 0.99: self.robots[robot_name].addBullets() action[5] = +0.0 if action[4] > 0.99 and int(self.t * FPS) % (FPS / 10) == 1: if (self.robots[robot_name].bullets_num > 0): init_angle, init_pos = self.robots[robot_name].getGunAnglePos() self.bullets.shoot(init_angle, init_pos) self.robots[robot_name].bullets_num -= 1 def detectEnemy(self, robot_id): detected = {} for i in range(-170, 170, 5): angle, pos = self.robots[robot_id].getAnglePos() angle += math.pi / 2 angle += i / 180 * math.pi p1 = (pos[0] + 0.2 * math.cos(angle), pos[1] + 0.2 * math.sin(angle)) p2 = (pos[0] + SCAN_RANGE * math.cos(angle), pos[1] + SCAN_RANGE * math.sin(angle)) self.world.RayCast(self.detect_callback, p1, p2) u = self.detect_callback.userData if u in self.robots.keys(): if u not in detected.keys(): p = detected[u] = self.detect_callback.point pos = self.robots[robot_id].getPos() p = (p[0] - pos[0], p[1] - pos[1]) angle = math.atan2(p[1], p[0]) # Auto shoot self.robots[robot_id].setCloudTerrance(angle) for robot_name in self.robots.keys(): self.state_dict[robot_id][robot_name] = detected[ robot_name] if robot_name in detected.keys() else (-1, -1) def updateRobotState(self, robot_id): self.state_dict[robot_id][robot_id] = self.robots[robot_id].getPos() self.state_dict[robot_id]["health"] = self.robots[robot_id].health self.state_dict[robot_id]["pos"] = self.robots[robot_id].getPos() self.state_dict[robot_id]["angle"] = self.robots[robot_id].getAngle() self.state_dict[robot_id]["velocity"] = self.robots[ robot_id].getVelocity() self.state_dict[robot_id]["angular"] = self.robots[ robot_id].hull.angularVelocity def setRobotAction(self, robot_id, action): self.actions[robot_id] = action def step(self, action): ###### observe ###### for robot_name in self.robots.keys(): self.detectEnemy(robot_name) self.updateRobotState(robot_name) ###### action ###### self.setRobotAction("robot_0", action) for robot_name in self.robots.keys(): action = self.actions[robot_name] if action is not None: self.stepAction(robot_name, action) self.robots[robot_name].step(1.0 / FPS) self.world.Step(1.0 / FPS, 6 * 30, 2 * 30) self.t += 1.0 / FPS ###### Referee ###### self.stepCollision() self.buff_areas.detect( [self.robots["robot_0"], self.robots["robot_1"]], self.t) ###### reward ###### step_reward = 0 done = False # First step without action, called from reset() if self.actions["robot_0"] is not None: pos = self.state_dict["robot_0"]["pos"] e_pos = self.state_dict["robot_1"]["pos"] distance = (pos[0] - e_pos[0])**2 + (pos[1] - e_pos[1])**2 self.reward = 10 / distance #self.reward = self.robots["robot_0"].health - \ #self.robots["robot_1"].health #self.reward -= 0.1 * self.t * FPS step_reward = self.reward - self.prev_reward if self.robots["robot_0"].health <= 0: done = True #step_reward -= 1000 if self.robots["robot_1"].health <= 0: done = True #step_reward += 1000 self.prev_reward = self.reward return self.getStateArray("robot_0"), step_reward, done, {} def render(self, mode='human'): if self.viewer is None: from gym.envs.classic_control import rendering self.viewer = rendering.Viewer(WINDOW_W, WINDOW_H) self.time_label = pyglet.text.Label('0000', font_size=36, x=20, y=WINDOW_H * 5.0 / 40.00, anchor_x='left', anchor_y='center', color=(255, 255, 255, 255)) self.score_label = pyglet.text.Label('0000', font_size=36, x=20, y=WINDOW_H * 2.5 / 40.00, anchor_x='left', anchor_y='center', color=(255, 255, 255, 255)) self.health_label = pyglet.text.Label('0000', font_size=16, x=520, y=WINDOW_H * 2.5 / 40.00, anchor_x='left', anchor_y='center', color=(255, 255, 255, 255)) self.bullets_label = pyglet.text.Label('0000', font_size=16, x=520, y=WINDOW_H * 3.5 / 40.00, anchor_x='left', anchor_y='center', color=(255, 255, 255, 255)) self.buff_stay_time = pyglet.text.Label('0000', font_size=16, x=520, y=WINDOW_H * 4.5 / 40.00, anchor_x='left', anchor_y='center', color=(255, 255, 255, 255)) self.buff_left_time = pyglet.text.Label('0000', font_size=16, x=520, y=WINDOW_H * 5.5 / 40.00, anchor_x='left', anchor_y='center', color=(255, 255, 255, 255)) self.transform = rendering.Transform() if "t" not in self.__dict__: return # reset() not called yet zoom = ZOOM * SCALE zoom_state = ZOOM * SCALE * STATE_W / WINDOW_W zoom_video = ZOOM * SCALE * VIDEO_W / WINDOW_W #scroll_x = self.car0.hull.position[0] #scroll_y = self.car0.hull.position[1] #angle = -self.car0.hull.angle scroll_x = 4.0 scroll_y = 0.0 angle = 0 #vel = self.car0.hull.linearVelocity # if np.linalg.norm(vel) > 0.5: #angle = math.atan2(vel[0], vel[1]) self.transform.set_scale(zoom, zoom) self.transform.set_translation( WINDOW_W / 2 - (scroll_x * zoom * math.cos(angle) - scroll_y * zoom * math.sin(angle)), WINDOW_H / 4 - (scroll_x * zoom * math.sin(angle) + scroll_y * zoom * math.cos(angle))) # self.transform.set_rotation(angle) self.map.draw(self.viewer) for robot_name in self.robots.keys(): self.robots[robot_name].draw(self.viewer) self.bullets.draw(self.viewer) arr = None win = self.viewer.window if mode != 'state_pixels': win.switch_to() win.dispatch_events() if mode == 'human': self.human_render = True win.clear() t = self.transform gl.glViewport(0, 0, WINDOW_W, WINDOW_H) t.enable() self.render_background() for geom in self.viewer.onetime_geoms: geom.render() t.disable() self.render_indicators(WINDOW_W, WINDOW_H) win.flip() self.viewer.onetime_geoms = [] return arr def close(self): if self.viewer is not None: self.viewer.close() self.viewer = None def render_background(self): gl.glBegin(gl.GL_QUADS) gl.glColor4f(0.4, 0.8, 0.4, 1.0) gl.glVertex3f(-PLAYFIELD, +PLAYFIELD, 0) gl.glVertex3f(+PLAYFIELD, +PLAYFIELD, 0) gl.glVertex3f(+PLAYFIELD, -PLAYFIELD, 0) gl.glVertex3f(-PLAYFIELD, -PLAYFIELD, 0) gl.glColor4f(0.4, 0.9, 0.4, 1.0) k = PLAYFIELD / 20.0 for x in range(-20, 20, 2): for y in range(-20, 20, 2): gl.glVertex3f(k * x + k, k * y + 0, 0) gl.glVertex3f(k * x + 0, k * y + 0, 0) gl.glVertex3f(k * x + 0, k * y + k, 0) gl.glVertex3f(k * x + k, k * y + k, 0) gl.glEnd() self.buff_areas.render(gl) self.supply_areas.render(gl) def render_indicators(self, W, H): self.time_label.text = "Time: {} s".format(int(self.t)) self.score_label.text = "Score: %04i" % self.reward self.health_label.text = "health left Car0 : {} Car1: {} ".format( self.robots["robot_0"].health, self.robots["robot_1"].health) self.bullets_label.text = "Car0 bullets : {}, oppotunity to add : {} ".format( self.robots['robot_0'].bullets_num, self.robots['robot_0'].opportuniy_to_add_bullets) self.buff_stay_time.text = 'Buff Stay Time: Red {}s, Blue {}s'.format( int(self.buff_areas.buffAreas[0].maxStayTime), int(self.buff_areas.buffAreas[1].maxStayTime)) self.buff_left_time.text = 'Buff Left Time: Red {}s, Blue {}s'.format( int(self.robots['robot_0'].buffLeftTime), int(self.robots['robot_1'].buffLeftTime)) self.time_label.draw() self.score_label.draw() self.health_label.draw() self.bullets_label.draw() self.buff_stay_time.draw() self.buff_left_time.draw()