Пример #1
0
        public string pathToString()
        {
            string      str   = "";
            SearchAgent agent = this;

            while (agent != null)
            {
                Console.WriteLine(agent.actualHash);
                str  += "(" + agent.bigKey + "," + agent.keyItems + "," + agent.keysAcquired + "," + agent.keysSpent + "," + agent.currentRoom.type + ",";
                str  += ") > \n ";
                agent = agent.parent;
            }
            Console.WriteLine();

            /*
             * foreach (var agent in agentPath) {
             *  str += "(" + agent.bigKey + "," + agent.keyItems + "," + agent.keysAcquired + "," + agent.keysSpent + "," + agent.currentRoom.type + ",";
             *  foreach (var sw in agent.switchesSet) {
             *      str += sw + ":";
             *  }
             *  str += ") > \n ";
             * }
             * */
            return(str);
        }
Пример #2
0
        public override int GetHashCode()
        {
            if (actualHash == -1)
            {
                unchecked // Overflow is fine, just wrap
                {
                    SortedSet <Room> rooms = new SortedSet <Room>(new RoomComparer());

                    int hash = 17;
                    // Suitable nullity checks etc, of course :)
                    hash = hash * 486187739 + keysAcquired.GetHashCode();
                    hash = hash * 486187739 + keysSpent.GetHashCode();
                    hash = hash * 486187739 + bigKey.GetHashCode();
                    hash = hash * 486187739 + items.GetHashCode();
                    hash = hash * 486187739 + keyItems.GetHashCode();
                    hash = hash * 486187739 + currentRoom.GetHashCode();
                    SearchAgent agent = this;
                    while (agent != null)
                    {
                        rooms.Add(agent.currentRoom);
                        agent = agent.parent;
                    }
                    foreach (var room in rooms)
                    {
                        hash = hash * 486187739 + room.GetHashCode();
                    }
                    actualHash = hash;
                    return(hash);
                }
            }
            else
            {
                return(actualHash);
            }
        }
Пример #3
0
 public SearchAgent(SearchAgent parent,
                    int keysAcquired,
                    int keysSpent,
                    bool bigKey,
                    bool requiresBigKey,
                    int items,
                    int keyItems,
                    Room currentRoom)
 {
     this.keysAcquired   = keysAcquired;
     this.keysSpent      = keysSpent;
     this.bigKey         = bigKey;
     this.parent         = parent;
     this.requiresBigKey = requiresBigKey;
     this.items          = items;
     this.keyItems       = keyItems;
     if (!hasVisited(currentRoom))
     {
         if (currentRoom.type.Contains("k"))
         {
             this.keysAcquired++;
             this.gotItem = true;
         }
         if (currentRoom.type.Contains("i"))
         {
             this.items++;
             this.gotItem = true;
         }
         if (currentRoom.type.Contains("K"))
         {
             this.bigKey  = true;
             this.gotItem = true;
         }
         foreach (var type in currentRoom.type.Split(new char[] { ',' }))
         {
             if (type.Contains("S"))
             {
                 this.gotItem = true;
             }
         }
         if (currentRoom.type.Contains("I"))
         {
             if (!this.requiresBigKey || this.bigKey)
             {
                 this.keyItems++;
                 this.gotItem = true;
             }
             else
             {
                 canAdd = false;
             }
         }
     }
     this.currentRoom = currentRoom;
 }
Пример #4
0
        public void UpdateRooms(SearchAgent endAgent)
        {
            List <Room> optimalPath = new List <Room>();
            SearchAgent agent       = endAgent;

            while (agent != null)
            {
                optimalPath.Add(agent.currentRoom);
                agent = agent.parent;
            }
            optimalPath.Reverse();

            List <Room> notVisited = new List <Room>();

            foreach (var room in rooms.Values)
            {
                if (optimalPath.Contains(room))
                {
                    room.detour        = 0;
                    room.depth         = optimalPath.IndexOf(room);
                    room.crossingCount = optimalPath.Where(x => x.Equals(room)).Count();
                }
                else
                {
                    notVisited.Add(room);
                }
            }

            while (notVisited.Count > 0)
            {
                Room roomToVisit = notVisited[0];
                notVisited.RemoveAt(0);
                Tuple <int, Room> detourRoomPair = FloodFill(roomToVisit, optimalPath);
                roomToVisit.detour = detourRoomPair.Item1;
                roomToVisit.depth  = detourRoomPair.Item2.depth + roomToVisit.detour;
            }
        }
Пример #5
0
        public void WriteStats(string filename, SearchAgent endAgent)
        {
            Dictionary <string, int> dungeonStatistics = new Dictionary <string, int>()
            {
                { "roomsInLevel", 0 },
                { "enemyRoomsInLevel", 0 },
                { "puzzleRoomsInLevel", 0 },
                { "itemRoomsInLevel", 0 },
                { "doorsInLevel", 0 },
                { "passableDoorsInLevel", 0 },
                { "lockedDoorsInLevel", 0 },
                { "bombLockedDoorsInLevel", 0 },
                { "bigKeyDoorsInLevel", 0 },
                { "oneWayDoorsInLevel", 0 },
                { "itemLockedDoorsInLevel", 0 },
                { "puzzleLockedDoorsInLevel", 0 },
                { "softLockedDoorsInLevel", 0 },
                { "lookAheadsInLevel", 0 },
                { "totalCrossings", 0 },
                { "maximumCrossings", 0 },
                { "maximumDistanceToPath", 0 },
                { "pathLength", 0 },
                { "roomsOnPath", 0 },
                { "enemyRoomsOnPath", 0 },
                { "puzzleRoomsOnPath", 0 },
                { "itemRoomsOnPath", 0 },
                { "doorsOnPath", 0 },
                { "lockedDoorsOnPath", 0 },
                { "bombLockedDoorsOnPath", 0 },
                { "bigKeyLockedDoorsOnPath", 0 },
                { "itemLockedDoorsOnPath", 0 },
                { "softLockedDoorsOnPath", 0 },
                { "puzzleLockedDoorsOnPath", 0 },
                { "lookAheadsOnPath", 0 },
                { "oneWayDoorsOnPath", 0 },
                { "distanceToDungeonKey", 0 },
                { "distanceToSpecialItem", 0 },
            };
            Dictionary <string, List <string> > roomStatistics = new Dictionary <string, List <string> >()
            {
                { "doorTypesFrom", new List <string>() },
                { "doorCameFrom", new List <string>() },
                { "doorTypesTo", new List <string>() },
                { "doorGoTo", new List <string>() },
                { "crossings", new List <string>() },
                { "depth", new List <string>() },
                { "pureDepth", new List <string>() },
                { "distanceOfRoomToOptimalPath", new List <string>() },
                { "numberOfNeighbors", new List <string>() },
                { "roomType", new List <string>() },
                { "roomCameFrom", new List <string>() },
                { "roomGoTo", new List <string>() },
                { "enemyNeighbors", new List <string>() },
                { "puzzleNeighbors", new List <string>() },
                { "itemNeighbors", new List <string>() },
                { "doorsToNeighbors", new List <string>() },
                { "passableToNeighbors", new List <string>() },
                { "lockedToNeighbors", new List <string>() },
                { "bombLockedToNeighbors", new List <string>() },
                { "itemLockedToNeighbors", new List <string>() },
                { "puzzleLockedToNeighbors", new List <string>() },
                { "softLockedToNeighbors", new List <string>() },
                { "bigKeyLockedToNeighbors", new List <string>() },
                { "oneWayLockedToNeighbors", new List <string>() },
                { "lookAheadToNeighbors", new List <string>() },
                { "passableFromNeighbors", new List <string>() },
                { "lockedFromNeighbors", new List <string>() },
                { "bombLockedFromNeighbors", new List <string>() },
                { "itemLockedFromNeighbors", new List <string>() },
                { "puzzleLockedFromNeighbors", new List <string>() },
                { "softLockedFromNeighbors", new List <string>() },
                { "bigKeyLockedFromNeighbors", new List <string>() },
                { "oneWayLockedFromNeighbors", new List <string>() },
                { "lookAheadFromNeighbors", new List <string>() },
            };

            foreach (var room in rooms.Values)
            {
                string type = cleanString(room.type == "," || room.type == "" ? "_" : room.type);
                roomStatistics["roomType"].Add(type);
                roomStatistics["numberOfNeighbors"].Add("" + room.neighbors.Count);
                type = "";
                string[] neighborTypes = new string[room.neighbors.Count];
                int      ii            = 0;
                int      enemyCount    = 0;
                int      puzzleCount   = 0;
                int      itemCount     = 0;
                foreach (var neighbor in room.neighbors)
                {
                    neighborTypes[ii] = cleanString(neighbor.type == "," || neighbor.type == "" ? "_" : neighbor.type);
                    ii++;
                    enemyCount  += ((neighbor.type.Contains('e')) || (neighbor.type.Contains('m')) || (neighbor.type.Contains('b')))? 1 : 0;
                    puzzleCount += neighbor.type.Contains('p')? 1 : 0;
                    itemCount   += ((neighbor.type.Contains('i')) || (neighbor.type.Contains('I')) ||
                                    (neighbor.type.Contains('k')) || (neighbor.type.Contains('K')))? 1 : 0;
                }
                roomStatistics["enemyNeighbors"].Add("" + enemyCount);
                roomStatistics["puzzleNeighbors"].Add("" + puzzleCount);
                roomStatistics["itemNeighbors"].Add("" + itemCount);
                Dictionary <string, int> doorStats = new Dictionary <string, int>()
                {
                    { "doorsToNeighbors", 0 },
                    { "passableToNeighbors", 0 },
                    { "lockedToNeighbors", 0 },
                    { "bombLockedToNeighbors", 0 },
                    { "itemLockedToNeighbors", 0 },
                    { "puzzleLockedToNeighbors", 0 },
                    { "softLockedToNeighbors", 0 },
                    { "bigKeyLockedToNeighbors", 0 },
                    { "oneWayLockedToNeighbors", 0 },
                    { "lookAheadToNeighbors", 0 },

                    { "passableFromNeighbors", 0 },
                    { "lockedFromNeighbors", 0 },
                    { "bombLockedFromNeighbors", 0 },
                    { "itemLockedFromNeighbors", 0 },
                    { "puzzleLockedFromNeighbors", 0 },
                    { "softLockedFromNeighbors", 0 },
                    { "bigKeyLockedFromNeighbors", 0 },
                    { "oneWayLockedFromNeighbors", 0 },
                    { "lookAheadFromNeighbors", 0 },
                };
                ii = 0;
                string[] doorToTypes   = new string[room.neighbors.Count];
                string[] doorFromTypes = new string[room.neighbors.Count];
                foreach (var door in room.doors)
                {
                    string doorLock = door.OtherLock(room);
                    doorStats["doorsToNeighbors"]        += 1;
                    doorStats["passableToNeighbors"]     += doorLock == "," || doorLock == "" ? 1 : 0;
                    doorStats["lockedToNeighbors"]       += doorLock.Contains("k") ? 1 : 0;
                    doorStats["bombLockedToNeighbors"]   += doorLock.Contains("b") ? 1 : 0;
                    doorStats["itemLockedToNeighbors"]   += doorLock.Contains("I") ? 1 : 0;
                    doorStats["puzzleLockedToNeighbors"] += doorLock.Contains("S") ? 1 : 0;
                    doorStats["softLockedToNeighbors"]   += doorLock.Contains("l") ? 1 : 0;
                    doorStats["bigKeyLockedToNeighbors"] += doorLock.Contains("K") ? 1 : 0;
                    doorStats["oneWayLockedToNeighbors"] += doorLock.Contains("O") ? 1 : 0;
                    doorStats["lookAheadToNeighbors"]    += doorLock.Contains("s") ? 1 : 0;
                    doorLock = door.OtherLock(door.OtherRoom(room));
                    doorStats["passableFromNeighbors"]     += doorLock == "," || doorLock == "" ? 1 : 0;
                    doorStats["lockedFromNeighbors"]       += doorLock.Contains("k") ? 1 : 0;
                    doorStats["bombLockedFromNeighbors"]   += doorLock.Contains("b") ? 1 : 0;
                    doorStats["itemLockedFromNeighbors"]   += doorLock.Contains("I") ? 1 : 0;
                    doorStats["puzzleLockedFromNeighbors"] += doorLock.Contains("S") ? 1 : 0;
                    doorStats["softLockedFromNeighbors"]   += doorLock.Contains("l") ? 1 : 0;
                    doorStats["bigKeyLockedFromNeighbors"] += doorLock.Contains("K") ? 1 : 0;
                    doorStats["oneWayLockedFromNeighbors"] += doorLock.Contains("O") ? 1 : 0;
                    doorStats["lookAheadFromNeighbors"]    += doorLock.Contains("s") ? 1 : 0;

                    doorToTypes[ii]   = cleanString(door.OtherLock(room) == "," || door.OtherLock(room) == "" ? "_" : door.OtherLock(room));
                    doorFromTypes[ii] = cleanString(door.OtherLock(door.OtherRoom(room)) == "," || door.OtherLock(door.OtherRoom(room)) == "" ? "_" : door.OtherLock(door.OtherRoom(room)));
                    if (doorToTypes[ii].Contains(","))
                    {
                        string t = doorToTypes[ii];
                    }
                    ii++;
                }
                foreach (var statPair in doorStats)
                {
                    roomStatistics[statPair.Key].Add("" + statPair.Value);
                }
                string doorCameFrom = "_";
                string roomCameFrom = "_";
                string doorGoTo     = "_";
                string roomGoTo     = "_";
                foreach (var door in room.doors)
                {
                    var doorLock = door.OtherLock(room);
                    if (door.OtherLock(room) != "O" && door.OtherLock(room) != "1")
                    {
                        if (door.OtherRoom(room).depth < room.depth)
                        {
                            doorCameFrom = doorLock == "" ? "_" : doorLock;
                            roomCameFrom = door.OtherRoom(room).type == "" ? "_" : door.OtherRoom(room).type;
                        }
                        if (door.OtherRoom(room).depth > room.depth)
                        {
                            doorGoTo = doorLock == "" ? "_" : doorLock;
                            roomGoTo = door.OtherRoom(room).type == "" ? "_" : door.OtherRoom(room).type;
                        }
                    }
                }
                roomStatistics["doorCameFrom"].Add(cleanString(doorCameFrom));
                roomStatistics["roomCameFrom"].Add(cleanString(roomCameFrom));
                roomStatistics["doorGoTo"].Add(cleanString(doorGoTo));
                roomStatistics["roomGoTo"].Add(cleanString(roomGoTo));

                Array.Sort(neighborTypes);
                Array.Sort(doorToTypes);
                Array.Sort(doorFromTypes);
                roomStatistics["doorTypesTo"].Add(String.Join(",", doorToTypes));
                roomStatistics["doorTypesFrom"].Add(String.Join(",", doorFromTypes));
                //  roomStatistics["neighborTypes"].Add(cleanString(type));
                roomStatistics["distanceOfRoomToOptimalPath"].Add("" + room.detour);
                roomStatistics["depth"].Add("" + room.depth);
                roomStatistics["pureDepth"].Add("" + room.pureDepth);
                roomStatistics["crossings"].Add("" + room.crossingCount);

                /*
                 * type = "";
                 * foreach (var door in room.doors){
                 *  type += door.OtherLock(door.OtherRoom(room)) == "" ? "_" : door.OtherLock(door.OtherRoom(room));
                 * }
                 * roomStatistics["doorTypesFrom"].Add(cleanString(type));
                 */

                dungeonStatistics["roomsInLevel"]       += 1;
                dungeonStatistics["enemyRoomsInLevel"]  += ((room.type.Contains('e')) || (room.type.Contains('m')) || (room.type.Contains('b')))? 1 : 0;
                dungeonStatistics["puzzleRoomsInLevel"] += room.type.Contains('p')? 1 : 0;
                dungeonStatistics["itemRoomsInLevel"]   += ((room.type.Contains('i')) || (room.type.Contains('I')) ||
                                                            (room.type.Contains('k')) || (room.type.Contains('K')))? 1 : 0;
                foreach (var door in room.doors)
                {
                    string doorLock = door.OtherLock(room);
                    dungeonStatistics["doorsInLevel"]             += 1;
                    dungeonStatistics["passableDoorsInLevel"]     += doorLock == "_" ? 1 : 0;
                    dungeonStatistics["lockedDoorsInLevel"]       += doorLock.Contains("k") ? 1 : 0;
                    dungeonStatistics["bombLockedDoorsInLevel"]   += doorLock.Contains("b") ? 1 : 0;
                    dungeonStatistics["itemLockedDoorsInLevel"]   += doorLock.Contains("I") ? 1 : 0;
                    dungeonStatistics["puzzleLockedDoorsInLevel"] += doorLock.Contains("S") ? 1 : 0;
                    dungeonStatistics["softLockedDoorsInLevel"]   += doorLock.Contains("l") ? 1 : 0;
                    dungeonStatistics["bigKeyDoorsInLevel"]       += doorLock.Contains("K") ? 1 : 0;
                    dungeonStatistics["oneWayDoorsInLevel"]       += doorLock.Contains("O") ? 1 : 0;
                    dungeonStatistics["lookAheadsInLevel"]        += doorLock.Contains("s") ? 1 : 0;
                }
                dungeonStatistics["totalCrossings"]       += room.crossingCount;
                dungeonStatistics["maximumCrossings"]      = Math.Max(room.crossingCount, dungeonStatistics["maximumCrossings"]);
                dungeonStatistics["maximumDistanceToPath"] = Math.Max(room.detour, dungeonStatistics["maximumDistanceToPath"]);
            }

            //PATH STATISTICS

            List <Room>        path        = new List <Room>();
            List <SearchAgent> agentPath   = new List <SearchAgent>();
            SortedSet <Room>   roomsOnPath = new SortedSet <Room>(new RoomComparer());
            SearchAgent        agent       = endAgent;
            int roomCount = 0;

            while (agent != null)
            {
                roomsOnPath.Add(agent.currentRoom);
                path.Add(agent.currentRoom);
                agentPath.Add(agent);
                agent = agent.parent;
                roomCount++;
            }
            path.Reverse();
            agentPath.Reverse();
            dungeonStatistics["pathLength"]  = roomCount;
            dungeonStatistics["roomsOnPath"] = roomsOnPath.Count;
            foreach (var room in roomsOnPath)
            {
                dungeonStatistics["enemyRoomsOnPath"]  += ((room.type.Contains('e')) || (room.type.Contains('m')) || (room.type.Contains('b')))? 1 : 0;
                dungeonStatistics["puzzleRoomsOnPath"] += room.type.Contains('p')? 1 : 0;
                dungeonStatistics["itemRoomsOnPath"]   += ((room.type.Contains('i')) || (room.type.Contains('I')) ||
                                                           (room.type.Contains('k')) || (room.type.Contains('K')))? 1 : 0;
                foreach (var door in room.doors)
                {
                    string doorLock = door.OtherLock(room);
                    dungeonStatistics["doorsOnPath"]             += 1;
                    dungeonStatistics["lockedDoorsOnPath"]       += doorLock.Contains("k") ? 1 : 0;
                    dungeonStatistics["bombLockedDoorsOnPath"]   += doorLock.Contains("b") ? 1 : 0;
                    dungeonStatistics["itemLockedDoorsOnPath"]   += doorLock.Contains("I") ? 1 : 0;
                    dungeonStatistics["puzzleLockedDoorsOnPath"] += doorLock.Contains("S") ? 1 : 0;
                    dungeonStatistics["softLockedDoorsOnPath"]   += doorLock.Contains("l") ? 1 : 0;
                    dungeonStatistics["bigKeyLockedDoorsOnPath"] += doorLock.Contains("K") ? 1 : 0;
                    dungeonStatistics["oneWayDoorsOnPath"]       += doorLock.Contains("O") ? 1 : 0;
                    dungeonStatistics["lookAheadsOnPath"]        += doorLock.Contains("s") ? 1 : 0;
                }
            }
            dungeonStatistics["distanceToDungeonKey"]  = path.FindIndex(a => a.type.Contains("K"));
            dungeonStatistics["distanceToSpecialItem"] = agentPath.FindIndex(a => a.keyItems > 0);
            XDocument statisticsDoc = new XDocument(new XElement("root"));

            foreach (var stat in dungeonStatistics)
            {
                statisticsDoc.Root.Add(new XElement(stat.Key, stat.Value));
            }
            foreach (var stat in roomStatistics)
            {
                statisticsDoc.Root.Add(new XElement(stat.Key, string.Join(";", stat.Value)));
            }
            statisticsDoc.Save(filename);
        }
Пример #6
0
        public SearchAgent getOptimalPath(bool requiresBigKey)
        {
            int requiredKeyItems = 0;

            foreach (var room in rooms.Values)
            {
                requiredKeyItems += room.type.Contains("I") ? 1 : 0;
            }
            HeapPriorityQueue <SearchAgent> openSet   = new HeapPriorityQueue <SearchAgent>(8000000);
            HashSet <SearchAgent>           closedSet = new HashSet <SearchAgent>();
            Dictionary <int, double>        gScore    = new Dictionary <int, double>();
            SearchAgent current = new SearchAgent(null, 0, 0, false, requiresBigKey, 0, 0, start);

            gScore[current.GetHashCode()] = 0;
            openSet.Enqueue(current, 0);
            int ii = 0;

            while (openSet.Count != 0)
            {
                ii++;
                current = openSet.Dequeue();
                closedSet.Add(current);
                if (current.currentRoom == end)
                {
                    if (current.keyItems >= requiredKeyItems)
                    {
                        return(current);
                    }
                }
                {
                    List <SearchAgent> children = current.GetChildren();
                    foreach (var child in children)
                    {
                        if (!closedSet.Contains(child))
                        {
                            double discounts = 0;
                            if (current.keyItems < child.keyItems)
                            {
                                discounts -= 0.1;
                            }
                            if (current.keysAcquired < child.keysAcquired)
                            {
                                discounts -= 0.1;
                            }
                            if (!current.bigKey && child.bigKey)
                            {
                                discounts -= 0.1;
                            }
                            double tentativeGScore = gScore[current.GetHashCode()] + 1 - discounts;// +rand.NextDouble() * 0.1 + 1;
                            if (!gScore.ContainsKey(child.GetHashCode()))
                            {
                                gScore[child.GetHashCode()] = tentativeGScore;
                                openSet.Enqueue(child, tentativeGScore);
                            }
                            else if (gScore[child.GetHashCode()] > tentativeGScore)
                            {
                                //  gScore[child.GetHashCode()] = tentativeGScore;
                                //   openSet.UpdatePriority(child, tentativeGScore);
                            }
                        }
                    }
                }
            }
            Console.WriteLine(current.pathToString());
            //   List<SearchAgent> children2 = current.GetChildren();
            //   int hash3 = children2[0].GetHashCode();
            return(null);
        }