def step(self, robot_action=None, human_action=None, debug=False, n_steps=4): dt = 0.25 # dt is randomly in interval [1, 2) time_iter = dt * n_steps # 记录上一步的游戏状态 past_bottom_pos = self.bottom_mallet.get_position() # 如果输入参数是None,就使用AI move if robot_action is None: if self.use_object['puck']: # robot_action = self.bottom_ai.move() robot_action = [0, 0] else: robot_action = [0, 0] if human_action is None: if self.use_object['top_mallet']: human_action = self.top_ai.move() # human_action = [0, 0] elif not self.use_object['puck']: human_action = [0, 0] else: human_action = [0, 0] self.bot_mallet_motion.set_motion(robot_action) self.top_mallet_motion.set_motion(self.top_ai.move()) # self.bottom_ai_motion.update_motion(robot_action) # 用数组来储存n_steps循环中 # puck_was_hit 和 border_was_hit 和 scored 的值 n_puck_was_hit = np.zeros(n_steps, dtype=np.float32) n_hit_the_border = np.zeros(n_steps, dtype=np.float32) n_score_flag = np.zeros(n_steps, dtype=np.float32) for k in range(n_steps): # Clear forces from last frame for body in self.bodies: body.clear_accumulated_v() self.motions.update_motions() # Move bodies for body in self.bodies: body.speed_position_update(dt) # Check collisions between all possible pairs of bodies if self.use_object['top_mallet']: Collision.circle_circle([self.puck, self.top_mallet]) Collision.circle_circle([self.top_mallet, self.bottom_mallet]) if self.use_object['puck']: n_puck_was_hit[k] = bool( Collision.circle_circle([self.puck, self.bottom_mallet])) else: n_puck_was_hit[k] = False in_the_target = Collision.circle_circle( [self.bottom_mallet, self.bottom_target], resolve=False) # Make sure all bodies are within their borders collided = [False, False, False] for i, body in enumerate(self.bodies): for border in body.borders: if Collision.circle_line(body, border): collided[i] = True n_hit_the_border[k] = collided[2] puck_is_at_the_bottom = self.puck.position[1] > self.dim.center[1] distance_decreased = False if puck_is_at_the_bottom: distance = V.magnitude(self.puck.position - self.bottom_mallet.position) distance_decreased = distance < self.distance self.distance = distance else: self.distance = P.max_distance _, n_score_flag[k] = self.score.update(self.puck) puck_position = self.puck.get_position() puck_velocity = V.address_data(self.puck.get_velocity()) bottom_mallet_position = self.bottom_mallet.get_position() bottom_mallet_velocity = V.address_data( self.bottom_mallet.get_velocity()) for i in range(len(past_bottom_pos)): if np.linalg.norm(past_bottom_pos[i] - self.bottom_mallet.get_position()[i]) < 1e-5: bottom_mallet_velocity[i] = 0 else: pass top_mallet_position = self.top_mallet.get_position() top_mallet_velocity = V.address_data(self.top_mallet.get_velocity()) puck_was_hit = np.any(n_puck_was_hit == 1) hit_the_border = np.any(n_hit_the_border == 1) scored = None score_flag = 0 if np.any(n_score_flag == 1): score_flag = 1 self.score.add_bottom() scored = 'bottom' elif np.any(n_score_flag == -1): score_flag = -1 self.score.add_top() scored = 'top' puck_position_mode = bool( self.dim.center[1] <= puck_position[1] <= self.dim.rink_bottom) game_info = GameInfo([], puck_position, puck_velocity, bottom_mallet_position, bottom_mallet_velocity, top_mallet_position, top_mallet_velocity, robot_action, human_action, scored, score_flag, puck_was_hit, puck_is_at_the_bottom, distance_decreased, hit_the_border, in_the_target, time_iter, puck_position_mode) return game_info