/// <summary> /// 根据角色位置和行动力,找到行动范围 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="mobility"></param> /// <param name="ignoreRole">是否可以穿人,默认关闭</param> /// <returns></returns> public List <BattleBlockVector> GetMoveRange(int x, int y, int mobility, bool ignoreRole = false) { var rst = new List <BattleBlockVector>(); var visited = new HashSet <int>(); Queue <MoveSearchHelper> searchQueue = new Queue <MoveSearchHelper>(); searchQueue.Enqueue(new MoveSearchHelper() { X = x, Y = y, Cost = 0 }); visited.Add(GetBlockHash(x, y)); while (searchQueue.Count > 0) { MoveSearchHelper currentNode = searchQueue.Dequeue(); int xx = currentNode.X; int yy = currentNode.Y; int cost = currentNode.Cost; rst.Add(new BattleBlockVector() { X = xx, Y = yy }); var nearBlocks = GetNearBlocks(xx, yy); foreach (var b in nearBlocks) { int x2 = b.X; int y2 = b.Y; int dcost = 1; if (Exists != null && !Exists(x2, y2)) { continue; } if (!ignoreRole && HasRole != null && HasRole(x2, y2)) { continue; } if (cost + dcost <= mobility && !visited.Contains(GetBlockHash(x2, y2))) { searchQueue.Enqueue(new MoveSearchHelper() { X = x2, Y = y2, Cost = cost + dcost }); visited.Add(GetBlockHash(x2, y2)); } } } return(rst); }
static List <BattleBlockVector> GenerateNearBlocks(int x, int y, int maxDist) { var rst = new List <BattleBlockVector>(); var visited = new HashSet <int>(); var searchQueue = new Queue <MoveSearchHelper>(); searchQueue.Enqueue(new MoveSearchHelper() { X = x, Y = y, Cost = 0 }); while (searchQueue.Count > 0) { MoveSearchHelper currentNode = searchQueue.Dequeue(); int xx = currentNode.X; int yy = currentNode.Y; int cost = currentNode.Cost; int blockHash = GetBlockHash(xx, yy); if (visited.Contains(blockHash)) { continue; } rst.Add(new BattleBlockVector() { X = xx, Y = yy }); visited.Add(blockHash); foreach (var b in GetNearBlocksHexMatrics(xx, yy)) { int x2 = b.X; int y2 = b.Y; int dcost = 1; if (cost + dcost <= maxDist && !visited.Contains(GetBlockHash(x2, y2))) { searchQueue.Enqueue(new MoveSearchHelper() { X = x2, Y = y2, Cost = cost + dcost }); } } } return(rst); }
/// <summary> /// 寻路函数,从sx,sy到tx,ty的路径(返回最近的任意一条) /// </summary> /// <param name="sx"></param> /// <param name="sy"></param> /// <param name="tx"></param> /// <param name="ty"></param> /// <param name="ignoreRole">是否可以穿人,默认关闭</param> /// <returns></returns> public List <MoveSearchHelper> GetWay(int sx, int sy, int tx, int ty, bool ignoreRole = false) { var rst = new List <MoveSearchHelper>(); if (sx == tx && sy == ty) { return(rst); } var visited = new HashSet <string>(); Queue <MoveSearchHelper> queue = new Queue <MoveSearchHelper>(); queue.Enqueue(new MoveSearchHelper() { X = sx, Y = sy }); visited.Add($"{sx}_{sy}"); while (queue.Count > 0) { MoveSearchHelper node = queue.Dequeue(); int xx = node.X; int yy = node.Y; if (xx == tx && yy == ty) { do { rst.Add(node); node = node.front; } while (node != null); rst.Reverse(); return(rst); } var nearBlocks = GetNearBlocks(xx, yy); foreach (var b in nearBlocks) { int x2 = b.X; int y2 = b.Y; if (Exists != null && !Exists(x2, y2)) { continue; } if (!ignoreRole && HasRole != null && HasRole(x2, y2) && (x2 != tx || y2 != ty)) { continue; } if (visited.Contains($"{x2}_{y2}")) { continue; } queue.Enqueue(new MoveSearchHelper() { X = x2, Y = y2, front = node }); visited.Add($"{x2}_{y2}"); } } return(rst); }
//重复调用,将覆盖之前的内容 void GenNearBlocksFirstTime(int x, int y, int maxdistance) { var pk = GetBlockCacheKey(x, y, maxdistance); if (!nearblocksCache.ContainsKey(pk)) { nearblocksCache.Add(pk, new List <BattleBlockVector>()); } var list = nearblocksCache[pk]; list.Clear(); var visited = new HashSet <int>(); var searchQueue = new Queue <MoveSearchHelper>(); searchQueue.Enqueue(new MoveSearchHelper() { X = x, Y = y, Cost = 0 }); while (searchQueue.Count > 0) { MoveSearchHelper currentNode = searchQueue.Dequeue(); int xx = currentNode.X; int yy = currentNode.Y; int cost = currentNode.Cost; int blockHash = GetBlockHash(xx, yy); if (visited.Contains(blockHash)) { continue; } list.Add(new BattleBlockVector() { X = xx, Y = yy }); visited.Add(blockHash); foreach (var b in GetNearBlocks(xx, yy)) { int x2 = b.X; int y2 = b.Y; int dcost = 1; if (Exists != null && !Exists(x2, y2)) { continue; } if (cost + dcost <= maxdistance && !visited.Contains(GetBlockHash(x2, y2))) { searchQueue.Enqueue(new MoveSearchHelper() { X = x2, Y = y2, Cost = cost + dcost }); } } } }