private void OrganicAddRoom(RandomNumberGenerator rng, Dictionary <Vector2, object> dataDict, List <Rect2> rooms, Rect2 room)
    {
        rooms.Add(room);

        var roomTypeRng = rng.RandiRange(0, 1);

        var xStart = (int)room.Position.x;
        var xEnd   = (int)room.End.x;
        var yStart = (int)room.Position.y;
        var yEnd   = (int)room.End.y;

        if (roomTypeRng == 0)         //square room
        {
            for (int x = xStart; x <= xEnd; x++)
            {
                for (int y = yStart; y <= yEnd; y++)
                {
                    var vector = new Vector2(x, y);
                    dataDict[vector] = null;
                }
            }
        }
        else if (roomTypeRng == 1)         //organic room
        {
            var unit  = Factor * room.Size;
            var order = new List <Rect2>()
            {
                room.GrowIndividual(-unit.x, 0, -unit.x, unit.y - room.Size.y),
                room.GrowIndividual(unit.x - room.Size.x, -unit.y, 0, -unit.y),
                room.GrowIndividual(-unit.x, unit.y - room.Size.y, -unit.x, 0),
                room.GrowIndividual(0, -unit.y, unit.x - room.Size.x, -unit.y)
            };

            var poly = new List <Vector2>();
            for (int i = 0; i < order.Count; i++)            //?
            {
                var rect        = order[i];
                var isEven      = (i % 2) == 0;           //?
                var polyPartial = new List <Vector2>();
                var rngRange    = rng.RandiRange(1, 2);
                for (int r = 0; r < rngRange; r++)                 //?
                {
                    var p = new Vector2(rng.RandfRange(rect.Position.x, rect.End.x), rng.RandfRange(rect.Position.y, rect.End.y));
                    polyPartial.Add(p);
                }

                polyPartial.Sort((v1, v2) =>
                {
                    var result = isEven ? Utils.LessX(v1, v2) : Utils.LessY(v1, v2);
                    if (result)
                    {
                        return(-1);
                    }
                    else
                    {
                        return(1);
                    }
                });

                if (i > 1)
                {
                    polyPartial.Reverse();
                }

                poly.AddRange(polyPartial);
            }

            for (int x = xStart; x <= xEnd; x++)
            {
                for (int y = yStart; y <= yEnd; y++)
                {
                    var vector = new Vector2(x, y);
                    if (Geometry.IsPointInPolygon(vector, poly.ToArray()))
                    {
                        dataDict[vector] = null;
                    }
                }
            }
        }
    }
    /// <summary>The <c>_addRoom</c> method adds randomly generated rooms in the
    /// <c>rooms</c> list, and each Vector2 point of the room in the <c>data</c>
    /// dictionary.</summary>
    public void _addRoom(RandomNumberGenerator rng, Dictionary <Vector2, int> data, List <Rect2> rooms, Rect2 room)
    {
        rooms.Add(room);

        // 50% chance to create a rectangular room.
        if (rng.RandiRange(0, 1) == 0)
        {
            for (int x = (int)room.Position.x; x < (int)room.End.x; x++)
            {
                for (int y = (int)room.Position.y; y < (int)room.End.y; y++)
                {
                    data[new Vector2(x, y)] = 0;
                }
            }
        }
        else
        {
            var     unit  = FACTOR * room.Size;
            Rect2[] order = new Rect2[] {
                // Create a rectangle at the top part of the original room rectangle.
                // This rectangle is two units narrower than the original room Rect2
                // with one unit taken from each side, and one unit high.
                room.GrowIndividual(-unit.x, 0, -unit.x, unit.y - room.Size.y),
                // This one is on the right side of the original room rectangle. It's
                // width is one unit and its height is two units smaller than the originals.
                room.GrowIndividual(unit.x - room.Size.x, -unit.y, 0, -unit.y),
                // This one is at the bottom. Two units narrower and one unit high.
                room.GrowIndividual(-unit.x, unit.y - room.Size.y, -unit.x, 0),
                // This one's at the left side. Two units shorter and one unit wide.
                room.GrowIndividual(0, -unit.y, unit.x - room.Size.x, -unit.y),
            };

            // Stores the Vector2's that make up the organic polygon shape
            List <Vector2> poly = new List <Vector2>();

            // Loop through the rectangles one by one
            for (int index = 0; index < order.Length; index++)
            {
                Rect2 rect = order[index];
                // Top and bottom are even, sides are odd
                bool           isEven       = index % 2 == 0;
                List <Vector2> poly_partial = new List <Vector2>();

                // Create one or two points inside each rectangle
                foreach (int r in Enumerable.Range(0, rng.RandiRange(1, 2)))
                {
                    // Pick a random point inside the rectangle
                    poly_partial.Add(new Vector2(
                                         rng.RandfRange(rect.Position.x, rect.End.x),
                                         rng.RandfRange(rect.Position.y, rect.End.y)
                                         ));
                }
                // Sort the points that get created using LINQ
                if (isEven)
                {
                    poly_partial.Sort((vec1, vec2) => vec1.x.CompareTo(vec2.x));
                }
                else
                {
                    poly_partial.Sort((vec1, vec2) => vec1.y.CompareTo(vec2.y));
                }
                // If two points are created, reverse the order so that the points
                // end up being in clockwise order.
                if (index > 1)
                {
                    poly_partial.Reverse();
                }
                // Add points that get created to the complete polygon
                poly.AddRange(poly_partial);
            }

            // Loop through the room's points
            for (float x = room.Position.x; x < room.End.x; x++)
            {
                for (float y = room.Position.y; y < room.End.y; y++)
                {
                    Vector2 point = new Vector2(x, y);
                    // Check to see if the current point is inside the polygon
                    // we just created. Store the point in data only if the point
                    // is within the polygon.
                    if (Geometry.IsPointInPolygon(point, poly.ToArray()))
                    {
                        data[point] = 0;
                    }
                }
            }
        }
    }