public RoomNetwork RecreateRoomNetwork() { #if PROFILE_NETWORK Stopwatch sw = new Stopwatch(); sw.Start(); #endif _roomNetwork = new RoomNetwork(); foreach (Room room in _roomRunner.rooms) { foreach (Ting exit in GetExits(room)) { var linkingTings = GetLinkedExitsInOtherRooms(exit); int group = exit.tile.group; var roomGroup = new RoomGroup(room, group); Dictionary <RoomGroup, Ting> maybeRooms = null; if (!_roomNetwork.linkedRoomGroups.TryGetValue(roomGroup, out maybeRooms)) { maybeRooms = new Dictionary <RoomGroup, Ting>(); _roomNetwork.linkedRoomGroups.Add(roomGroup, maybeRooms); } D.isNull(maybeRooms, "maybeRooms is null"); //D.Log("The exit " + exit.name + " in " + exit.room.name + " is linked to the following tings: "); foreach (var linkingTing in linkingTings) { D.isNull(linkingTing, "linking ting is null"); maybeRooms[RoomGroup.FromTing(linkingTing)] = exit; //D.Log(linkedTing.name + " in " + linkedTing.room); } } } #if PROFILE_NETWORK sw.Stop(); if (sw.Elapsed.TotalSeconds > 0.0f) { D.Log("Recreating Room Network took " + sw.Elapsed.TotalSeconds + " s."); } #endif return(_roomNetwork); }
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[] {}, }); }