def get_distance(a_x, a_y, b_x, b_y): """ Get distance between two coordinates :param a_x: point a horizontal coordinate :param a_y: point a vertical coordinate :param b_x: point b horizontal coordinate :param b_y: point b vertical coordinate :return: distance value """ return position_calc.get_distance(a_x, a_y, b_x, b_y)
def radar_visible_calc(self_context, enemy_detector_context_list, enemy_fighter_context_list): ''' 计算自身雷达的可见敌方目标,将自身上下文中雷达可见目标列表更新 规则: 1. 当一个雷达收到n个干扰机干扰时,在干扰机方向±5°范围内收到主瓣干扰,在其他方向收到副瓣干扰 2. 若有n个干扰机对一个雷达进行干扰,只要有瞄准式干扰存在,则雷达整体受到瞄准式副瓣干扰影响,若无瞄准式干扰存在,则雷达受到阻塞式干扰影响 3. 预警机雷达为全向探测,战机雷达为扇形方向探测 :param self_context:自身上下文 :param enemy_detector_context_list:敌方预警机上下文列表 :param enemy_fighter_context_list:敌方战机上下文列表 :return: 新发现detector数量和fighter数量 ''' radar_list = [] r_band = self_context['r_band'] o_pos_x = self_context['pos_x'] o_pos_y = self_context['pos_y'] course = self_context['course'] r_max_range = config.get_r_max_range(r_band) # 预警机雷达为全向探测 if r_band == config.get_band_L() or r_band == config.get_band_S(): for unit in (enemy_detector_context_list + enemy_fighter_context_list): # 战机已被摧毁 if not unit['alive']: continue e_pos_x = unit['pos_x'] e_pos_y = unit['pos_y'] distance = position_calc.get_distance(o_pos_x, o_pos_y, e_pos_x, e_pos_y) if distance <= r_max_range: radar_list.append(unit) # 战机雷达为扇形方向探测 else: r_coverage_angle_X = config.get_r_coverage_angle_X() r_angle_low_bound = course - r_coverage_angle_X/2 r_angle_up_bound = course + r_coverage_angle_X/2 for unit in (enemy_detector_context_list + enemy_fighter_context_list): # 战机已被摧毁 if not unit['alive']: continue e_pos_x = unit['pos_x'] e_pos_y = unit['pos_y'] distance = position_calc.get_distance(o_pos_x, o_pos_y, e_pos_x, e_pos_y) angle = position_calc.angle_cal(o_pos_x, o_pos_y, e_pos_x, e_pos_y) # the coverage angle cross the horizon line if r_angle_low_bound < 0 and r_angle_up_bound > 0: if distance <= r_max_range and (angle >= (r_angle_low_bound + 360) or angle <= r_angle_up_bound): radar_list.append(unit) elif r_angle_low_bound < 360 and r_angle_up_bound > 360: if distance <= r_max_range and (angle >= r_angle_low_bound or angle <= (r_angle_up_bound - 360)): radar_list.append(unit) else: if distance <= r_max_range and angle >= r_angle_low_bound and angle <= r_angle_up_bound: radar_list.append(unit) # 计算雷达新发现目标的数量,用于确定无人机的奖励 new_detector_count = 0 new_fighter_count = 0 id_list = [] for item in self_context['radar_visible_list']: id_list.append(item['id']) for item in radar_list: if not item['id'] in id_list: if item['id'] > len(enemy_detector_context_list): new_fighter_count += 1 else: new_detector_count += 1 self_context['radar_visible_list'].clear() for radar in radar_list: enemy = {} enemy['id'] = radar['id'] if radar['r_band'] == config.get_band_L() or radar['r_band'] == config.get_band_S(): enemy['type'] = 0 else: enemy['type'] = 1 enemy['pos_x'] = radar['pos_x'] enemy['pos_y'] = radar['pos_y'] self_context['radar_visible_list'].append(enemy) return new_detector_count, new_fighter_count
def strike_act_validation_and_initiation(missile_type, fighter_context, detector_context_list, enemy_status, strike_list): ''' 打击有效性判断,更新打击列表内容,同时返回该打击动作的有效性指示 :param missile_type: 导弹类型 :param fighter_context: 发起攻击的战机上下文 :param detector_context_list: 己方预警机上下文列表 :param enemy_status: 目标状态 :param strike_list: 打击列表[{'attacker_id': 攻击者编号, 'target_id': 目标编号, 'missile_type': 导弹类型(1:远程,2:中程), information_source_type: 信息来源类型(0:L预警机,1:S预警机,2:战机,3:被动侦测) step_count: step计数, op_count: 观测点计数, del_ind: 删除指示(默认false)}] :return: valid:打击动作是否有效(False,无效;True,有效) ''' # print(missile_type,'\n') # print(fighter_context,'\n') # print(detector_context_list,'\n') # print(enemy_status,'\n') # print(strike_list) # b = a # 判断是否超出打击距离 fighter_pos_x = fighter_context['pos_x'] fighter_pos_y = fighter_context['pos_y'] enemy_pos_x = enemy_status['pos_x'] enemy_pos_y = enemy_status['pos_y'] distance = position_calc.get_distance(fighter_pos_x, fighter_pos_y, enemy_pos_x, enemy_pos_y) if missile_type == config.get_s_missile_type(): effective_strike_distance = config.get_s_missile_dis() if missile_type == config.get_l_missile_type(): effective_strike_distance = config.get_l_missile_dis() if distance > effective_strike_distance: return False # 判断enemy是否存活 if not enemy_status['alive']: return False sublist_of_strike = {} sublist_of_strike['attacker_id'] = fighter_context['id'] sublist_of_strike['target_id'] = enemy_status['id'] sublist_of_strike['missile_type'] = missile_type if fighter_context['j_enable']: for jammed in fighter_context['j_receive_list']: if enemy_status['id'] == jammed['id']: sublist_of_strike[ 'information_source_type'] = config.get_hit_detection_source_passive( ) for detector in detector_context_list: if detector['alive'] and detector['radar_enable']: for radar in detector['radar_visible_list']: if enemy_status['id'] == radar['id']: sublist_of_strike['information_source_type'] = detector[ 'r_band'] if fighter_context['radar_enable']: for radar in fighter_context['radar_visible_list']: if enemy_status['id'] == radar['id']: sublist_of_strike['information_source_type'] = fighter_context[ 'r_band'] if not 'information_source_type' in sublist_of_strike: print("cannot found information source type") print(fighter_context) print(detector_context_list) print(enemy_status) return False sublist_of_strike['step_count'] = 0 sublist_of_strike['op_count'] = 0 sublist_of_strike['del_ind'] = False strike_list.append(sublist_of_strike.copy()) return True