Ejemplo n.º 1
0
 /// <summary>
 /// Legt fest, dass eine Tür durchschritten wurde
 /// </summary>
 /// <param name="set">Das Lookup-Set</param>
 /// <param name="room">Der Raum</param>
 /// <param name="direction">Die Richtung</param>
 private static void SetBeenThere(HashSet<Tuple<IRoom4, Door4>> set, IRoom4 room, Door4 direction)
 {
     Contract.Requires(set != null);
     Contract.Requires(room != null);
     Contract.Requires(direction.ExactlyOneValueSet());
     set.Add(new Tuple<IRoom4, Door4>(room, direction));
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Setzt einen Startraum und ermittelt den Raum, der am weitesten entfernt ist
        /// </summary>
        /// <param name="startRoom">Der Startraum</param>
        /// <param name="distances">Die Karte der Entfernungen vom Startraum</param>
        /// <returns>Die Liste der Sackgassen mit ihren Entfernungen zum Startpunkt</returns>
        /// <exception cref="ArgumentException">Der angegebene Raum liegt nicht im Labyrinth</exception>
        public IList<Tuple<int, IRoom4>> SetStartingPoint(IRoom4 startRoom, out int[,] distances)
        {
            // TODO: Logik in den Generator übernehmen.

            Contract.Requires(startRoom != null);
            Contract.Ensures(Contract.Result<IList<Tuple<int, IRoom4>>>() != null);
            Contract.Ensures(Contract.ValueAtReturn(out distances) != null);

            var startPosition = GetPosition(startRoom);
            if (startPosition == null) throw new ArgumentException("Der gegebene Raum liegt nicht im Labyrinth", "startRoom");

            // Werte intialisieren
            int width = Rooms.GetLength(0);
            int height = Rooms.GetLength(1);

            int roomCount = width * height;
            int roomsVisited = 1;

            // Hilfslisten vorbereiten
            HashSet<Tuple<IRoom4, Door4>> visited = new HashSet<Tuple<IRoom4, Door4>>();
            distances = new int[width, height];
            int lastDistance = 0;

            // Die Zielwerte
            List<Tuple<int, IRoom4>> deadEnds = new List<Tuple<int, IRoom4>>();

            // Bewegungs-Hilfsklasse erzeugen
            Marcher4 marcher = new Marcher4(Door4.East, startPosition.Item1, startPosition.Item2);

            // Und los.
            while (roomsVisited < roomCount)
            {
                IRoom4 currentRoom = GetRoom(marcher.X, marcher.Y);
                Door4 currentDoors = currentRoom.Doors;

                // Signalify your life
                OnMarcherMoved(new DistanceTrackingEventArgs(marcher.X, marcher.Y, marcher.Direction));

                // Distanz setzen.
                // - Wenn wir nicht der Startraum sind und noch keine Distanz haben, alte Distanz erhöhen und setzen
                // - In jedem anderen Fall: "alte Distanz" auf aktuelle Distanz setzen (backtracking!)
                int currentDistance;
                if (currentRoom != startRoom && distances[marcher.X, marcher.Y] == 0 )
                {
                    currentDistance = ++lastDistance;
                    distances[marcher.X, marcher.Y] = currentDistance;
                    ++roomsVisited;
                }
                else
                {
                    lastDistance = currentDistance = distances[marcher.X, marcher.Y];
                }

                // Wenn wir uns nach links bewegen können und dort noch nicht waren
                if (marcher.CanTurnLeft(currentDoors) && !BeenThere(visited, currentRoom, marcher.LeftDirection))
                {
                    SetBeenThere(visited, currentRoom, marcher.LeftDirection);
                    marcher.TurnLeft().MoveForward();
                    continue;
                }

                // Wenn wir uns vorwärts bewegen können und dort noch nicht waren
                if (marcher.CanMoveForward(currentDoors) && !BeenThere(visited, currentRoom, marcher.Direction))
                {
                    SetBeenThere(visited, currentRoom, marcher.Direction);
                    marcher.MoveForward();
                    continue;
                }

                // Wenn wir uns nach rechts bewegen können und dort noch nicht waren
                // (entspricht mehrfacher Linksdrehung)
                if (marcher.CanTurnRight(currentDoors) && !BeenThere(visited, currentRoom, marcher.RightDirection))
                {
                    SetBeenThere(visited, currentRoom, marcher.RightDirection);
                    marcher.TurnRight().MoveForward();
                    continue;
                }

                // Hier angekommen, kann weder vorwärts, noch rückwärts gegangen werden

                // Raum als Sackgasse markieren
                if (currentRoom != startRoom) deadEnds.Add(new Tuple<int, IRoom4>(currentDistance, currentRoom));
                marcher.TurnAround().MoveForward();

            }

            // Entfernteste Punkte zurückgeben
            deadEnds.Sort((a, b) => -1 * a.Item1.CompareTo(b.Item1));
            deadEnds.TrimExcess();
            return deadEnds;
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Ermittelt, ob eine Tür bereits durchschritten wurde
 /// </summary>
 /// <param name="set">Das Lookup-Set</param>
 /// <param name="room">Der Raum</param>
 /// <param name="direction">Die Richtung</param>
 /// <returns><c>true</c>, wenn der angegebene Raum bereits durch diese Tür verlassen wurde, ansonsten <c>false</c></returns>
 private static bool BeenThere(HashSet<Tuple<IRoom4, Door4>> set, IRoom4 room, Door4 direction)
 {
     Contract.Requires(set != null);
     Contract.Requires(room != null);
     Contract.Requires(direction.ExactlyOneValueSet());
     return set.Contains(new Tuple<IRoom4, Door4>(room, direction));
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Ermittelt die Koordinaten eines Raumes
        /// </summary>
        /// <param name="room">Der zu findende Raum</param>
        /// <returns>Die Position des Raumes oder <c>null</c>, falls der Raum nicht gefunden wurde</returns>
        public Tuple<int, int> GetPosition(IRoom4 room)
        {
            Contract.Requires(room != null);

            Tuple<int, int> position;
            return _roomIndexLookup.TryGetValue(room, out position) ? position : null;
        }