def hasHiden(bop): try: assert bop.ObjHide in [0, 2] return True if bop.ObjHide > 0 else False except Exception as e: common.echosentence_color('error in wgruler.py> hasHiden():{}'.format(str(e))) raise
def wait(self, dic_metadata, flag_color): '''信息打印''' try: list_g_stage_now = self.obj_interface.getSimTime() dic_metadata['l_stage'] = list_g_stage_now if dic_metadata['l_stage'][0:3] == list_g_stage_now[0:3]: # if list_g_stage_now[1] % 2 == self.flag_color: if list_g_stage_now[1] % 2 == flag_color: print(u'AI 当前阶段({}),无动作输出,等待中...'.format( self.showStage(list_g_stage_now))) while (dic_metadata['l_stage'][0:3] == list_g_stage_now[0:3]): time.sleep(0.5) list_g_stage_now = self.obj_interface.getSimTime() else: # 对方阶段 if list_g_stage_now[2] != 1: #对间瞄,最终射击 print(u'AI 当前阶段({}),无动作输出,等待中...'.format( self.showStage(list_g_stage_now))) while (dic_metadata['l_stage'][0:3] == list_g_stage_now[0:3]): time.sleep(0.5) list_g_stage_now = self.obj_interface.getSimTime() else: # 对方机动环节(刷新数据库,重新迭代) time.sleep(0.05) except Exception as e: common.echosentence_color(" " + str(e)) self.__del__() raise except KeyboardInterrupt as k: common.echosentence_color(" " + str(k)) self.__del__() raise
def isMyStage(list_g_stage, flag_mycolor): try: assert flag_mycolor in [0,1] return list_g_stage[1] % 2 == flag_mycolor except Exception as e: common.echosentence_color('error in wgstage.py > isRStage():{}'.format(str(e))) raise
def genOccupyAction(self, cur_bop): ''' 判断是否可以夺控 :param cur_bop: :return: True/可以夺控,False/不能夺控 ''' try: list_g_stage = self.dic_metadata['l_stage'] list_loc_notmycity = wgsdata.updateNotMyCityList( self.dic_metadata['l_cities'], cur_bop.GameColor) list_ubops = self.dic_metadata['l_ubops'] if wgruler.OccupyingRightNow(list_g_stage, cur_bop, list_loc_notmycity, list_ubops) == 'O': return True return False except Exception as e: common.echosentence_color(" " + str(e)) self.__del__() raise except KeyboardInterrupt as k: common.echosentence_color(" " + str(k)) self.__del__() raise
def hasBeenTired(bop_attacker): '''判断算子是否已经疲劳:(只关注人)''' try: return bop_attacker.ObjType == 1 and bop_attacker.ObjPass >= 1 except Exception as e: common.echosentence_color('wgruler > hasBeenTired():{}'.format(str(e))) raise
def genMoveAction(self, cur_bop, obj_pos): ''' 判断是否机动,若机动,返回机动路线 :param cur_bop: 机动算子 :param obj_pos: 目标位置 :return: (True,list)/(需要机动,机动路线),(False,None)/(不机动,None) ''' try: list_g_stage = self.dic_metadata['l_stage'] flag_str_moving = wgruler.Moving(list_g_stage, cur_bop) assert flag_str_moving in ['N', 'M', 'O'] if flag_str_moving == 'M': series = wgobject.bop2Ser(cur_bop) flag_result, list_movepath = self.obj_interface.getMovePath( series, obj_pos) if (flag_result == 0): return True, list_movepath return False, None except Exception as e: common.echosentence_color(" " + str(e)) self.__del__() raise except KeyboardInterrupt as k: common.echosentence_color(" " + str(k)) self.__del__() raise
def cvtMapBop2AIBop(map_bop, list_g_stage): '''地图算子 -> AI算子的映射函数 (将算子的阶段标志换成0_1标志) BUG0: 2018/08/06 - 08:23 加入隐蔽状态的判断 ''' try: # map_bop.ObjStep , map_bop.ObjStepMax = map_bop.ObjStepMax , map_bop.ObjStep # step / stepmax 交换 map_bop.ObjAttack = 1 if haveShooted(map_bop, list_g_stage) else 0 map_bop.ObjRound = 1 if haveMoved(map_bop, list_g_stage) else 0 map_bop.ObjRound = 1 if map_bop.ObjStep != map_bop.ObjStepMax else map_bop.ObjRound # 特殊设置 map_bop.ObjKeep = 1 if hasBeenKept(map_bop, list_g_stage) else 0 map_bop.ObjHide = 1 if hasHiden(map_bop) else 0 # if map_bop.ObjKeep == 1: # print '{} is kept'.format(map_bop.ObjID) map_bop.ObjTire = 1 if hasBeenTired(map_bop) else 0 # 人员算子的ObjPass出现了3? map_bop.ObjPass = 2 if map_bop.ObjTypeX == 2 and map_bop.ObjPass > 2 else map_bop.ObjPass if map_bop.ObjPass >= 1 and map_bop.ObjType == 1: # 人员算子处于疲劳状态 map_bop.ObjStep = 0 if ( 2 - map_bop.ObjPass) < 0 else 2 - map_bop.ObjPass return map_bop except Exception as e: common.echosentence_color('wgruler > cvtMapBop2AIBop():{}'.format( str(e))) raise
def __init__(self, obj_interface, flag_color): ''' 初始化 :param obj_interface: 接口类 :param flag_color: 'RED'/红色 'BLUE'/蓝色 ''' try: self.obj_interface = obj_interface self.flag_color = 0 if flag_color == 'RED' else 1 # l_obops:我方算子列表; l_ubops:敌方算子列表; l_cities:夺控点信息列表; l_stage:阶段信息 self.dic_metadata = { 'l_obops': [], 'l_ubops': [], 'l_cities': [], 'l_stage': [] } self.dic_targets = {} self.memory_obj = {} self.main_city_occupied = False self.updateSDData() # 更新态势数据 except Exception as e: common.echosentence_color(" " + str(e)) self.__del__() raise except KeyboardInterrupt as k: common.echosentence_color(" " + str(k)) self.__del__() raise
def genGetOnAction(self, car_bop, peo_bop): ''' 生成上车动作 :param car_bop: :param peo_bop: :return: True/能上车 False/不能上车 ''' try: list_g_stage = self.dic_metadata['l_stage'] flag_car_moving = wgruler.Moving(list_g_stage, cur_bop=car_bop) flag_peo_moving = wgruler.Moving(list_g_stage, cur_bop=peo_bop) flag_car_geton = car_bop.ObjTypeX == 1 and car_bop.ObjSonNum == 0 and car_bop.ObjStep >= car_bop.ObjStepMax // 2 and car_bop.ObjKeep == 0 flag_peo_geton = peo_bop.ObjTypeX == 2 and peo_bop.ObjStep == peo_bop.ObjStepMax and peo_bop.ObjKeep == 0 if flag_car_moving == 'M' and flag_peo_moving == 'M' and flag_car_geton and flag_peo_geton: return True return False except Exception as e: common.echosentence_color(" " + str(e)) self.__del__() raise except KeyboardInterrupt as k: common.echosentence_color(" " + str(k)) self.__del__() raise
def genShootAction(self, bop_attacker, bop_obj): ''' 判断能否射击 :param bop_attacker: :param bop_obj: :return: (True,wp_index)/(能射击,武器编号),(False,None)/(不能射击,None) ''' try: list_g_stage = self.dic_metadata['l_stage'] flag_str_shooting = wgruler.Shooting(list_g_stage, bop_attacker, bop_obj) if flag_str_shooting != 'N' and flag_str_shooting != 'TS': ser_att = wgobject.bop2Ser(bop_attacker) ser_obj = wgobject.bop2Ser(bop_obj) flag_success, wp_index = self.obj_interface.chooseWeaponIndex( ser_att, ser_obj) # 获取武器编号 if flag_success == 0: return (True, wp_index) return (False, None) except Exception as e: common.echosentence_color(" " + str(e)) self.__del__() raise except KeyboardInterrupt as k: common.echosentence_color(" " + str(k)) self.__del__() raise
def getLocDataInTuple(self): try: assert self.isValid() return (self.q, self.r, self.s) except Exception as e: common.echosentence_color('error in class HEX_CUBE getLocDataInTuple():{}'.format(str(e))) raise
def doMove(self, bop): #移动 try: main_city = wgsdata.mainCity(self.dic_metadata['l_cities']) bopId = common.getBopIdentity(bop) flag, l_path = self.genMoveAction(bop, self.dic_targets[bopId]) if flag and l_path: l = int(len(l_path) + 1) // 2 if len(l_path) >= 4 else len(l_path) + 1 l_path = l_path[:l] if l_path[-1] == main_city and len(l_path) >= 2: l_path = l_path[:-1] self.obj_interface.setMove(bop.ObjID, l_path) #调用接口函数执行机动动作 self.updateSDData() bop = common.getSpecifiedBopById(self.dic_metadata['l_obops'], common.getBopIdentity(bop)) return True return False except Exception as e: common.echosentence_color("doMove error: " + str(e)) self.__del__() raise except KeyboardInterrupt as k: common.echosentence_color("doMove: " + str(k)) self.__del__() raise
def moveToSecondary(self): ''' 是否应该占领次要目标地 ''' try: score = self.obj_interface.getScore() not_my_city = wgsdata.updateNotMyCityList( self.dic_metadata['l_cities'], self.flag_color) if self.flag_color == 0: if score["BlueObjScore"][0] == 0 or score["RedObjScore"][ 0] - score["BlueObjScore"][0] > 60 and len( not_my_city) == 1: return True if self.flag_color == 1: if score["RedObjScore"][0] == 0 or score["BlueObjScore"][ 0] - score["RedObjScore"][0] > 60 and len( not_my_city) == 1: return True return False except Exception as e: common.echosentence_color(" " + str(e)) self.__del__() raise except KeyboardInterrupt as k: common.echosentence_color(" " + str(k)) self.__del__() raise
def oneWin(self): ''' 是否一方胜利 :return: True/是 False/否 ''' try: score = self.obj_interface.getScore() not_my_city = wgsdata.updateNotMyCityList( self.dic_metadata['l_cities'], self.flag_color) if self.flag_color == 0: if score["RedObjScore"][0] == 0: return True elif len(not_my_city) == 0: return True if self.flag_color == 1: if score["BlueObjScore"][0] == 0: return True elif len(not_my_city) == 0: return True except Exception as e: common.echosentence_color(" " + str(e)) self.__del__() raise except KeyboardInterrupt as k: common.echosentence_color(" " + str(k)) self.__del__() raise
def getDistanceInOff(hexa, hexb): try: hexa_cube = hexa.cvtToCube() hexb_cube = hexb.cvtToCube() return getDistanceInCube(hexa_cube, hexb_cube) except Exception as e: common.echosentence_color('error in getDistanceInOff():{}'.format(str(e))) raise
def getSixNeighInOrder(self): try: assert self.col and self.row list_dir_index = range(6) return self.getSpecifiedNeighFromDirList(list_dir_index) except Exception as e: common.echosentence_color('error in class HEX_OFF getSixNeighInOrder():{}'.format(str(e))) raise
def cvtToOff(self): try: assert self.isValid() col = self.q + (self.r - (self.r & 1)) // 2 row = self.r return HEX_OFF(row, col) except Exception as e: common.echosentence_color('error in class HEX_CUBE cvtToOff():{}'.format(str(e))) raise
def haveShooted(bop, list_g_stage): '''判断算子在当前阶段是否已经射击过 射击只判断当前阶段(算子在每个阶段开始时候射击标志清零/ 算子在每个阶段(无论敌我)都可以进行射击) ''' try: round_num = wgstage.getStageId(list_g_stage) return True if bop.ObjAttack == round_num else False except Exception as e: common.echosentence_color('wgruler > haveShooted():{}'.format(str(e))) raise
def cvtToCube(self): try: assert self.col >= 0 and self.row >= 0 q = self.col - (self.row - (self.row & 1)) // 2 r = self.row s = 0 - q - r return HEX_CUBE(q, r, s) except Exception as e: common.echosentence_color( 'error in class HEX_OFF cvtToCube():[row:col={}:{}]:{}'.format(self.col, self.row, str(e))) raise
def mainCity(l_cities): '''返回主要目标地''' try: assert len(l_cities) % 3 == 0 return [ l_cities[i] for i in range(len(l_cities)) if i % 3 == 0 and l_cities[i + 2] == 80 ][0] # 主要夺控点坐标 except Exception as e: common.echosentence_color('wgsdata > mainCity():{}'.format(str(e))) raise
def tonggeCheck(list_obops, list_ubops): '''算子是否处于同格交战状态,''' try: for obop in list_obops: list_result_bops = common.getSpecifiedBopByPos(list_ubops, obop.ObjPos, obj_type = -1) obop.ObjTongge = 1 if list_result_bops is not None else 0 if obop.ObjTongge == 0: obop.ObjTonggeOrder = obop.ObjTonggeShootCountLeft = 0 except Exception as e: common.echosentence_color('wgruler > tonggeCheck():{}'.format(str(e))) raise e
def updateSDData(self): ''' 更新态势数据,放在成员变量dic_metadata中 :return: ''' try: # 时间信息 self.dic_metadata['l_stage'] = self.obj_interface.getSimTime() # 我方算子 self.dic_metadata['l_obops'] = [] df_myOp = self.obj_interface.getSideOperatorsData() for index, row in df_myOp.iterrows(): bop = wgobject.Gen_Op(row) bop = wgruler.cvtMapBop2AIBop(bop, self.dic_metadata['l_stage']) self.dic_metadata['l_obops'].append(bop) # 敌方算子 self.dic_metadata['l_ubops'] = [] df_enemyOp = self.obj_interface.getEnemyOperatorsData() for index, row in df_enemyOp.iterrows(): #敌方算子不包括血量为0的算子 bop = wgobject.Gen_Op(row) bop = wgruler.cvtMapBop2AIBop(bop, self.dic_metadata['l_stage']) self.dic_metadata['l_ubops'].append(bop) # 堆叠检查 wgruler.stackCheck(self.dic_metadata['l_obops']) wgruler.stackCheck(self.dic_metadata['l_ubops']) #同格检查 wgruler.tonggeCheck(self.dic_metadata['l_obops'], self.dic_metadata['l_ubops']) wgruler.tonggeCheck(self.dic_metadata['l_obops'], self.dic_metadata['l_ubops']) #城市列表 df_city = self.obj_interface.getCityData() df_city = df_city.sort_values(by='C1', ascending=True) self.dic_metadata['l_cities'] = [] dic_color2flag = {'GREEN': -1, 'RED': 0, 'BLUE': 1} for index, row in df_city.iterrows(): self.dic_metadata['l_cities'] += [ row.MapID, dic_color2flag[row.UserFlag], row.C1 ] except Exception as e: common.echosentence_color(" " + str(e)) self.__del__() raise except KeyboardInterrupt as k: common.echosentence_color(" " + str(k)) self.__del__() raise
def updateNotMyCityList(l_cities, flag_color): '''更新非我方城市列表''' try: assert len(l_cities) % 3 == 0 list_valid_indexs = [ i for i in range(len(l_cities) // 3) if l_cities[i * 3 + 1] != flag_color ] return [l_cities[i * 3] for i in list_valid_indexs] except Exception as e: common.echosentence_color('wgsdata > updateNotMyCityList():{}'.format( str(e))) raise
def stackCheck(list_bops): '''算子的堆叠检查''' try: for cur_index, cur_bop in enumerate(list_bops): flag_stack = False for inter_index, inter_bop in enumerate(list_bops): if cur_index != inter_index and cur_bop.ObjPos == inter_bop.ObjPos: flag_stack = True break cur_bop.ObjStack = 1 if flag_stack else 0 except Exception as e: common.echosentence_color('wgruler > stackCheck():{}'.format(str(e))) raise
def Shooting(list_g_stage, bop_attacker, bop_obj): '''外部规则针对射击动作的判断(只关注射击动作) 第一批: 'S' (射击) | 'N'(不允许射击) | 'MS' 移动射击组合动作(针对坦克) | 'TS' 测试射击能力(针对战车/人员在机动阶段可以射击,需要测试是否保留该射击能力到最终阶段的情况) 给定参数: 攻击算子bop_attacker, 目标算子 bop_obj, 返回bop_attacker能够对bop_obj的射击动作类型 ''' try: # 处于同格状态的算子不能做射击动作 if bop_attacker.ObjTongge == 1 or bop_obj.ObjTongge == 1: return 'N' #2018年10月24日添加:处于同格的算子不能被射击 # 被压制的人员算子无法射击(同时也无法机动) if bop_attacker.ObjTypeX == 2 and bop_attacker.ObjKeep == 1: return 'N' # 处于行军状态的算子(车辆算子)无法射击 if bop_attacker.ObjTypeX <= 1 and bop_attacker.ObjPass == 1: return 'N' # 分算子考虑, 只关注射击动作 # if list_g_stage [1] % 2 == bop_attacker.GameColor: #我方阶段 if wgstage.isMyStage(list_g_stage, bop_attacker.GameColor): #我方阶段 # if list_g_stage[2] == 1: # 机动环节 if wgstage.isMoveHuanJie(list_g_stage): # 机动环节 if bop_attacker.ObjTypeX == 0: # 坦克 if bop_attacker.ObjAttack == 0: # 未射击过 if bop_attacker.ObjStep == bop_attacker.ObjStepMax: # 2018年10月24日添加:坦克未机动不能射击 return 'N' return 'MS' if bop_attacker.ObjStep > 0 else 'S' else: return 'N' # 已射击过 if bop_attacker.ObjTypeX >= 1: # 战车与人员 if bop_attacker.ObjAttack == 0 and bop_attacker.ObjRound == 0: # 未射击过+未机动过 if bop_obj.ObjAttack == 1: return 'S' # 对方算子射击过,我方作掩护射击 else: return 'TS' if bop_attacker.ObjFlagMoving == 1 else 'N' #保留机动能力,在最终阶段射击 else: return 'N' else: # 对方阶段 # if list_g_stage[2] == 1:# 机动环节, 我方算子作机会射击 if wgstage.isMoveHuanJie(list_g_stage): # 机动环节, 我方算子作机会射击 if bop_attacker.ObjAttack == 0 and bop_attacker.ObjRound == 0 and bop_obj.ObjRound == 1: return 'S' else: return 'N' # if list_g_stage[2] == 2:#最终射击环节 if wgstage.isMyFinalShootHuanJie(list_g_stage, bop_attacker.GameColor): if bop_attacker.ObjAttack == 0 and bop_attacker.ObjRound == 0: return 'S' else: return 'N' return 'N' except Exception as e: common.echosentence_color('wgruler > Shooting():{}'.format(str(e))) raise
def timeIsout(self): ''' 游戏时间是否结束 :return: True/是 False/否 ''' try: return self.obj_interface.flagTimeOut() except Exception as e: common.echosentence_color(" " + str(e)) self.__del__() raise except KeyboardInterrupt as k: common.echosentence_color(" " + str(k)) self.__del__() raise
def getSpecifiedNeighFromDirList(self, list_dir_index=None): try: assert self.col and self.row and len(list_dir_index) <= 6 list_neigh_loc = [] ji_flag = self.row % 2 == 1 list_neighdir_offset = common.list_neighdir_offset_ji if ji_flag else common.list_neighdir_offset_ou for dir_index in list_dir_index: assert dir_index < 6 and dir_index >= 0 list_neigh_loc.append(tuple(np.add((self.row, self.col), list_neighdir_offset[dir_index]))) return list_neigh_loc except Exception as e: common.echosentence_color('error in class HEX_OFF getSpecifiedNeigh():{}'.format(str(e))) raise
def haveMoved(bop, list_g_stage): ''' 判断算子在当前阶段是否已经机动过 机动要分我方/敌方两个阶段(算子只能在属于自己的机动阶段进行机动) BUG: 该函数目前只能用于我方算子 ''' try: if bop.ObjRound == 0: return False round_num = wgstage.getStageId(list_g_stage) # if list_g_stage[1] % 2 == bop.GameColor : if wgstage.isMyStage(list_g_stage, bop.GameColor): return True if bop.ObjRound == round_num else False else: return True if bop.ObjRound == round_num - 1 else False except Exception as e: common.echosentence_color('wgruler > haveMoved():{}'.format(str(e))) raise
def hasBeenKept( bop, list_g_stage): '''判断算子是否被压制在当前阶段是否被压制 在每个回合地第1个阶段移除红方标志; 在每个回合的第3个阶段移除蓝方标志 ''' try: round_num = wgstage.getStageId(list_g_stage) if bop.ObjKeep == 0 : return False if bop.ObjKeep == round_num: return True else: if bop.GameColor == 0: expected_num = round_num - (round_num % 4 + 1) if round_num % 4 < 3 else round_num else: expected_num = (round_num - 1) // 4 * 4 + 1 return False if expected_num > bop.ObjKeep else True except Exception as e: common.echosentence_color('wgruler > hasBeenKept():{}'.format ( str ( e ) )) raise
def oneWin(self): ''' 是否一方胜利 :return: True/是 False/否 ''' try: num_obops, num_ubops = len(self.dic_metadata['l_obops']), len( self.dic_metadata['l_ubops']) return num_obops == 0 except Exception as e: common.echosentence_color(" " + str(e)) self.__del__() raise except KeyboardInterrupt as k: common.echosentence_color(" " + str(k)) self.__del__() raise