遊戲服務器挖礦系統

問題

此題來自NF框架羣友一實際需求:

有個金礦裏面有 N個資源,玩家可以去採礦攜帶上限是M,每個人採集速度都是 S/秒。 這個礦有個定時提醒服務,有人達到上限了會給這個人發出提醒。如果金礦枯竭了會給所有人發出提醒。 這個系統可能會因爲故障暫停服務,但數據不會丟失,要求系統重新上線後,能繼續提醒服務。

其實就是世界占城型戰略類遊戲的資源挖掘系統,需要考慮到服務器可能重啓要保證停服不停時間。

遂於三分鐘之內找出思路,描述過程省略不寫,經後續整理得
一個挖掘者主隊列(如果有未來開始挖,就再加一個事件副隊列,用來動態控制遊戲狀態),作爲改進,可以將挖掘者主隊列改爲金礦超隊列(隊列的隊列),超隊列中每個元素爲挖掘者隊列

方法

workResult cancelWorker(workerID) 提前中止一個挖掘者
insertWorker 加入挖掘者
getNextEventTick() 獲取下一次模塊事件的時機
updateUntilOneEvent(tick) 推進至多一個事件,(即至多推進到有挖掘者結束任務,或金礦耗盡)
updateUntilTick(tick) 連續推進時間直至某時刻

變量

總挖掘速率
金礦量
挖礦系統當前時刻
(可選的,每個金礦耗盡時刻,如果需要支持耗盡後挖掘者待命直至金礦補充)

方法簡介

挖掘者隊列的排序依據爲“簡單挖礦結束時刻”(忽視金礦耗盡)=單位剩餘攜帶量/單位挖掘速度
insertWorker/cancelWoker 插入移除挖掘者時,更新“總挖掘速率”及其他處理。
getNextEventTick 根據min(“金礦簡單耗盡時刻”=金礦餘量/總挖掘速率,“挖掘者隊列第一個結束挖掘時刻”)對比,取小值即爲下一個事件、時刻。
updateUntilOneEvent 推進直至下一個事件時刻:彈出結束挖掘者,或執行金礦耗盡處理。
updateUntilTick:反覆調用upateUntilOneEvent直至系統內部時間追上外部時間,大體代碼爲爲:
 for(;!下一次事件超出服務器時刻;)
  upateUntilOneEvent(getNextEventTick());
  根據需要和事件副隊列進行穿插執行,用於處理有挖掘者提前中止及改變速率等。

通常不建議使用updateUntilTick,因爲可以用updateUntilOneEvent和系統外部做交互混插。

性能

插入移除挖掘者,複雜度爲O(logN)
處理一個挖掘者,複雜度爲O(1)
處理所有挖掘任務,整體複雜度約爲O(挖掘者數量)

適用

該算法超越了原始需求,可用於處理系統重啓快進、即時處理。支持中斷,單位獨立速率,改變速率,耗盡待命,多金礦、和其他系統模塊交互等。時間精度可隨意設置。性能最優。

當然本算法亦可改爲戰鬥事件算法、任務……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章