| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543 | using System;using System.Collections;using System.Collections.Generic;using System.Linq;#if UNITY_EDITORusing UnityEditor;#endifusing UnityEngine;using Utility;public class WFXMapInfo{    public int x;    public int y;    public int px;    public int py;    public List<string> excludeName = new List<string>();    public List<string> showName = new List<string>();    public string currShowName;    public List<string> huiTuiName = new List<string>();    public GameObject g;}public class MyWFX : MonoBehaviour{    public MapConfig MapConfig;    public int w;    public int h;    private int[,] _indexCount;    public WFXMapInfo[,] WfxMapInfos;    public float xJg;    public float yJg;    public int startX;    public int startY;    public int suijiShu;    // public int lasetStartX;    // public int lasetStartY;    // public int lasetWidth;    // public int lasetHeight;    public List<TileMapInfo> allMapInfo = new List<TileMapInfo>();    private System.Random _random;    private List<WFXMapInfo> currFindMap = new List<WFXMapInfo>();    public bool isRun;    private bool isHuiTui;    private List<WFXMapInfo> _huiTuiMap = new List<WFXMapInfo>();    public Map<int, WFXMapInfo> currAllMapName = new Map<int, WFXMapInfo>();    private void Start()    {        StartMap();    }    [ContextMenu("测试生成.")]    public void StartMap()    {        _random = new System.Random(suijiShu);        WfxMapInfos = new WFXMapInfo[w, h];        for (int i = 0; i < w; i++)        {            for (int j = 0; j < h; j++)            {                WfxMapInfos[i, j] = new WFXMapInfo();                WfxMapInfos[i, j].x = i;                WfxMapInfos[i, j].y = j;                WfxMapInfos[i, j].px = i;                WfxMapInfos[i, j].py = j;            }        }        allMapInfo = MapConfig.allMapInfo;        RandMap(startX, startY, "zhixian");        for (int k = 0; k < allMapInfo.Count; k++)        {            if (allMapInfo[k].root.name.Equals("zhixian"))            {                WfxMapInfos[startX, startY].g = GameObject.Instantiate(allMapInfo[k].root);                WfxMapInfos[startX, startY].g.transform.position = new Vector3(startX * xJg, 0, startY * yJg);                break;            }        }        _huiTuiMap.Add(WfxMapInfos[startX, startY]);        StartCoroutine(ShengChengMap());    }    public void NewShengCheng(WFXMapInfo[,] WfxMapInfos, List<WFXMapInfo> huiTuiMap, int w, int h)    {        this.w = w;        this.h = h;        _huiTuiMap = huiTuiMap;        this.WfxMapInfos = WfxMapInfos;        StartCoroutine(ShengChengMap());    }#if UNITY_EDITOR    private void OnDrawGizmos()    {        if (WfxMapInfos == null)        {            return;        }        for (int i = 0; i < w; i++)        {            for (int j = 0; j < h; j++)            {                WFXMapInfo wfxMapInfo = WfxMapInfos[i, j];                if (wfxMapInfo.currShowName != null)                {                    Color color = Handles.color;                    Handles.color = Color.red;                    Handles.Label(new Vector3(wfxMapInfo.px * xJg, 0, wfxMapInfo.py * yJg),                        "!!" + wfxMapInfo.currShowName);                    Handles.color = color;                }                else                {                    string data = "";                    for (int k = 0; k < wfxMapInfo.showName.Count; k++)                    {                        data += wfxMapInfo.showName[k] + "_";                    }                    if (string.IsNullOrEmpty(data))                    {                        data = "无";                    }                    Handles.Label(new Vector3(wfxMapInfo.px * xJg, 0, wfxMapInfo.py * yJg), data);                }            }        }    }#endif    private void Update()    {        if (isRun)        {            return;        }        if (Input.GetMouseButtonDown(0))        {            StartCoroutine(ShengChengMap());        }    }    private IEnumerator ShengChengMap()    {        bool isFinish = false;        while (true)        {            isHuiTui = false;            currFindMap.Clear();            for (int i = 0; i < w; i++)            {                for (int j = 0; j < h; j++)                {                    WFXMapInfo wfxMapInfo = WfxMapInfos[i, j];                    wfxMapInfo.excludeName.Clear();                    wfxMapInfo.showName.Clear();                }            }            Run(0, 0);            if (isHuiTui)            {                WFXMapInfo wfxMapInfo = _huiTuiMap[_huiTuiMap.Count - 1];                Debug.Log("回退" + wfxMapInfo.x + "__" + wfxMapInfo.y);                wfxMapInfo.huiTuiName.Add(wfxMapInfo.currShowName);                wfxMapInfo.currShowName = null;                _huiTuiMap.Remove(wfxMapInfo);                continue;            }            bool isJx = false;            WFXMapInfo minMap = null;            int minCount = int.MaxValue;            int lingju = int.MaxValue;            for (int i = 0; i < w; i++)            {                for (int j = 0; j < h; j++)                {                    WFXMapInfo wfxMapInfo = WfxMapInfos[i, j];                    if (string.IsNullOrEmpty(wfxMapInfo.currShowName))                    {                        isJx = true;                    }                    else                    {                        continue;                    }                    if (wfxMapInfo.showName.Count < minCount)                    {                        minMap = wfxMapInfo;                        minCount = wfxMapInfo.showName.Count;                    }                }            }            if (!isJx)            {                isFinish = true;                break;            }            if (minMap != null)            {                bool isOk = RandMap(minMap.x, minMap.y);                if (!isOk)                {                    if (_huiTuiMap.Count <= 0)                    {                        Debug.Log("没有有效数据生成地图");                        yield break;                    }                    WFXMapInfo wfxMapInfo = _huiTuiMap[_huiTuiMap.Count - 1];                    wfxMapInfo.huiTuiName.Add(wfxMapInfo.currShowName);                    wfxMapInfo.currShowName = null;                    continue;                }                else                {                    GameObject sprite = null;                    for (int k = 0; k < allMapInfo.Count; k++)                    {                        if (allMapInfo[k].root.name.Equals(minMap.currShowName))                        {                            sprite = allMapInfo[k].root;                            break;                        }                    }                    // if (minMap.g == null)                    // {                    //     minMap.g = new GameObject(minMap.x + "__" + minMap.y);                    //     minMap.g.AddComponent<SpriteRenderer>();                    // }                    if (minMap.g != null)                    {                        GameObject.Destroy(minMap.g);                    }                    // SpriteRenderer spriteRenderer = minMap.g.GetComponent<SpriteRenderer>();                    minMap.g = GameObject.Instantiate(sprite);                    minMap.g.transform.position = new Vector3(minMap.px * xJg, 0, minMap.py * yJg);                    yield return new WaitForSeconds(0.0f);                }                if (!_huiTuiMap.Contains(minMap))                {                    _huiTuiMap.Add(minMap);                }                else                {                    Debug.Log("重复数据");                    yield break;                }            }            if (!isRun)            {                break;            }        }        if (!isFinish)        {            yield break;        }        Debug.Log("循环完成");        for (int i = 0; i < w; i++)        {            for (int j = 0; j < h; j++)            {                WFXMapInfo wfxMapInfo = WfxMapInfos[i, j];                int n = wfxMapInfo.px * 10000 + wfxMapInfo.py;                // if (currAllMapName.TryGetValue(n,out WFXMapInfo data))                // {                //     if (!wfxMapInfo.currShowName.Equals(data))                //     {                //         Debug.LogError("重复的地块纯在不通的名字");                //     }                // }                currAllMapName[n] = wfxMapInfo;                // Sprite sprite = null;                // for (int k = 0; k < allMapInfo.Count; k++)                // {                //     if (allMapInfo[k].root.name.Equals(wfxMapInfo.currShowName))                //     {                //         sprite = allMapInfo[k].root;                //         break;                //     }                // }                //                // GameObject g = new GameObject(i + "__" + j);                // SpriteRenderer spriteRenderer = g.AddComponent<SpriteRenderer>();                // spriteRenderer.sprite = sprite;                // g.transform.position = new Vector3(i * xJg, j * yJg);            }        }    }    private bool RandMap(int x, int y, string defName = null)    {        WFXMapInfo wfxMapInfo = WfxMapInfos[x, y];        List<TileMapInfo> currUseMap = new List<TileMapInfo>();        int allOdd = 0;        for (int i = 0; i < allMapInfo.Count; i++)        {            TileMapInfo tileMapInfo = allMapInfo[i];            if (wfxMapInfo.excludeName.Contains(tileMapInfo.root.name))            {                continue;            }            if (wfxMapInfo.huiTuiName.Contains(tileMapInfo.root.name))            {                continue;            }            allOdd += tileMapInfo.gailu;            currUseMap.Add(tileMapInfo);        }        if (currUseMap.Count <= 0)        {            return false;        }        if (string.IsNullOrEmpty(defName))        {            int odds = _random.Next(0, allOdd);            int currOdds = 0;            for (int i = 0; i < currUseMap.Count; i++)            {                currOdds += currUseMap[i].gailu;                if (odds <= currOdds)                {                    wfxMapInfo.currShowName = currUseMap[i].root.name;                    return true;                }                // else if(i!=0)                // {                //                     // }            }            // int index = _random.Next(0, currUseMap.Count);        }        else        {            wfxMapInfo.currShowName = defName;        }        return true;    }    private void Run(int x, int y)    {        if (isHuiTui)        {            return;        }        WFXMapInfo wfxMapInfo = WfxMapInfos[x, y];        if (currFindMap.Contains(wfxMapInfo))        {            return;        }        currFindMap.Add(wfxMapInfo);        string xianZhiName = wfxMapInfo.currShowName;        List<TileMapInfo> allName = new List<TileMapInfo>();        if (!string.IsNullOrEmpty(xianZhiName))        {            for (int i = 0; i < allMapInfo.Count; i++)            {                TileMapInfo tileMapInfo = allMapInfo[i];                if (xianZhiName.Equals(tileMapInfo.root.name))                {                    allName.Add(tileMapInfo);                }            }        }        else        {            if (wfxMapInfo.excludeName.Count > 0)            {                for (int i = 0; i < allMapInfo.Count; i++)                {                    TileMapInfo tileMapInfo = allMapInfo[i];                    if (wfxMapInfo.excludeName.Contains(tileMapInfo.root.name))                    {                        continue;                    }                    allName.Add(tileMapInfo);                }            }            else            {                allName.AddRange(allMapInfo);            }        }        bool isOk1 = SetHind(x - 1, y, allName, 0);        bool isOk2 = SetHind(x + 1, y, allName, 1);        bool isOk3 = SetHind(x, y + 1, allName, 2);        bool isOk4 = SetHind(x, y - 1, allName, 3);        if (!isOk1 || !isOk2 || !isOk3 || !isOk4)        {            isHuiTui = true;        }    }    private bool SetHind(int x, int y, List<TileMapInfo> allName, int type)    {        if (x < 0 || x >= w || y < 0 || y >= h)        {            return true;        }        WFXMapInfo wfxMapInfo = WfxMapInfos[x, y];        if (string.IsNullOrEmpty(wfxMapInfo.currShowName))        {            {                List<string> showName = new List<string>();                // for (int i = 0; i < allName.Count; i++)                {                    for (int j = 0; j < allName.Count; j++)                    {                        List<GameObject> showSprite = null;                        switch (type)                        {                            case 0: //左                                 showSprite = allName[j].zuo;                                break;                            case 1: //右                                showSprite = allName[j].you;                                break;                            case 2: //上                                showSprite = allName[j].shang;                                break;                            case 3: //下                                showSprite = allName[j].xia;                                break;                        }                        for (int k = 0; k < showSprite.Count; k++)                        {                            if (wfxMapInfo.excludeName.Contains(showSprite[k].name))                            {                                continue;                            }                            if (wfxMapInfo.huiTuiName.Contains(showSprite[k].name))                            {                                continue;                            }                            if (showName.Contains(showSprite[k].name))                            {                                continue;                            }                            showName.Add(showSprite[k].name);                        }                    }                }                for (int i = 0; i < allMapInfo.Count; i++)                {                    TileMapInfo tileMapInfo = allMapInfo[i];                    if (wfxMapInfo.excludeName.Contains(tileMapInfo.root.name))                    {                        continue;                    }                    if (showName.Contains(tileMapInfo.root.name))                    {                        continue;                    }                    wfxMapInfo.excludeName.Add(tileMapInfo.root.name);                    if (wfxMapInfo.showName.Contains(tileMapInfo.root.name))                    {                        wfxMapInfo.showName.Remove(tileMapInfo.root.name);                    }                }                if (showName.Count <= 0 && string.IsNullOrEmpty(wfxMapInfo.currShowName))                {                    Debug.Log("没有可选的图" + x + "___" + y + "___" + type);                    return false;                }                for (int i = 0; i < showName.Count; i++)                {                    if (!wfxMapInfo.showName.Contains(showName[i]))                    {                        wfxMapInfo.showName.Remove(showName[i]);                    }                }                wfxMapInfo.showName = showName;            }        }        Run(x, y);        return true;    }}
 |