Ting[] GetListOfTingsLeadingThroughRoomGroups(RoomGroupNode current) { #if LOG D.Log("Will GetListOfTingsLeadingThroughRoomGroups!"); D.Log("Starting at goal of " + current); #endif var roomGroupsPath = new List <RoomGroup>(); while (current.prev != null) { roomGroupsPath.Add(current.roomGroup); current = current.prev; } roomGroupsPath.Add(current.roomGroup); roomGroupsPath.Reverse(); // REVERSE! string[] roomGroupsAsStrings = roomGroupsPath.Select(r => r.ToString()).ToArray(); #if LOG D.Log("Room groups to go through: " + string.Join(", ", roomGroupsAsStrings)); #endif List <Ting> tingsToInteractWith = new List <Ting>(); for (int i = 0; i < roomGroupsPath.Count - 1; i++) { var a = roomGroupsPath[i]; var b = roomGroupsPath[i + 1]; #if LOG D.Log("Will find ting that connects " + a + " with " + b); #endif var connections = _roomNetwork.linkedRoomGroups[a]; Ting ting = connections[b]; tingsToInteractWith.Add(ting); } return(tingsToInteractWith.ToArray()); }
private MimanPath AStar(Ting pStart, Ting pGoal) { if (pStart.room == pGoal.room) { return(new MimanPath() { status = MimanPathStatus.IN_THE_SAME_ROOM_ALREADY }); } var visited = new HashSet <RoomGroup>(); var startGroup = RoomGroup.FromTing(pStart); var goalGroup = RoomGroup.FromTing(pGoal); RoomGroupNode startNode = new RoomGroupNode() { roomGroup = startGroup, gscore = 0f, fscore = CostEstimate(startGroup, goalGroup), hasBeenTouched = true, depth = 0, }; var unvisited = new List <RoomGroupNode>() { startNode }; int iterations = 0; while (unvisited.Count > 0) { iterations++; if (iterations > 1000) { D.Log("Hit maximum iterations when doing MimanPathfinder2 search from " + pStart.position + " to " + pGoal.position); return(new MimanPath() { status = MimanPathStatus.NO_PATH_FOUND, iterations = iterations, tings = new Ting[] {}, }); } RoomGroupNode current = GetCheapest(unvisited); if (current.prev != null) { current.depth = current.prev.depth + 1; } #if LOG Console.WriteLine("Current node: " + current + ", with gscore " + current.gscore + " and depth: " + current.depth); #endif if (current.roomGroup.Equals(goalGroup)) { return(new MimanPath() { status = MimanPathStatus.FOUND_GOAL, tings = GetListOfTingsLeadingThroughRoomGroups(current), iterations = iterations, }); } unvisited.Remove(current); visited.Add(current.roomGroup); Dictionary <RoomGroup, Ting> linkedRooms = null; if (!_roomNetwork.linkedRoomGroups.TryGetValue(current.roomGroup, out linkedRooms)) { linkedRooms = new Dictionary <RoomGroup, Ting>(); } #if LOG Console.WriteLine("Nr of linked rooms: " + linkedRooms.Count); #endif List <RoomGroupNode> neighbours = new List <RoomGroupNode>(); foreach (var roomGroup in linkedRooms.Keys) { neighbours.Add(new RoomGroupNode() { roomGroup = roomGroup, }); } foreach (RoomGroupNode neighbour in neighbours) { #if LOG Console.WriteLine("Testing out neighbour " + neighbour); #endif float tentativeGScore = current.gscore + ActualCost(current.roomGroup, neighbour.roomGroup); bool hasBeenVisited = visited.Contains(neighbour.roomGroup); if (hasBeenVisited && tentativeGScore > neighbour.gscore) { #if LOG //Console.WriteLine("It has been visited and its score is too high, lets skip it"); #endif continue; } #if LOG //Console.WriteLine("Tentative gscore: " + tentativeGScore + ", neighbour score: " + neighbour.gscore); #endif if (!neighbour.hasBeenTouched || tentativeGScore < neighbour.gscore) { neighbour.hasBeenTouched = true; neighbour.prev = current; neighbour.gscore = tentativeGScore; neighbour.fscore = neighbour.gscore + CostEstimate(neighbour.roomGroup, goalGroup); if (!unvisited.Contains(neighbour)) { #if LOG //Console.WriteLine("Adding neighbour " + neighbour.ting.name + " to unvisited list."); #endif unvisited.Add(neighbour); } } } } return(new MimanPath() { status = MimanPathStatus.NO_PATH_FOUND, iterations = iterations, tings = new Ting[] {}, }); }