Unity實戰篇:實現連連看死局判定(一:資料結構的選擇以及基本思路概述)
阿新 • • 發佈:2018-12-21
最近在做連連看小遊戲,整體完成的差不多,還差一個死局判定,若為死局,即重新洗牌。
由於專案結構較為繁雜,建議大家先下載原始碼
原始碼下載連結:https://gitee.com/NKG/UnityWorks/blob/master/UnityPackages/LinkUp.unitypackage
和群裡的大神討論後,決定使用有向鄰接表這一資料結構思想來實現這個目的。
直接講實現方法也沒用,先來複習一下C++版的鄰接表吧
https://blog.csdn.net/qq_15020543/article/details/84178417
針對連連看這個專案,因為我們只需要將相同的牌存在一個連結串列裡,所以我們可以利用C#自帶的連結串列結構,字典結構,結合泛型來實現(有向鄰接表思想)實現起來是比較容易的。
/// <summary>
/// 水果結點
/// </summary>
public class FruitNode
{
/// <summary>
/// X下標
/// </summary>
public int X;
/// <summary>
/// Y下標
/// </summary>
public int Y;
}
/// <summary> /// 用來檢測死局的有向鄰接表 /// </summary> public static Dictionary<int, LinkedList<FruitNode>> MapCollect = new Dictionary<int, LinkedList<FruitNode>>();
/// <summary> /// 向鄰接表表中新增元素 /// </summary> /// <param name="x">x座標</param> /// <param name="y">y座標</param> /// <param name="value">水果型別</param> private void AddItemToLinklist(int x, int y, int value) { if (MapCollect.ContainsKey(value)) { FruitNode fruitNode = new FruitNode(x, y, value); MapCollect[value].AddLast(fruitNode); } else { FruitNode fruitNode = new FruitNode(x, y, value); LinkedList<FruitNode> tempFruitNodes = new LinkedList<FruitNode>(); tempFruitNodes.AddLast(fruitNode); MapCollect.Add(value, tempFruitNodes); } }
/// <summary>
/// 依照當前地圖生成鄰接表
/// </summary>
public void CreateMapLink()
{
for (int i = 1; i < RowNum; i++)
{
for (int j = 1; j < ColumNum; j++)
{
AddItemToLinklist(j,i,TestMap[j,i]);
}
}
}
資料結構已經建立好了,那麼具體方法為
1.玩家每次進行消除操作就更新此資料結構,並且判定是否為死局
- 遍歷字典,判斷其中的結點能否滿足消除條件(消除邏輯已完善)
- 若找到可消除的,即返回,繼續遊戲
- 若沒找到可消除的,重新洗牌
2.儘管已經做了演算法上的優化,但可以預見,他仍是一個比較消耗效能的操作,所以我準備新開一個執行緒讓它執行判斷。
選擇有向鄰接表這一資料結構用來做死局判定,優勢有:
- 時間複雜度低,只需要構建有向鄰接表的時候完整遍歷一次二維陣列,維護的時候就比較輕鬆了。舉個例子,10x10的矩陣,你直接要判定是否死局,最壞情況就是O(100^100)的時間複雜度。如果用有向鄰接表...還真不好說是多少,反正比直接用矩陣好的多得多。
- 便於維護,由於是有向鄰接表,刪除結點只需要找到它刪除就行了,時間複雜度為O(1),這同時也是為什麼不用無向鄰接表的理由,因為無向鄰接表你要刪除兩個地方。不方便。