// returns the optimal path of a start and end cell, returns empty if path is longer than move speed, or there is no path public static List <HexCell> GetPath(HexCell begin, HexCell end, int moveSpeed) { List <HexCell> path = new List <HexCell>(); OddQPoint goal = new OddQPoint(end); OddQPoint start = new OddQPoint(begin); if (SolvePath(MapMaster.Map, start, goal, moveSpeed)) { OddQPoint step = goal; while (!step.Equals(start)) { path.Add(MapMaster.Map[step.r, step.q]); step = cameFrom[step]; } path.Reverse(); /*string s = ""; * foreach (HexCell h in path) * { * s += h.ToString() + " "; * } * Debug.Log(s);*/ } return(path); }
//Finds and returns a list of valid neighbors around a given point private static List <OddQPoint> Neighbors(OddQPoint center) { List <OddQPoint> items = new List <OddQPoint>(); int parity = center.q & 1; OddQPoint n; foreach (OddQPoint dir in directions[parity]) { n = new OddQPoint(center.q + dir.q, center.r + dir.r); if (MapMaster.IsCellOnMap(n.q, n.r)) { items.Add(n); } } return(items); }
//Uses A* to solve for the optimal path, bounded by a cost limit private static bool SolvePath(HexCell[,] map, OddQPoint start, OddQPoint goal, int maxCost) { if (!map[goal.r, goal.q].Passable) { return(false); } cameFrom = new Dictionary <OddQPoint, OddQPoint>(); costSoFar = new Dictionary <OddQPoint, int>(); P_Queue <OddQPoint> openNodes = new P_Queue <OddQPoint>(); openNodes.Enqueue(start, 0); cameFrom[start] = start; costSoFar[start] = 0; OddQPoint current; while (openNodes.Count != 0) // buid paths until a goal is reached or there is no where else to explore { current = openNodes.Dequeue(); if (current.Equals(goal)) { if (costSoFar[current] > maxCost) { return(false); } else { return(true); } } foreach (OddQPoint next in Neighbors(current)) { HexCell h = map[next.r, next.q]; if (!h.passable) { if (h.unit == null) { continue; } else if ((h.Unit.Player != PlayerMaster.CurrentTurn)) { continue; } } int nCost = costSoFar[current] + HexCell.CostToHex(map[current.r, current.q], map[next.r, next.q]); if (!costSoFar.ContainsKey(next) || nCost < costSoFar[next]) { costSoFar[next] = nCost; int prio = nCost + Heuristic(map[next.r, next.q], map[goal.r, goal.q]); openNodes.Enqueue(next, prio); cameFrom[next] = current; } } } return(false); }
public bool Equals(OddQPoint other) { return((other.q == this.q) && (other.r == this.r)); }