• C# 4格A*自动寻径


        class Program
        {
            //public const char[] _specialStrings = { '☆', '★', '○', '●', '◎', '◇', '◆', '□', '■', '△', '▲', '※' };
    
            public class Row
            {
                public int Id { get; set; }
                public List<Cell> Cells { get; set; }
            }
    
    
            public enum Terrian
            {
                Sea,
                Land,
                River,
                Mountain
            }
    
            public class Cell
            {
                public int X { get; set; }
                public int Y { get; set; }
    
                #region
                public int G { get; set; }
                public int H { get; set; }
                public Cell Father { get; set; }
    
                public bool IsMove
                {
                    get
                    {
                        if (this._terr == Terrian.Mountain || this._terr == Terrian.Sea)
                            return false;
                        return true;
                    }
                }
    
                #endregion
    
    
                public event Action TerrianChanged;
                public void OnTerrianChanged()
                {
                    TerrianChanged?.Invoke();
                }
    
    
                private Terrian _terr = Terrian.Sea;
    
    
                public Terrian GetTerr()
                {
                    return this._terr;
                }
                public void SetTerr(Terrian terr)
                {
                    this._terr = terr;
                }
    
                public char GetRender()
                {
                    switch (this._terr)
                    {
                        case Terrian.Sea:
                            return '';
                        case Terrian.Land:
                            return '';
                        case Terrian.River:
                            return '';
                        case Terrian.Mountain:
                            return '';
                        default:
                            return ' ';
                    }
                }
    
    
                public bool IsEqual(Cell cell)
                {
                    if (this.X == cell.X && this.Y == cell.Y)
                        return true;
                    else
                        return false;
                }
    
    
            }
            public class Map
            {
    
                private int _rowCount = 100;
                private int _cellCount = 100;
                private Random _random = new Random();
                private delegate void SetTerrianFunc(Cell Source);
    
                public List<Row> Rows { get; set; }
    
                private void InitRows()
                {
                    this.Rows = new List<Row>();
                    for (int y = 0; y < this._rowCount; y++)
                    {
                        var cells = new List<Cell>();
                        for (int x = 0; x < this._cellCount; x++)
                        {
                            var cell = new Cell { X = x, Y = y };
                            cells.Add(cell);
                        }
                        var row = new Row { Id = y, Cells = cells };
                        this.Rows.Add(row);
                    }
                }
    
    
                public Map(int rowCount, int colCount)
                {
                    this._rowCount = rowCount;
                    this._cellCount = colCount;
    
                    InitRows();
    
                    ExecuteMap();
                }
    
                private void ExecuteMap()
                {
                    var landSource = GetCell(0, 0);
                    DrawLand(landSource);
    
                    var center = GetCenterCell();
                    DrawRangeRandom(center, 0, 5, 30, SetMountain);
    
                    int tmpRange = 5;
                    var start = GetCell(center.X - tmpRange, center.Y - tmpRange);
                    var end = GetCell(center.X + tmpRange, center.Y + tmpRange);
                    SetLand(start);
                    SetLand(end);
                    DrawRiver(start, end);
    
                    //测试代码写于此处
    
    
                }
    
    
    
                private void DrawLand(Cell source)
                {
                    int land = Convert.ToInt32(_cellCount * 0.7);
                    int Islands = Convert.ToInt32(_cellCount * 0.9);
    
                    DrawRangeRandom(source, 0, land, 100, SetLand);
                    DrawRangeRandom(source, land, Islands, 20, SetLand);
                }
    
                private void DrawRangeRandom(Cell source, int startRange, int endRange, int percentage, SetTerrianFunc func)
                {
                    var list = GetCells(source, startRange, endRange).Where(x => _random.Next(0, 100) < percentage).ToList();
                    SetTerrian(list, func);
                }
    
                private void DrawRiver(Cell start, Cell end)
                {
                    var list = GetPatch(start, end);
                    SetTerrian(list, SetRiver);
                }
    
    
                #region A*
    
    
                private List<Cell> _openList = new List<Cell>();
                private List<Cell> _closeList = new List<Cell>();
    
                private bool IsInOpenList(Cell cell)
                {
                    foreach (var open in _openList)
                        if (open.IsEqual(cell))
                            return true;
    
                    return false;
                }
    
                private bool IsInCloseList(Cell cell)
                {
                    foreach (var open in _closeList)
                        if (open.IsEqual(cell))
                            return true;
    
                    return false;
                }
    
                private Cell GetMinFFromOpenList()
                {
                    Cell Pmin = null;
                    foreach (Cell p in _openList)
                        if (Pmin == null || Pmin.G + Pmin.H > p.G + p.H)
                            Pmin = p;
                    return Pmin;
                }
    
    
                public List<Cell> GetPatch(Cell Start, Cell End)
                {
                    var path = new List<Cell>();
    
                    _openList.Add(Start);
                    while (!(IsInOpenList(End) || _openList.Count == 0))
                    {
                        Cell minF = GetMinFFromOpenList();
                        if (minF == null) return null;
                        _openList.Remove(minF);
                        _closeList.Add(minF);
    
                        CheckP4(minF, Start, ref End);
                    }
    
                    while (End.Father != null)
                    {
                        path.Add(End);
                        End = End.Father;
                    }
    
                    return path;
                }
    
    
                private int GetG(Cell p, Cell pb)
                {
                    return Math.Abs(p.X - pb.X) + Math.Abs(p.Y - pb.Y);
                }
    
                //计算某个点的H值  
                private int GetH(Cell p, Cell pb)
                {
                    return Math.Abs(p.X - pb.X) + Math.Abs(p.Y - pb.Y);
                }
                //检查当前节点附近的节点  
                private void CheckP4(Cell minF, Cell pa, ref Cell pb)
                {
    
                    foreach (var nb in GetNeighbors(minF))
                    {
                        if (nb.IsMove && !IsInCloseList(nb))
                        {
                            if (IsInOpenList(nb))
                            {
                                _openList.Remove(nb);
                                nb.Father = minF;
                                _openList.Add(nb);
                            }
                            else
                            {
                                //不在开启列表中  
                                nb.Father = minF;
                                nb.H = GetH(nb, pb);
                                nb.G = GetG(nb, pa);
                                _openList.Add(nb);
                            }
                        }
                    }
    
                }
    
                #endregion
    
    
                #region Cell
    
                public void SetSea(Cell Source)
                {
                    Source.SetTerr(Terrian.Sea);
                }
    
                public void SetLand(Cell Source)
                {
                    Source.SetTerr(Terrian.Land);
                }
    
                public void SetMountain(Cell Source)
                {
                    Source.SetTerr(Terrian.Mountain);
                }
    
                public void SetRiver(Cell Source)
                {
                    Source.SetTerr(Terrian.River);
                }
    
                private void SetTerrian(List<Cell> list, SetTerrianFunc func)
                {
                    foreach (var cell in list)
                    {
                        func(cell);
                    }
                }
    
                public Cell GetCell(int X, int Y)
                {
                    if (X < this._cellCount && Y < this._rowCount && X >= 0 && Y >= 0)
                        return this.Rows[Y].Cells[X];
                    else
                        return null;
                }
    
                private Cell GetCenterCell()
                {
                    return GetCell(_cellCount / 2, _rowCount / 2);
                }
    
                public List<Cell> GetCells(Cell source, int startRange, int endRange)
                {
                    var list = new List<Cell>();
    
                    for (int y = source.Y - endRange; y <= source.Y + endRange; y++)
                    {
                        for (int x = source.X - endRange; x <= source.X + endRange; x++)
                        {
                            if (x <= source.X - startRange || x >= source.X + startRange || y <= source.Y - startRange || y >= source.Y + startRange)
                            {
                                list.Add(GetCell(x, y));
                            }
                        }
                    }
    
                    return list.Where(x => x != null).Distinct().ToList();
                }
    
    
                private Cell GetLeft(Cell source)
                {
                    return GetCell(source.X - 1, source.Y);
                }
    
                private Cell GetRight(Cell source)
                {
                    return GetCell(source.X + 1, source.Y);
                }
    
                private Cell GetUp(Cell source)
                {
                    return GetCell(source.X, source.Y - 1);
                }
    
                private Cell GetDown(Cell source)
                {
                    return GetCell(source.X, source.Y + 1);
                }
    
                private List<Cell> GetNeighbors(Cell source)
                {
                    var nbs = new List<Cell>();
    
                    nbs.Add(GetLeft(source));
                    nbs.Add(GetRight(source));
                    nbs.Add(GetUp(source));
                    nbs.Add(GetDown(source));
    
                    return nbs.Where(x => x != null).ToList();
                }
    
                #endregion
    
    
    
            }
    
    
            static void Main(string[] args)
            {
                var map = new Map(40, 50);
    
                foreach (var row in map.Rows)
                {
                    string str = "";
                    foreach (var cell in row.Cells)
                    {
                        str += cell.GetRender();
                    }
                    Console.WriteLine(str);
                }
    
                Console.ReadKey();
            }
    
    
        }
  • 相关阅读:
    IDEA常用快捷键和常用插件集成,持续更新......
    【转】javascript日期操作详解(脚本之家整理)
    学习AngularJs:Directive指令用法
    Angular过滤器 自定义及使用方法
    【转】AngularJS 日期格式化 字典
    【转】AngularJs $location获取url参数
    【转】JavaScript对Json节点的增删改
    Asp.Net Mvc后台数据验证自测小Demo
    你必须先行上路
    【转】俞敏洪:我和马云差了8个字,结果财富相差2200亿美金
  • 原文地址:https://www.cnblogs.com/xuhongcai/p/8252649.html
Copyright © 2020-2023  润新知