def _calc_query_melee_ranking(self, proxy, user_id, scores_range, req, timer): cache_proxy = DataProxy() self_arena = proxy.get_result("melee", user_id) self_ranking = proxy.get_ranking("melee", "score", user_id) + 1 cache_proxy.search("user", user_id) all_arenas = {} all_arenas_rank = {} player_rankings = {} for range in scores_range: arena_list = proxy.get_rank_score_result("melee", "score", range[0], range[1], 0, MELEE_COUNT) #按照积分先排序 arena_list.sort(lambda x, y: cmp(ArenaInfo.get_real_score( x.score), ArenaInfo.get_real_score(y.score)), reverse=True) arena_rank = 1 for arena in arena_list: all_arenas[arena.user_id] = arena all_arenas_rank[arena.user_id] = arena_rank arena_rank = arena_rank + 1 cache_proxy.search("user", arena.user_id) defer = cache_proxy.execute() defer.addCallback(self._query_melee_ranking_succeed, user_id, self_arena, self_ranking, all_arenas, all_arenas_rank, req, timer) return defer
def pack_arena_info(user, arena, message, now, ranking = 0, with_own = True): """ranking [int] 0表示不需要排名信息 """ message.index = arena.index #描述 message.open_time_des = data_loader.ServerDescKeyInfo_dict["arena_open_time"].value.encode("utf-8") if not user.allow_pvp_arena: message.status = 3 #锁定 message.end_time = 0 return if arena.is_arena_active(now): message.status = 2 #激活 else: message.status = 1 #未激活 message.coin = arena.coin message.end_time = arena.next_time - now message.refresh_num = arena.refresh_num if with_own: message.own.ranking_index = ranking message.own.score = ArenaInfo.get_real_score(arena.score)
def update_arena_offline(data, user, arena): """离线更新演武场信息 """ ##积分衰减 #score = ArenaInfo.get_real_score(arena.score) #decay = float(data_loader.OtherBasicInfo_dict["ArenaScoreDecay"].value) #new_score = int(score * decay) #score_diff = new_score - score #arena.add_score(score_diff) #积分清零 #score = ArenaInfo.get_real_score(arena.score) #score_diff = 0 - score #arena.add_score(score_diff) #积分衰减(退一档,低于等于1600就不再衰减) decay_score = arena.calc_decay_score() score_diff = decay_score - ArenaInfo.get_real_score(arena.score) arena.add_score(score_diff) #清除对战记录 record_id = [] for record in data.arena_record_list.get_all(True): record_id.append(record.id) for id in record_id: data.arena_record_list.delete(id) #根据主公等级重新分配房间 arena.update_index(user.level) #重置演武场最高段位 arena.reset_highest_title_level() #乱斗场清理 #积分清零 melee = data.melee.get() decay_score = melee.calc_decay_score() score_diff = decay_score - MeleeInfo.get_real_score(melee.score) melee.add_score(score_diff) #清除对战记录 record_id = [] for record in data.melee_record_list.get_all(True): record_id.append(record.id) for id in record_id: data.melee_record_list.delete(id) #根据主公等级重新分配房间 melee.update_index(user.level) #重置演武场最高段位 melee.reset_highest_title_level() return True
def _get_users(self, proxy, min_score, max_score, arenas, arena_rankings, users): """ users(out: 元组(userid, name, level, icon_id, title_level, score, ranking_index)) """ results = proxy.get_all_result("user") for user in results: users.append( (user.id, user.get_readable_name(), user.level, user.icon_id, arenas[user.id].title_level, ArenaInfo.get_real_score(arenas[user.id].score), arena_rankings[user.id])) return True
def _select_players_info(self, proxy, data, arena, players_rank): """查询玩家的主公信息、阵容和战斗科技 """ users_id = [] users_arena = {} users_arena_ranking = {} for rank in players_rank: if rank > self.users_count: #超过本房间人数则跳过 continue results = proxy.get_rank_result( "arena", "score", self.rank_base + rank - 1, self.rank_base + rank - 1) if len(results) == 0: continue #匹配到玩家自己,舍弃 if results[0].user_id == data.user.get(True).id: continue #匹配到积分为0的玩家,舍弃 if ArenaInfo.get_real_score(results[0].score) == 0: continue #assert len(results) == 1 user_id = results[0].user_id users_id.append(user_id) users_arena[user_id] = results[0] users_arena_ranking[user_id] = rank cache_proxy = DataProxy() for user_id in users_id: cache_proxy.search("user", user_id) #查询主公信息 cache_proxy.search("guard", user_id) #查阵容 cache_proxy.search_by_index("technology", "user_id", user_id) #查战斗科技 defer = cache_proxy.execute() defer.addCallback(self._select_teams, data, arena, users_id, users_arena, users_arena_ranking) return defer
def calc_battle_score(arena, rival_score): """计算单场得分 Args: arena(ArenaInfo): 己方竞技场信息 rival_score(int): 对手积分 """ self_score = ArenaInfo.get_real_score(arena.score) D = abs(self_score - rival_score) #P for i in data_loader.ELOBasicInfo_dict: elo = data_loader.ELOBasicInfo_dict[i] if D >= elo.lowerLimitScore and D <= elo.upperLimitScore: if self_score >= rival_score: P = float(elo.expectationA) else: P = float(elo.expectationB) break #K1 得分系数与段位相关 key = "%s_%s" % (arena.index, arena.title_level) K1 = float(data_loader.GradeBasicInfo_dict[key].factorK1) #K2 连胜连败修正系数 max_num = max(data_loader.ArenaContinuousWinRepairFactor_dict.keys()) min_num = min(data_loader.ArenaContinuousWinRepairFactor_dict.keys()) #胜 if arena.continuous_win_num >= 0: num_win = min(max_num, arena.continuous_win_num + 1) else: num_win = min(max_num, 1) #负 if arena.continuous_win_num < 0: num_lose = max(min_num, arena.continuous_win_num - 1) else: num_lose = max(min_num, -1) continuous_factor = data_loader.ArenaContinuousWinRepairFactor_dict[ num_win] K2_win = float(continuous_factor.factor) continuous_factor = data_loader.ArenaContinuousWinRepairFactor_dict[ num_lose] K2_lose = float(continuous_factor.factor) #K3 场次修正系数 max_num = max(data_loader.ArenaNumRepairFactor_dict.keys()) num = min(max_num, arena.total_num) num_factor = data_loader.ArenaNumRepairFactor_dict[num] if num_factor is None: max_num = 0 for i in data_loader.ArenaNumRepairFactor_dict: num = data_loader.ArenaNumRepairFactor_dict[i].num if max_num < num: max_num = num num_factor = data_loader.ArenaNumRepairFactor_dict[max_num] K3 = float(num_factor.factor) R = 1 win_score = K1 * K2_win * K3 * (R - P) R = 0 lose_score = K1 * K2_lose * K3 * (R - P) logger.debug( "Calc arena battle score[D=%d][P=%f][K1=%d][K2_win=%d][K2_lose=%d][K3=%d][win_score=%d][lose_score=%d]" % (D, P, K1, K2_win, K2_lose, K3, win_score, lose_score)) #打胜最低也能得30分,避免出现0积分的情况 return (max(35, int(win_score)), int(lose_score))
def _set_rivals_info(self, proxy, data, arena, rivals, users, heroes_id, tech_basic_ids): rivals_user_id = [] rivals_battle_score = [] rivals_score = [] rivals_info = [] for i in rivals: rival = rivals[i] #对手阵容中英雄信息 rival_heroes = [] heroes_id = rival.get_heroes_id() for hero_id in heroes_id: if hero_id == 0: rival_heroes.append(None) else: hero = proxy.get_result("hero", hero_id) rival_heroes.append(hero) spoils = reward_module.random_pve_spoils(users[rival.rival_id].level) rival.set_pvp_enemy_detail(users[rival.rival_id], rival_heroes, items = spoils, technology_basic_ids = tech_basic_ids[rival.rival_id]) rivals_user_id.append(rival.rival_id) rivals_battle_score.append(rival.score) rivals_score.append(rival.win_score) rivals_info.append(rival) #演武场搜出来的对手不足3人,pve补上 rivals_id = arena.generate_arena_rivals_id() pve_user_id = 0 #rival为pve类型的user_id for i in range(3 - len(rivals)): rival_id = rivals_id[i + len(rivals)] rival = data.rival_list.get(rival_id) if rival is None: rival = RivalInfo.create(rival_id, data.id) data.rival_list.add(rival) #pve匹配的战力范围 key = data.user.get(True).level - 3 #演武场需主公17级才开启 match_info = data_loader.KeyNodeMatchBasicInfo_dict[key] rival.set_pve_matching_condition(NodeInfo.ENEMY_TYPE_ARENA, match_info.enemyScoreMin, match_info.enemyScoreMax) #创建pve arena数据 self_score = ArenaInfo.get_real_score(arena.score) pve_rival_score = random.randint(int(0.8 * self_score), int(1.2 * self_score)) #pve对手随机积分 pve_arena = ArenaInfo() pve_arena.add_score(pve_rival_score) pve_arena.update_index(data.user.get(True).level) pve_arena_ranking = 9999 #pve的rival排名随意给个很大的名次 arena_buff_id = pve_arena.calc_arena_buff_id(pve_arena_ranking) #只计算我方积分变化 (self_win_score, self_lose_score) = arena_business.calc_battle_score(arena, pve_rival_score) rival.set_arena(pve_user_id, 0, '', pve_rival_score, pve_arena_ranking, arena_buff_id, self_win_score, self_lose_score) logger.debug("arena rival(pve):[user_id=%d][arena_score=%d][arena_ranking=%d]" "[arena_buff_id=%d][self_win_score=%d][self_lose_score=%d]" % (pve_user_id, pve_rival_score, pve_arena_ranking, arena_buff_id, self_win_score, self_lose_score)) self._match_one_pve(rival, pve_user_id) rivals_user_id.append(pve_user_id) rivals_battle_score.append(rival.score) rivals_score.append(rival.win_score) rivals_info.append(rival) pve_user_id += 1 #若pve有多个,保证user_id不重 rivals_user_id_origin = copy.copy(rivals_user_id) #rivals_user_id按照rivals_score的高低排序 for i in range(len(rivals_score)): for j in range(i + 1, len(rivals_score)): if rivals_score[i] < rivals_score[j]: #互换积分 tmp1 = rivals_score[j] rivals_score[j] = rivals_score[i] rivals_score[i] = tmp1 #互换rival user id tmp2 = rivals_user_id[j] rivals_user_id[j] = rivals_user_id[i] rivals_user_id[i] = tmp2 #互换rival battle_score tmp3 = rivals_battle_score[j] rivals_battle_score[j] = rivals_battle_score[i] rivals_battle_score[i] = tmp3 arena.set_arena_rivals_user_id(rivals_user_id_origin) #根据情况从三个对手中选择出一个对手 if not arena.choose_rival((data.guard_list.get_all(True))[0].get_team_score(), rivals_user_id, rivals_score, rivals_user_id_origin, rivals_battle_score): logger.warning("Arena choose rival error") return False return True
def _select_teams(self, proxy, data, arena, users_id, users_arena, users_arena_ranking): """查team信息 """ cache_proxy = DataProxy() users = {} users_id_usable = [] guards = {} tech_basic_ids = {} heroes_id = {} for user_id in users_id: user_result = proxy.get_result("user", user_id) if not user_result.allow_pvp_arena: #若恰好匹配到演武场还未开启的玩家,则跳过 continue guard_result = proxy.get_result("guard", user_id) if guard_result is None: continue users[user_id] = user_result users_id_usable.append(user_id) guards[user_id] = guard_result #目前只有一个防守阵容 results = proxy.get_all_result("technology") battle_technologys = [] for result in results: if (result.user_id == user_id and not result.is_upgrade and result.is_battle_technology()): battle_technologys.append(result.basic_id) tech_basic_ids[user_id] = battle_technologys heroes_id[user_id] = utils.split_to_int(guards[user_id].teams_hero) for hero_id in heroes_id[user_id]: if hero_id != 0: cache_proxy.search("hero", hero_id) #设置rival的演武场信息 rivals = {} rivals_id = arena.generate_arena_rivals_id() for i in range(len(users_id_usable)): user_id = users_id_usable[i] rival_id = rivals_id[i] rival = data.rival_list.get(rival_id) if rival is None: rival = RivalInfo.create(rival_id, data.id) data.rival_list.add(rival) rivals[rival_id] = rival user_arena = users_arena[user_id] battle_score = guards[user_id].get_team_score() heroes = utils.join_to_string(heroes_id[user_id]) #计算积分变化 (self_win_score, self_lose_score) = arena_business.calc_battle_score( arena, ArenaInfo.get_real_score(user_arena.score)) (rival_win_score, rival_lose_score) = arena_business.calc_battle_score( user_arena, ArenaInfo.get_real_score(arena.score)) arena_buff_id = user_arena.calc_arena_buff_id(users_arena_ranking[user_id]) rival.set_arena(user_id, battle_score, heroes, ArenaInfo.get_real_score(user_arena.score), users_arena_ranking[user_id], arena_buff_id, self_win_score, self_lose_score) logger.debug("arena rival:[user_id=%d][battle_score=%d][heroes=%s][arena_score=%d]" "[arena_ranking=%d][arena_buff_id=%d][self_win_score=%d][self_lose_score=%d]" "[rival_win_score=%d][rival_lose_score=%d]" % (user_id, battle_score, heroes, ArenaInfo.get_real_score(user_arena.score), users_arena_ranking[user_id], arena_buff_id, self_win_score, self_lose_score, rival_win_score, rival_lose_score)) defer = cache_proxy.execute() defer.addCallback(self._set_rivals_info, data, arena, rivals, users, heroes_id, tech_basic_ids) return defer