当前位置: 首页 > news >正文

Rank-Analysis 预组队识别(英雄联盟)

1. 前言

LOL-Ranklysis 已经更新到 1.4 版本了,感觉大家的使用和反馈, https://github.com/wnzzer/lol-rank-record-analysis

对于一个英雄联盟战绩查询软件,对预组队(双排,乃至车队)的判断是至关重要的,对于对喷的理由(bushi),对于预组队的针对配合有个提前量的判断,是个非常重要的功能。

在这里插入图片描述

2. 功能实现:

首先我们需要知道,通过LOL LCU 接口不提供相关的数据,因此,我们只能通过我们自己判断是否是预组队的逻辑预判他们是不是为预组队。

我们需要知道预组队的前置条件

  1. 组队最多为 2 - 5 人
  2. 最多有 4 个队伍
  3. 好友组队的概率很高

2.1. 判断好友:

我们可以把每局遇到的玩家的 puuid 提取出来,如果在同一局,在同一个队伍超过某个次数,则判断为好友

  1. 提取对局
func getOneGamePlayers(matchHistory *client.MatchHistory) map[string][]OneGamePlayer {
	oneGamePlayerMap := make(map[string][]OneGamePlayer)
	for index, games := range matchHistory.Games.Games {
		myTeamId := games.Participants[0].TeamId
		for i := 0; i < len(games.GameDetail.ParticipantIdentities); i++ {
			oneGamePlayerMap[games.GameDetail.ParticipantIdentities[i].Player.Puuid] = append(oneGamePlayerMap[games.GameDetail.ParticipantIdentities[i].Player.Puuid], OneGamePlayer{
				Index:          index,
				GameId:         games.GameId,
				GameCreatedAt:  games.GameCreationDate,
				IsMyTeam:       myTeamId == games.GameDetail.Participants[i].TeamId,
				GameName:       games.GameDetail.ParticipantIdentities[i].Player.SummonerName,
				TagLine:        games.GameDetail.ParticipantIdentities[i].Player.TagLine,
				ChampionId:     games.GameDetail.Participants[i].ChampionId,
				ChampionBase64: client.GetChampionBase64ById(games.GameDetail.Participants[i].ChampionId),
				Kills:          games.GameDetail.Participants[i].Stats.Kills,
				Deaths:         games.GameDetail.Participants[i].Stats.Deaths,
				Assists:        games.GameDetail.Participants[i].Stats.Assists,
				Win:            games.GameDetail.Participants[i].Stats.Win,
				QueueIdCn:      client.QueueIdToCn[games.QueueId],
			})
		}
	}
	return oneGamePlayerMap
}


  1. 添加到好友队列,比如大于 3 局为队友的数量
				if teamCount >= friendThreshold {
					theTeams = append(theTeams, puuid)
				}

2.3. 过滤好友队列:

  1. 我们可以查询本局的十个玩家,每个人的可以的好友队列提取出来之后
  2. 再与当前对局的玩家取交集,去掉不是该对局的玩家
	// 统一处理 TeamOne 和 TeamTwo 的逻辑,把可能的队伍存入 allMaybeTeams
	processTeamForMarkers := func(team []SessionSummoner) {
		for _, sessionSummoner := range team {
			var theTeams []string
			for puuid, playRecordArr := range sessionSummoner.UserTag.RecentData.OneGamePlayersMap {

				// 如果不在当前对局中,跳过这个玩家的统计
				if !currentGamePuuids[puuid] {
					continue
				}

				teamCount := 0
				for _, playRecord := range playRecordArr {
					if playRecord.IsMyTeam {
						teamCount++
					}
				}
				if teamCount >= friendThreshold {
					theTeams = append(theTeams, puuid)
				}
			}
			allMaybeTeams = append(allMaybeTeams, theTeams)
		}
	}

	// 分别处理 TeamOne 和 TeamTwo
	processTeamForMarkers(sessionData.TeamOne)
	processTeamForMarkers(sessionData.TeamTwo)

2.4. 合并子区间

如果两个都是好友,一个人玩的多,一个人玩的少,玩的多的人提供的数据范围可能更大,对于多人组队识别的准确率会更高,因此要合并子区间,保留较大的区间

func removeSubsets(arrays [][]string) [][]string {
	// 按数组长度排序,确保先处理较大的数组
	sort.Slice(arrays, func(i, j int) bool {
		return len(arrays[i]) > len(arrays[j])
	})

	// 存储去重后的结果
	var result [][]string
	for _, arr := range arrays {
		// 判断当前数组是否被其他数组包含
		isSubsetFlag := false
		for _, resArr := range result {
			if isSubset(arr, resArr) {
				isSubsetFlag = true
				break
			}
		}
		// 如果当前数组没有被包含,就加入结果
		if !isSubsetFlag {
			result = append(result, arr)
		}
	}
	return result
}

2.5. 与当前对局同一队伍取交集

虽然我们前面过滤了一遍,但是并不是很严谨,只是粗过滤,实际上,好友也可能排到对面去,因此,我们需要把待映射好友队列,与红蓝两队取交集,理论上交集的结果最多有一队大于 2 个人。就把结果映射上去。

	var mergedTeams [][]string
	mergedTeams = removeSubsets(allMaybeTeams)

	// 标记预组队信息
	constIndex := 0
	preGroupMakerConsts := []PreGroupMaker{
		{Name: "队伍1", Type: "success"},
		{Name: "队伍2", Type: "warning"},
		{Name: "队伍3", Type: "error"},
		{Name: "队伍4", Type: "info"},
	}

	for _, team := range mergedTeams {
		marked := false
		intersectionTeamOne := intersection(team, teamOnePuuids)
		intersectionTeamTwo := intersection(team, teamTwoPuuids)
		if len(intersectionTeamOne) >= theTeamMinSum {
			for i := range sessionData.TeamOne {
				sessionSummoner := &sessionData.TeamOne[i]
				if oneInArr(sessionSummoner.Summoner.Puuid, intersectionTeamOne) && sessionSummoner.PreGroupMarkers.Name == "" {
					sessionSummoner.PreGroupMarkers = preGroupMakerConsts[constIndex]
					marked = true
				}
			}

		} else if len(intersectionTeamTwo) >= theTeamMinSum {
			for i := range sessionData.TeamTwo {
				sessionSummoner := &sessionData.TeamTwo[i]
				if oneInArr(sessionSummoner.Summoner.Puuid, intersectionTeamTwo) && sessionSummoner.PreGroupMarkers.Name == "" {
					sessionSummoner.PreGroupMarkers = preGroupMakerConsts[constIndex]
					marked = true
				}
			}
		}
		if marked {
			constIndex++
		}
	}
}

这里的 type 用于区分前端显示颜色,无其他用途

3. 后记:

预组队识别是很好用且项目组较繁琐的功能,旨在一步步拆解功能的实现即可,如果想更深的了解这个 lcu 的项目,请前往 https://github.com/wnzzer/lol-rank-record-analysis 了解更多详情哦!

相关文章:

  • Qwen2-VL 的重大省级,Qwen 发布新旗舰视觉语言模型 Qwen2.5-VL
  • Flask和Django相比哪个更适合新手?
  • mac搭建环境
  • 【第2章:神经网络基础与实现——2.2反向传播算法详解与实现步骤】
  • 冒泡排序的缺陷及优化
  • ASP.NET Core SixLabors.ImageSharp 位图图像创建和下载
  • 2月14日情人节,致挚爱
  • Linux 驱动开发:字符设备、块设备与网络设备驱动详解​​
  • Linux驱动层学习:LED 驱动开发
  • 前端开发入门一
  • c# 对象属性拷贝 解决方案
  • NPDP学习笔记 -产品经理(第二版)-第二章 组合管理
  • 为什么vue3需要对引入的组件使用markRaw?
  • 【Elasticsearch】词项中心(term-centric)和字段中心(field-centric)
  • 10bit VS 8bit 视频:色彩深度的较量,谁才是视觉盛宴的王者?
  • 【Sceneform-EQR】实现3D场景背景颜色的定制化(背景融合的方式、Filament材质定制)
  • OpenLayer创建第一个基础地图实例
  • “集团企业浪潮”(Conglomerate Wave):市盈率套利(P/E Arbitrage)与每股盈利增长的幻象
  • 基于深度学习的半导体领域关键技术创新与应用突破
  • python调用多平台deepseek等大模型api
  • 四川观察最新新闻/seo网站关键词优化工具
  • 大连网站建设比较好的公司/即时热榜
  • 怎么不花钱建网站/seo排名公司
  • 网站后台上传图片不显示/百度竞价推广是什么意思
  • 京东网上购物/福州seo外包公司
  • 个人网站能允许做哪些/google 官网入口