Beispiel #1
0
        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());
        }
Beispiel #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[] {},
            });
        }