public ProtoSubregion(int id, ProtoRegion region, ProtoRoom[,] MasterRoomList)
        {
            ID = id;
            ProtoRegion = region;
            Color = region.Color;
            Name = Statics.RandomRegionType();

            int RoomCountX = MasterRoomList.GetLength(0);
            int RoomCountY = MasterRoomList.GetLength(1);

            // keep track of available adjacent roomss
            // list for random access; hashset for lookup by coordinates
            List<ProtoRoom> AvailableAdjacentRooms = new List<ProtoRoom>();
            HashSet<PointInt> AvailableAdjacentCoordinates = new HashSet<PointInt>();

            // grab random point as starting room
            int x = Statics.Random.Next(RoomCountX);
            int y = Statics.Random.Next(RoomCountY);
            while (!MasterRoomList[x, y].Available)
            {
                x = Statics.Random.Next(RoomCountX);
                y = Statics.Random.Next(RoomCountY);
            }

            // create starting room
            ProtoRoom startingRoom = MasterRoomList[x, y];
            ProtoRooms.Add(startingRoom);
            startingRoom.Available = false;
            startingRoom.ProtoRegion = region;
            startingRoom.ProtoSubregion = this;
            UpdateAdjacentRooms(AvailableAdjacentRooms, AvailableAdjacentCoordinates, startingRoom, MasterRoomList);

            while (AvailableAdjacentRooms.Count > 0 && ((ProtoRooms.Count < Statics.MinimumRegionSize) || (Statics.Random.Next(100) < Statics.ProbabilityOfExpansion)))
            {
                // pick a random room from available neighbor set
                ProtoRoom randomNeighbor = AvailableAdjacentRooms.RandomListItem();
                randomNeighbor.Available = false;
                randomNeighbor.ProtoRegion = region;
                randomNeighbor.ProtoSubregion = this;

                AvailableAdjacentRooms.Remove(randomNeighbor);
                AvailableAdjacentCoordinates.Remove(randomNeighbor.CoordinatesXY);
                ProtoRooms.Add(randomNeighbor);

                // add new room's available neighbors to the available set
                UpdateAdjacentRooms(AvailableAdjacentRooms, AvailableAdjacentCoordinates, randomNeighbor, MasterRoomList);
            }
        }
 private void UpdateAdjacentRooms(List<ProtoRoom> AvailableAdjacentRooms, HashSet<PointInt> AvailableAdjacentCoordinates, ProtoRoom protoRoom, ProtoRoom[,] MasterRoomList)
 {
     // left
     if (protoRoom.CoordinatesXY.X > 0)
     {
         ProtoRoom neighborLeft = MasterRoomList[protoRoom.CoordinatesXY.X - 1, protoRoom.CoordinatesXY.Y];
         if (neighborLeft.Available && !AvailableAdjacentCoordinates.Contains(neighborLeft.CoordinatesXY))
         {
             AvailableAdjacentRooms.Add(neighborLeft);
             AvailableAdjacentCoordinates.Add(neighborLeft.CoordinatesXY);
         }
     }
     // right
     if (protoRoom.CoordinatesXY.X < MasterRoomList.GetLength(0) - 1)
     {
         ProtoRoom neighborRight = MasterRoomList[protoRoom.CoordinatesXY.X + 1, protoRoom.CoordinatesXY.Y];
         if (neighborRight.Available && !AvailableAdjacentCoordinates.Contains(neighborRight.CoordinatesXY))
         {
             AvailableAdjacentRooms.Add(neighborRight);
             AvailableAdjacentCoordinates.Add(neighborRight.CoordinatesXY);
         }
     }
     // above
     if (protoRoom.CoordinatesXY.Y > 0)
     {
         ProtoRoom neighborAbove = MasterRoomList[protoRoom.CoordinatesXY.X, protoRoom.CoordinatesXY.Y - 1];
         if (neighborAbove.Available && !AvailableAdjacentCoordinates.Contains(neighborAbove.CoordinatesXY))
         {
             AvailableAdjacentRooms.Add(neighborAbove);
             AvailableAdjacentCoordinates.Add(neighborAbove.CoordinatesXY);
         }
     }
     // below
     if (protoRoom.CoordinatesXY.Y < MasterRoomList.GetLength(1) - 1)
     {
         ProtoRoom neighborBelow = MasterRoomList[protoRoom.CoordinatesXY.X, protoRoom.CoordinatesXY.Y + 1];
         if (neighborBelow.Available && !AvailableAdjacentCoordinates.Contains(neighborBelow.CoordinatesXY))
         {
             AvailableAdjacentRooms.Add(neighborBelow);
             AvailableAdjacentCoordinates.Add(neighborBelow.CoordinatesXY);
         }
     }
 }
        private bool HasAvailableNeighboringRoom(ProtoRoom[,] MasterRoomList)
        {
            int RoomCountX = MasterRoomList.GetLength(0);
            int RoomCountY = MasterRoomList.GetLength(1);

            foreach (ProtoRoom room in ProtoRooms)
            {
                // check left
                if (room.CoordinatesXY.X > 0 && MasterRoomList[(int)room.CoordinatesXY.X - 1, (int)room.CoordinatesXY.Y].Available) { return true; }
                // check right
                if (room.CoordinatesXY.X < RoomCountX - 1 && MasterRoomList[(int)room.CoordinatesXY.X + 1, (int)room.CoordinatesXY.Y].Available) { return true; }
                // check up
                if (room.CoordinatesXY.Y > 0 && MasterRoomList[(int)room.CoordinatesXY.X, (int)room.CoordinatesXY.Y - 1].Available) { return true; }
                // check down
                if (room.CoordinatesXY.Y < RoomCountY - 1 && MasterRoomList[(int)room.CoordinatesXY.X, (int)room.CoordinatesXY.Y + 1].Available) { return true; }
            }

            return false;
        }