database - 《部落冲突》和其他游戏如何有效地对玩家进行排名和匹配?
问题描述
所以,几天前,我研究了一个非常标准的 ELO 系统。一名球员可以攻击另一名球员的防守,并根据结果重新分配积分。
它开始运行良好,但最终排名较低的玩家无法找到匹配,因为系统查找匹配的方式是:
- 从排名第一的玩家开始
- 降低排名直到找到请求匹配的玩家
显然,如果参与者的排名接近 2000,则这导致必须请求 2,000 名玩家的数据。
所以,现在低段位的玩家都发现无法请求了。
我注意到在召唤师战争和部落冲突等其他热门游戏中,每当你的积分调整时,你的排名会立即可见,我无法想象它们会在每个玩家的列表中下降,直到他们达到 #200,000。
我无法使用想到的第一个策略(猜数字游戏),如果有 100 名玩家,请检查 #50 的点数。如果您的分数较低,请检查 #75 的,较低的:检查 #88 等。这是因为由于 OrderedDataStore 的性质,我无法在不检查 #2、#3 等的情况下检查 #50
我正在尝试以以下方式存储数据:
- 可显示前50名球员
- 一个算法可以快速找到你等级附近玩家的4个防御
- 您可以查看自己的排名
有什么解决办法吗?
解决方案
您应该能够像这样获得前 50 名玩家(假设您的排名列表简称为“排名”:
ranks.GetSortedAsync(false, 50).GetCurrentPage() -- This will just be an array of the top 50 players.
找到您排名附近的特定玩家应该像以下一样简单:
local playerRating -- set this to your player's Elo rating
local searchWidth = 5
ranks.GetSortedAsync(false, 100, playerRating - searchWidth, playerRating + searchWidth)
--[[ the above is a DataStorePages of all players within searchWidth Elo points of your player;
you may want to widen the search if matches are not found, which is why
searchWidth is a variable instead of a magic number ]]
获得排名确实是最难的部分;确实,我认为解决方案实际上可能与您所说的一致:
local playerRating -- set to player's Elo rating
local playerRank = 0
local allRanks = ranks.getSortedAsync(false, 100, playerRating)
while not allRanks.IsFinished do
allRanks.AdvanceToNextPageAsync()
playerRank = playerRank + #allRanks.GetCurrentPage()
end
playerRank = playerRank + #allRanks.GetCurrentPage() -- have to add the last page too
由于限制,最好在存储更新时将前 50 个缓存在其自己的数据存储中。
你是对的,他们可能没有对所有等级进行线性搜索,但在这里似乎这是必要的。
推荐阅读
- apache-spark - 胶水如何使用pyspark删除数据帧上的记录
- javascript - ES6 箭头函数 () 与 _
- git - 为什么 PyCharm 不验证 Git 提交
- android - 在 Kotlin 中创建 SAM 接口的实例时,为什么需要在接口名称后加上括号?
- python - Django 表单中的 HTML 必需属性
- python - 如何在python中求解雅可比椭圆函数
- python - 如何模拟随机过程,直到路径的所有元素都是正数?
- javascript - 匹配不包含特定模式的特定字符串
- java - Spring Data Jpa如何处理静态外键相关表
- reactjs - 嵌入 gatsby 项目的 Tiktok 在 Netlify 上消失了