Mar*_*nen 14 python algorithm ranking rank python-3.x
我有Player一个score属性类:
class Player(game_engine.Player):
def __init__(self, id):
super().__init__(id)
self.score = 0
Run Code Online (Sandbox Code Playgroud)
当玩家成功/未能完成目标时,该分数增加/减少.现在我需要告诉玩家他的排名超出了玩家的总数
print('Your rank is {0} out of {1}')
Run Code Online (Sandbox Code Playgroud)
首先,我想到了所有玩家的列表,以及玩家什么时候发生的事情:
但这将非常缓慢.可以有成千上万的玩家,并且玩家可以重置他自己的分数,0这意味着我必须在堆叠中移动所有人.即使找到玩家也是O(n).
我正在寻找的是一个高性能的解决方案.尽管应该使用常识,但RAM的使用并不那么重要.我怎样才能更快地改进系统?
更新信息:我每次离开游戏服务器时都会使用SQLAlchemy将玩家的数据存储到MySQL数据库中,并且每次他加入服务器时都会加载它.这些是通过'player_join'和'player_leave'事件处理:
@Event('player_join')
def load_player(id):
"""Load player into the global players dict."""
session = Session()
query = session.query(Player).filter_by(id=id)
players[id] = query.one_or_none() or Player(id=id)
@Event('player_leave')
def save_player(id):
"""Save player into the database."""
session = Session()
session.add(players[id])
session.commit()
Run Code Online (Sandbox Code Playgroud)
此外,玩家的分数会根据'player_kill'事件更新:
@Event('player_kill')
def update_score(id, target_id):
"""Update players' scores upon a kill."""
players[id].score += 2
players[target_id].score -= 2
Run Code Online (Sandbox Code Playgroud)
Redis sort sets帮助解决了这个问题(文档使用排行榜作为示例用法)http://redis.io/topics/data-types-intro#redis-sorted-sets
Redis可以用作玩家排名的缓存.应用程序启动时,从SQL数据中填充redis.在mysql中更新玩家分数时也会更新redis.
如果您有多个服务器进程/线程并且它们可以同时触发玩家得分更新,那么您还应该考虑mysql/redis更新竞争条件,例如:
| 归档时间: |
|
| 查看次数: |
1322 次 |
| 最近记录: |