Ejemplo n.º 1
0
        private Hall CreateHall(Room room, Door door)
        {
            //Calculate the position of the first segment
            List <Position> segments   = new List <Position>();
            Position        start      = new Position(room.Location);
            int             hallLength = _randomizer.ChooseCount(2, 10);
            Hall            result;

            switch (door.Wall)
            {
            case Direction.North:
            {
                start.Row--;
                start.Column += door.Position - 1;
                break;
            }

            case Direction.West:
            {
                start.Row    += door.Position - 1;
                start.Column += room.Size.Length + 1;
                break;
            }

            case Direction.East:
            {
                start.Row += door.Position - 1;
                start.Column--;
                break;
            }

            case Direction.South:
            {
                start.Row    += room.Size.Width + 1;
                start.Column += door.Position - 1;
                break;
            }

            default:
                throw new ApplicationException(string.Format("Unknown direction for wall {0}", door.Wall));
            }

            bool hallSuccess = false;

            segments.Add(start);
            hallLength--;
            for (int retry = 0; retry < MaxPlacementRetries; retry++)
            {
                Position  prevSegment            = start;
                Direction backtrackDirection     = GetOppositeDirection(door.Wall);
                Direction prevBacktrackDirection = backtrackDirection;
                if (segments.Count == hallLength + 1)
                {
                    //success!
                    hallSuccess = true;
                    break;
                }
                for (int i = 0; i < hallLength; i++)
                {
                    Direction nextDirection;
                    Position  nextSegment = new Position(prevSegment);
                    do
                    {
                        nextDirection = _randomizer.ChooseDirection();
                    } while (nextDirection == backtrackDirection || nextDirection == prevBacktrackDirection);

                    switch (nextDirection)
                    {
                    case Direction.North:
                        nextSegment.Row--;
                        break;

                    case Direction.West:
                        nextSegment.Column++;
                        break;

                    case Direction.East:
                        nextSegment.Column--;
                        break;

                    case Direction.South:
                        nextSegment.Row++;
                        break;

                    default:
                        throw new ApplicationException(string.Format("Unknown next direction for hall {0}", door.Wall));
                    }
                    if (CanPlaceHallSegment(nextSegment) == false)
                    {
                        //reset the entire hall and retry
                        segments.Clear();
                        segments.Add(start);
                        break;
                    }
                    else
                    {
                        prevSegment            = nextSegment;
                        prevBacktrackDirection = GetOppositeDirection(nextDirection);
                        segments.Add(nextSegment);
                    }
                }
            }

            if (hallSuccess == true)
            {
                //hall was successfully placed create it
                result = new Hall(GetNextHallName());
                result.StartRoomName = room.Name;
                result.Segments      = segments.ToArray();

                door.ConnectedHallName = result.Name;
            }
            else
            {
                //hall could not be placed return null
                result = null;
            }

            return(result);
        }