日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

游戏对战匹配逻辑小结

發(fā)布時間:2024/3/13 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 游戏对战匹配逻辑小结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

近期接觸了到了游戲后臺的匹配邏輯,寫此文作記錄,也給后來者一些參考。
本文主要是對邏輯的一些整理,真正使用的時候還需根據實際場景來。

場景與需求

  • 玩家去匹配戰(zhàn)斗力與自己類似的其他玩家。如果在一定區(qū)間找不到對手,那就擴展區(qū)間。
  • 連續(xù)匹配兩次,不能匹配到相同的玩家。
  • 如果已經戰(zhàn)斗過的玩家,在一定時間內不能再被匹配到。(此處假設5分鐘內不能再被匹配到,5分鐘之后需要又可以被匹配到)
  • 數據結構

    根據上面幾個需求,得出以下初步結論:

  • 至少要有兩個List,一個是可以匹配的玩家的List,另一個是已經戰(zhàn)斗過的玩家的List。
  • 由于需要根據不同戰(zhàn)斗力來匹配不同的玩家,所以要根據不同戰(zhàn)斗力,分出多個List。
  • 需要隨時可以獲取到每個用戶上次戰(zhàn)斗的時間,這樣才能讓用戶過了5分鐘后又可以匹配到。
  • 根據這三點,目前的結構是這樣的:

    //上次戰(zhàn)斗的時間private final HashMap<String,Long> battleTimeMap=new HashMap<>();//不能戰(zhàn)斗的隊列private final LinkedList<String> unableBattleList=new LinkedList<>();//根據戰(zhàn)力分區(qū)private final HashMap<Integer,LinkedList<String>> enableBattleMap=new HashMap<>();

    匹配邏輯

    已經可以確定是從一個List中選出被對戰(zhàn)的玩家,選擇的方式其實是兩種:順序讀和隨機讀。

    由于隨機匹配兩次,不能匹配到相同的玩家,所以隨機讀是很不方便的,于是就確定使用順序讀。

    匹配的時候有一個場景的問題是必須解決的:

    用戶匹配到的對手,不一定會選擇戰(zhàn)斗,也可能直接退出匹配界面,或者換一個匹配的對手。
    這時候,被匹配到,但卻沒有戰(zhàn)斗過的用戶仍應該在可被匹配的List中。

    于是結構就變成了這樣:

    //上次戰(zhàn)斗的時間private final HashMap<String,Long> battleTimeMap=new HashMap<>();//不能戰(zhàn)斗的隊列private final LinkedList<String> unableBattleList=new LinkedList<>();//根據戰(zhàn)力分區(qū)private final HashMap<Integer,LinkedList<String>> enableBattleMap=new HashMap<>(); //是否可以被匹配private final HashSet<String> enableBattleSet=new HashSet<>();

    添加了一個enableBattleSet,如果戰(zhàn)斗過了,那么就不會在這個Set中。
    于是邏輯就變成了這樣:

  • 匹配的時候,如果一個玩家被匹配到,首先看下是否enableBattleSet中,如果在,那么就返回,如果不在,那就把這個玩家移出匹配List,并且匹配下一個。
  • 返回之后不移出可匹配的List,而是放到隊列末尾。(因為只有戰(zhàn)斗了才會被認為不能匹配)
  • 在戰(zhàn)斗開始后,將這個用戶從enableBattleSet中移出。(這樣在匹配的時候就不會被匹配到)
  • 戰(zhàn)斗冷卻結束邏輯

    簡單來說就是將戰(zhàn)斗冷卻結束的用戶放到可匹配的List中。

    這個大概有兩種實現方案:

  • 由玩家每次匹配,觸發(fā)戰(zhàn)斗冷卻結束的邏輯。
  • 后來放一個線程,定時去觸發(fā)戰(zhàn)斗冷卻技術的邏輯。
  • 由于隨著玩家越來越多,戰(zhàn)斗匹配的邏輯觸發(fā)會越發(fā)頻繁。但是戰(zhàn)斗冷卻結束的邏輯沒有必要那么頻繁觸發(fā),所以方案一是不合適的。

    筆者最終選擇的是方案二。

    上鎖的邏輯

    如果兩個玩家戰(zhàn)斗力類似,他們同時觸發(fā)匹配的話,可能會匹配到同樣的對手,這樣就會導致被匹配到的玩家在同一時間與兩個玩家戰(zhàn)斗。這樣顯然是不合理的,所以需要對邏輯上鎖。
    上鎖也是有兩種方案:

  • 對可匹配玩家的List上鎖
  • 對匹配函數上鎖
  • 兩種方案筆者評估下都是可行的,都各有利弊:

  • 對List上鎖。
    優(yōu)勢: 只有戰(zhàn)斗力類似的玩家同時觸發(fā)匹配邏輯才會阻塞,減小了由于“同時匹配”被阻塞的概率。
    劣勢: 如果在匹配的時候觸發(fā)了“戰(zhàn)斗冷卻結束邏輯”,那么也會被阻塞,存在請求超時風險。
  • 對匹配函數上鎖
    優(yōu)勢: 如果在匹配的時候觸發(fā)了“戰(zhàn)斗冷卻結束邏輯”,不會被阻塞。而且結束戰(zhàn)斗冷卻的玩家是被放到List尾部,所以一般情況也不會影響匹配邏輯。
    劣勢: 所有玩家中,只要有有兩個人同時觸發(fā)匹配邏輯,就會有玩家被阻塞,存在請求超時風險。
  • 一致性問題

    實際操作過程中,一個服務一般都會部署在多臺服務器上,這樣才能通過負載均衡提高并發(fā),并且在有一臺服務器出故障的時候,能保證服務正常運行。
    在這種情況下,匹配邏輯的中間過程就不能僅僅放在緩存中,而應該使用redis放在redis服務器上,這樣才能保證匹配數據只有一份,而不是每臺服務器都有一份。

    總結

    以上是生活随笔為你收集整理的游戏对战匹配逻辑小结的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。