date: 2017-08-29
title: 「golang筆記:遊戲中排行榜的實現」
draft: false
categories:
遊戲開發中排行榜經常出現,接觸過的排行榜有兩種。一種是由玩家挑戰排名比自己靠前的其他玩家,勝利後交換位置;另一種是根據玩家的某特性對所有玩家進行排序。第一種只涉及到兩個玩家資料的變化,實現起來比較簡單,因此只記錄第二種情況。
思路一。如果用關係型資料庫的話,實現排行版比較簡單,一條sql即可。由於遊戲伺服器併發量大、排行榜資料變化頻繁,用sql顯然不合適。
思路二。用陣列作為排行榜存放玩家資訊並對其進行排序。有新玩家加入或玩家等級變化時,重新排序。這樣的好處是獲取特定排名的玩家時很快,時間複雜度僅僅是o(1)。但是獲取某玩家的排名時需要遍歷整個陣列,時間複雜度是o(n)。有新玩家加入或玩家資訊有變化時,需要重新排序,以歸併排序為例,其平均時間複雜度為o(nlogn)。每次更新排行榜都需要排序,不斷地排序似乎並不優雅。於是考慮定期排序,如每分鐘排一次序。
思路三。思路二的情況下,如果某玩家的排名上公升了1000名,運算元組就要把被他超越的1000個玩家資料都向後移動。於是考慮了使用鍊錶替代陣列。但是這就帶來了新的問題,通過排名獲取玩家時,就要遍歷鍊錶,思路二中這個操作的時間複雜度為o(1),現在就變成了o(n)。故不能使用鍊錶,或者說不能直接使用普通的鍊錶。
思路四。借助redis。網上搜尋一番,似乎大家都是用redis的zset來處理排行榜,看了一些介紹覺得靠譜。然鵝,專案中沒用使用redis,為了乙個小的功能加上乙個redis似乎不太必要。幸運的是,專案中用到了ssdb,這貨號稱相容redis的api。
完美解決?呵呵。寫到一半時發現ssdb文件中關於zrank有這麼一句話:
important! this method may be extremly slow! may not be used in an online service.redis處理zset用的是乙個特殊的跳表,不妨自己實現乙個一模一樣的。
然而 不會 嫌麻煩。既然redis是開源的,照搬過來就好了。
還沒搬完,只是簡單實現了幾個基本的需求,歡迎pr
AppStore排行榜遊戲安利 目錄
文字以下資料來自 七麥資料 正文 正值3月初,看了一眼遊戲排行榜,準備對當前遊戲排行榜前10 免費榜,暢銷榜 做乙個同類分析。以下為來自七麥資料的今日遊戲榜單 1.免費榜 2.暢銷榜 所有遊戲都過一遍貌似不是特現實,就選擇幾個我比較感興趣的做乙個簡單的 測評 以下是對這些遊戲做乙個簡單的歸類 一.操...
微信小遊戲獲取排行榜
儲存每個使用者的分數 獲取好友列表,並獲取好友的分數 渲染排行榜 步驟一 獲取當前使用者託管資料當中對應 key 的資料。該介面只可在開放資料域下使用 wx.setusercloudstorage object 例如 儲存最高分 var score 100 var kvscore wx.setuse...
遊戲排行榜系統設計 有感
需求 1 玩家在點選穿 脫裝備需要重新計算戰鬥力 2 玩家可以檢視自己的戰鬥力及排名 3 戰鬥力前100名的玩家名稱以及戰鬥力大小隨時可以查詢,且準確性100 4 為了準確性,任意兩個玩家同時檢視自己的戰鬥力時,戰鬥力高的玩家排名必須高 5 玩家數量龐大,可能達到百萬級別 需求解析 1 戰鬥力就是個...