コード例 #1
0
        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);
        }
コード例 #2
0
        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[] {},
            });
        }