Beispiel #1
0
        /// <summary>
        /// Reserves a rectangular area for the given image in this.Maze.
        /// The chosen location is remembered in this.imageLocations.
        /// Returns true if the reservation was successful.
        /// </summary>
        /// <param name="contourImage"></param>
        /// <returns></returns>
        private bool AddImage(ContourImage contourImage)
        {
            Image img     = contourImage.DisplayedImage;
            int   padding = MazePainter.ApplyScaleFactor(8) + this.wallWidth;
            int   sqW     = (img.Width + padding) / this.gridWidth + 1;
            int   sqH     = (img.Height + padding) / this.gridWidth + 1;

            int xOffsetImg = (sqW * gridWidth - img.Width) / 2;
            int yOffsetImg = (sqH * gridWidth - img.Height) / 2;

            OutlineShape shape = (ContourImage.DisplayProcessedImage ? contourImage.GetCoveredShape(gridWidth, wallWidth, xOffsetImg, yOffsetImg) : null);

            Rectangle rect;

            if (Maze.ReserveRectangle(sqW, sqH, 2, shape, out rect))
            {
                // Remember the image data and location.  It will be painted in PaintMaze().
                int x = rect.X * gridWidth + xOffset + xOffsetImg;
                int y = rect.Y * gridWidth + yOffset + yOffsetImg;
                imageLocations.Add(new Rectangle(x, y, img.Width, img.Height));
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #2
0
 public MixedIrregularMazeShape(OutlineShape outline, IrregularMazeShape inside, IrregularMazeShape outside)
     : base(Kind.Mixed)
 {
     this.outline = outline;
     this.inside  = inside;
     this.outside = outside;
 }
Beispiel #3
0
        /// <summary>
        /// Reserves a rectangular region of the given dimensions at a random location.
        /// The area must not touch any other reserved ares.
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="borderDistance">minimum number of squares between the reserved area and the maze border</param>
        /// <param name="rect"></param>
        /// <returns>true if the reservation was successful</returns>
        public bool ReserveRectangle(int width, int height, int borderDistance, OutlineShape shape, out Rectangle rect)
        {
            // Reject very large areas.
            if (width < 2 || height < 2 || width > xSize - Math.Max(4, 2 * borderDistance) || height > ySize - Math.Max(4, 2 * borderDistance))
            {
                rect = new Rectangle();
                return(false);
            }

            for (int nTries = 0; nTries < 100; nTries++)
            {
                // Choose a random location.
                // The resulting rectangle may touch the borders.
                int x = random.Next(borderDistance, xSize - width - borderDistance);
                int y = random.Next(borderDistance, ySize - height - borderDistance);

                if (ReserveRectangle(x, y, width, height, shape))
                {
                    rect = new Rectangle(x, y, width, height);
                    return(true);
                }
            }

            rect = new Rectangle();
            return(false);
        }
Beispiel #4
0
        /// <summary>
        /// Take all modifyable parameters from the given data object.
        /// </summary>
        /// <param name="data"></param>
        public void TakeParametersFrom(AriadneSettingsData data)
        {
            // The Auto... flags for Width and Height have already been checked by the MazeUserControl.
            this.xSize = Math.Max(dimensionsObj.MinSize, Math.Min(dimensionsObj.MaxXSize, data.MazeWidth));
            this.ySize = Math.Max(dimensionsObj.MinSize, Math.Min(dimensionsObj.MaxYSize, data.MazeHeight));

            if (!data.AutoSeed)
            {
                this.seed = Math.Max(0, Math.Min(codeObj.SeedLimit - 1, data.Seed));
            }
            else
            {
                Random r = RandomFactory.CreateRandom();
                this.seed = r.Next(codeObj.SeedLimit);
            }
            this.random = RandomFactory.CreateRandom(seed);

            this.reservedAreas.Clear();
            this.reservedAreaShapes.Clear();
            this.outlineShape = null;
            this.embeddedMazeShapes.Clear();
            this.embeddedMazes.Clear();

            this.Irregular    = data.IrregularMaze;
            this.Irregularity = data.Irregularity;

            // Decode(data.Code);
        }
Beispiel #5
0
        private void FixOutline(OutlineShape shape)
        {
            // We need a test for the "inside" of an OutlineShape.
            OutlineShape.InsideShapeDelegate test = delegate(int x, int y) { return(shape[x, y]); };

            FixOutline(test, WallState.WS_OUTLINE);
        }
Beispiel #6
0
 /// <summary>
 /// Mark the defined outline walls.
 /// </summary>
 private void FixOutlineShape()
 {
     if (outlineShape != null)
     {
         OutlineShape shape = outlineShape;
         FixOutline(shape);
     }
 }
        private static void TestHalfArea(string testObject, Bitmap bitmap, RotateFlipType rft, int scale)
        {
            int xSize = Math.Max(bitmap.Width, bitmap.Height) * scale;
            int ySize = xSize;

            OutlineShape actual = SWA_Ariadne_Outlines_TilesOutlineShapeAccessor.FromBitmap(xSize, ySize, bitmap, rft, scale);

            Assert.AreEqual(xSize * ySize / 2, actual.Area, testObject + " " + rft.ToString() + ": incorrect Area");
        }
Beispiel #8
0
        /// <summary>
        /// Returns the shape of a ContourImage or null if none of the images has a real contour.
        /// </summary>
        public OutlineShape SuggestOutlineShape(Random r, double offCenter, double size)
        {
            foreach (ContourImage img in this.images)
            {
                if (img.HasContour)
                {
                    // Use img.GetCoveredShape() as an OutlineShapeBuilder.
                    return(OutlineShape.RandomInstance(r, img.GetCoveredShape, this.XSize, this.YSize, offCenter, size));
                }
            }

            return(null);
        }
Beispiel #9
0
 /// <summary>
 /// Overwrites the mazeId of every square inside the shape.
 /// </summary>
 /// <param name="shape"></param>
 private void InstallInHost(OutlineShape shape)
 {
     for (int x = 0; x < xSize; x++)
     {
         for (int y = 0; y < ySize; y++)
         {
             if (shape[x, y] && !this[x, y].isReserved)
             {
                 this[x, y].MazeId = this.mazeId;
             }
         }
     }
 }
Beispiel #10
0
        /// <summary>
        /// Returns an irregular pattern that is only applied to the inside/outside of the given OutlineShape.
        /// The remainder is a regular pattern (without preferred directions).
        /// </summary>
        /// <param name="r"></param>
        /// <param name="maze"></param>
        /// <param name="outline"></param>
        /// <param name="confinedToInside">
        /// When true: only the inside is irregular.
        /// When false: only the outside is irregular.
        /// </param>
        /// <returns></returns>
        private static IrregularMazeShape ConfinedInstance(Random r, Maze maze, OutlineShape outline, bool confinedToInside)
        {
            IrregularMazeShape regular   = new PreferNothing();
            IrregularMazeShape irregular = SimpleInstance(r, maze);

            if (confinedToInside)
            {
                return(new MixedIrregularMazeShape(outline, irregular, regular));
            }
            else
            {
                return(new MixedIrregularMazeShape(outline, regular, irregular));
            }
        }
        /// <summary>
        /// Add an outline shape to the maze.
        /// </summary>
        private bool AddOutlineShape()
        {
            int percentage = (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_OUTLINE_SHAPES) ? 80 : 0);

            if (random.Next(100) < percentage)
            {
                OutlineShape shape = mazeUserControl.RandomShape(0.3, 0.7, random);
                mazeUserControl.Maze.OutlineShape = shape;

                return(true);
            }

            return(false);
        }
Beispiel #12
0
        /// <summary>
        /// Returns a randomly chosen instance.
        /// Some patterns are "simple", applied to the whole maze area.
        /// Some patterns are "mixed", with two different patterns on the inside/outside of an OutlineShape.
        /// </summary>
        /// <param name="r"></param>
        /// <returns></returns>
        public static IrregularMazeShape RandomInstance(Random r, Maze maze)
        {
            if (maze.OutlineShape != null && r.Next(100) < 10)
            {
                // Build a mixed instance, using the OutlineShape laid into the maze.

                if (r.Next(100) < 50)
                {
                    // two different patterns inside and outside of the OutlineShape
                    return(MixedInstance(r, maze, maze.OutlineShape));
                }
                else if (r.Next(100) < 66)
                {
                    // the outside of the OutlineShape is regular
                    return(ConfinedInstance(r, maze, maze.OutlineShape, true));
                }
                else
                {
                    // the inside of the OutlineShape is regular
                    return(ConfinedInstance(r, maze, maze.OutlineShape, false));
                }
            }
            else if (maze.OutlineShape == null && r.Next(100) < 20)
            {
                // Build a mixed instance, using a new OutlineShape.

                OutlineShape outline = OutlineShape.RandomInstance(r, maze.XSize, maze.YSize, 0.3, 0.9);

                if (r.Next(100) < 20)
                {
                    // two different patterns inside and outside of the OutlineShape
                    return(MixedInstance(r, maze, outline));
                }
                else if (r.Next(100) < 50)
                {
                    // the outside of the OutlineShape is regular
                    return(ConfinedInstance(r, maze, outline, true));
                }
                else
                {
                    // the inside of the OutlineShape is regular
                    return(ConfinedInstance(r, maze, outline, false));
                }
            }
            else
            {
                return(SimpleInstance(r, maze));
            }
        }
Beispiel #13
0
        /// <summary>
        /// Reserves a rectanglurar region of the given dimensions.
        /// The area must not touch any other reserved areas.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns>true if the reservation was successful</returns>
        public bool ReserveRectangle(int x, int y, int width, int height, OutlineShape shape)
        {
            // Restrict to the actual maze area.
            if (x < 0)
            {
                width += x;
                x      = 0;
            }
            if (y < 0)
            {
                height += y;
                y       = 0;
            }
            width  = Math.Min(xSize - x, width);
            height = Math.Min(ySize - y, height);

            // Reject very large areas.
            if (width < 1 || height < 1 || width > xSize - 4 || height > ySize - 4)
            {
                return(false);
            }

            // The candidate rectangle.
            Rectangle candidate = new Rectangle(x, y, width, height);

            // The candidate, extended with two squares around all four edges.
            Rectangle extendedCandidate = new Rectangle(x - 2, y - 2, width + 4, height + 4);

            bool reject = false;

            foreach (Rectangle rect in this.reservedAreas)
            {
                // Reject the candidate if its extension would intersect with another reserved area.
                if (extendedCandidate.IntersectsWith(rect))
                {
                    reject = true;
                }
            }

            if (!reject)
            {
                reservedAreas.Add(candidate);
                reservedAreaShapes.Add(shape);
                return(true);
            }

            return(false);
        }
Beispiel #14
0
        /// <summary>
        /// Creates a maze that is embedded in the hostMaze.
        /// The maze is formed by all squares inside the given shape.
        /// </summary>
        /// <param name="hostMaze"></param>
        /// <param name="mazeId"></param>
        /// <param name="shape"></param>
        public EmbeddedMaze(Maze hostMaze, int mazeId, OutlineShape shape)
            : base(hostMaze.XSize, hostMaze.YSize)
        {
            if (mazeId <= MazeSquare.PrimaryMazeId || mazeId > MazeSquare.MaxMazeId)
            {
                throw new Exception("invalid maze ID: " + mazeId.ToString());
            }

            this.hostMaze = hostMaze;
            this.mazeId   = mazeId;

            // We want to share the host's Random generator.
            this.random = hostMaze.Random;

            this.InstallInHost(shape);
        }
Beispiel #15
0
        /// <summary>
        /// Returns a combination of two different patterns on the inside/outside of the given OutlineShape.
        /// </summary>
        /// <param name="r"></param>
        /// <param name="maze"></param>
        /// <param name="outline"></param>
        /// <returns></returns>
        private static IrregularMazeShape MixedInstance(Random r, Maze maze, OutlineShape outline)
        {
            IrregularMazeShape inside = null, outside = null;

            do
            {
                inside  = SimpleInstance(r, maze);
                outside = SimpleInstance(r, maze);
            } while (inside.kind <= Kind.Neutral ||
                     outside.kind <= Kind.Neutral ||
                     inside.kind == outside.kind ||
                     (inside.kind != Kind.Zigzags && outside.kind != Kind.Zigzags)
                     );

            return(new MixedIrregularMazeShape(outline, inside, outside));
        }
Beispiel #16
0
        /// <summary>
        /// Returns an OutlineShape for the given location and size.
        /// If one of the displayed images has a defined contour,
        /// the shape is preferrably derived from that contour.
        /// </summary>
        /// <param name="offCenter">A fraction of the control's size.</param>
        /// <param name="size">A fraction of the control's size.</param>
        public OutlineShape RandomShape(double offCenter, double size, Random random)
        {
            OutlineShape result = null;

            // We may suggest a shape based on the displayed ContourImage.
            if (random.Next(100) < (ContourImage.DisplayProcessedImage ? 12 : 25))
            {
                result = SuggestOutlineShape(random, offCenter, size);
            }

            if (result == null)
            {
                result = OutlineShape.RandomInstance(random, Maze.XSize, Maze.YSize, offCenter, size);
            }

            return(result);
        }
Beispiel #17
0
        /// <summary>
        /// Creates the embedded mazes, as defined in embeddedMazeShapes.
        /// </summary>
        /// Note: The algorithm must provide that all mazes (main and embedded) are totally connected.
        private void FixEmbeddedMazes()
        {
            for (int i = 0; i < embeddedMazeShapes.Count; i++)
            {
                int embeddedMazeId = this.MazeId + 1 + i;

                if (embeddedMazeId > MazeSquare.MaxMazeId)
                {
                    break;
                }

                // We need a test that regards the reserved squares and current embedded mazes as the "inside" of a shape.
                OutlineShape.InsideShapeDelegate regularTest = delegate(int x, int y)
                {
                    return(this.squares[x, y].MazeId != MazeSquare.PrimaryMazeId);
                };

                // This test ensures that the border of the main maze must also not be covered.
                OutlineShape.InsideShapeDelegate conservativeTest = delegate(int x, int y)
                {
                    if (x - 2 < 0 || x + 2 >= this.XSize || y - 2 < 0 || y + 2 >= this.YSize)
                    {
                        return(true);
                    }
                    return(this.squares[x, y].MazeId != MazeSquare.PrimaryMazeId);
                };

                OutlineShape originalShape  = embeddedMazeShapes[i];
                OutlineShape connectedShape = originalShape.ConnectedSubset(conservativeTest).Closure(regularTest);

                // Discard the shape if the connected subset is too small.
                if (connectedShape.Area >= 0.3 * originalShape.Area)
                {
                    EmbeddedMaze embeddedMaze = new EmbeddedMaze(this, embeddedMazeId, connectedShape);
                    this.embeddedMazes.Add(embeddedMaze);
                }

                if (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_OUTLINE_SHAPES))
                {
                    // The disconnected and enclosed parts of the original shape are handled as a regular outline shape.
                    FixOutline(originalShape);
                }
            }
        }
        public static MazeTestForm.MazeConfiguratorDelegate DistortedPolygonConfiguratorDelegate(int corners, int windings, double slant, double centerX, double centerY, double shapeSize, double distortionWinding)
        {
            MazeTestForm.MazeConfiguratorDelegate mazeConfigurator = delegate(Maze maze)
            {
                int          xSize = maze.XSize, ySize = maze.YSize;
                OutlineShape baseShape = SWA_Ariadne_Outlines_PolygonOutlineShapeAccessor.CreatePrivate(corners, windings, slant, xSize, ySize, centerX, centerY, shapeSize);

                SWA_Ariadne_Outlines_SmoothOutlineShapeAccessor baseShapeAccessor = new SWA_Ariadne_Outlines_SmoothOutlineShapeAccessor(baseShape);

                double xCenter, yCenter, size;
                SWA_Ariadne_Outlines_OutlineShapeAccessor.ConvertParameters(xSize, ySize, centerX, centerY, shapeSize, out xCenter, out yCenter, out size);
                SWA_Ariadne_Outlines_DistortedOutlineShape_DistortionAccessor distortion = SWA_Ariadne_Outlines_DistortedOutlineShapeAccessor.SpiralDistortion(xCenter, yCenter, size, distortionWinding);

                OutlineShape targetShape = SWA_Ariadne_Outlines_DistortedOutlineShapeAccessor.CreatePrivate(xSize, ySize, baseShapeAccessor, distortion);

                maze.OutlineShape = targetShape;
            };
            return(mazeConfigurator);
        }
Beispiel #19
0
        /// <summary>
        /// Mark the squares inside the reserved areas.
        /// </summary>
        private void FixReservedAreas()
        {
            for (int i = 0; i < this.reservedAreas.Count; i++)
            {
                Rectangle    rect  = this.reservedAreas[i];
                OutlineShape shape = this.reservedAreaShapes[i];

                for (int x = rect.Left; x < rect.Right; x++)
                {
                    for (int y = rect.Top; y < rect.Bottom; y++)
                    {
                        if (shape == null || shape[x - rect.Left, y - rect.Top] == true)
                        {
                            this.squares[x, y].isReserved = true;
                        }
                    }
                }
            }
        }
        public void ItemTest()
        {
            int xSize = 0;                                                                                              // TODO: Initialize to an appropriate value

            int ySize = 0;                                                                                              // TODO: Initialize to an appropriate value

            SWA.Ariadne.Outlines.Tests.SWA_Ariadne_Outlines_SmoothOutlineShapeAccessor baseShape = null;                // TODO: Initialize to an appropriate value

            SWA.Ariadne.Outlines.Tests.SWA_Ariadne_Outlines_DistortedOutlineShape_DistortionAccessor distortion = null; // TODO: Initialize to an appropriate value

            OutlineShape target = SWA.Ariadne.Outlines.Tests.SWA_Ariadne_Outlines_DistortedOutlineShapeAccessor.CreatePrivate(xSize, ySize, baseShape, distortion);

            bool val = false; // TODO: Assign to an appropriate value for the property

            SWA.Ariadne.Outlines.Tests.SWA_Ariadne_Outlines_DistortedOutlineShapeAccessor accessor = new SWA.Ariadne.Outlines.Tests.SWA_Ariadne_Outlines_DistortedOutlineShapeAccessor(target);

            double x = 0; // TODO: Initialize to an appropriate value

            double y = 0; // TODO: Initialize to an appropriate value


            Assert.AreEqual(val, accessor[x, y], "SWA.Ariadne.Outlines.DistortedOutlineShape.this was not set correctly.");
            Assert.Inconclusive("Verify the correctness of this test method.");
        }
        /// <summary>
        /// Add an embedded maze.
        /// </summary>
        private bool AddEmbeddedMaze()
        {
            int percentage = (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_MULTIPLE_MAZES) ? 15 : 0);

            if (random.Next(100) < percentage)
            {
                OutlineShape shape = null;
                int          area = mazeUserControl.Maze.XSize * mazeUserControl.Maze.YSize;
                int          minArea = (int)(0.1 * area), maxArea = (int)(0.5 * area);

                while (true)
                {
                    shape = mazeUserControl.RandomShape(0.2, 1.0, random);

                    // Discard shapes that are too small or too large.
                    if (minArea > shape.Area || shape.Area > maxArea)
                    {
                        continue;
                    }

                    // Discard shapes that cover the whole maze.
                    if (shape.BoundingBox.Width >= mazeUserControl.Maze.XSize || shape.BoundingBox.Height >= mazeUserControl.Maze.YSize)
                    {
                        continue;
                    }

                    break; // Terminate the loop.
                }

                mazeUserControl.Maze.AddEmbeddedMaze(shape);

                return(true);
            }

            return(false);
        }
Beispiel #22
0
        private void AddOutlineShape(AriadneSettingsData data)
        {
            Random r = Maze.Random;

            double offCenter = data.OutlineOffCenter / 100.0;
            double size      = data.OutlineSize / 100.0;

            OutlineShape.OutlineShapeBuilder shapeBuilderDelegate = null;

            switch (data.OutlineKind)
            {
            case AriadneSettingsData.OutlineKindEnum.Random:
                shapeBuilderDelegate = OutlineShape.RandomOutlineShapeBuilder(r);
                break;

            case AriadneSettingsData.OutlineKindEnum.Circle:
                shapeBuilderDelegate = OutlineShape.Circle;
                break;

            case AriadneSettingsData.OutlineKindEnum.Diamond:
                shapeBuilderDelegate = OutlineShape.Diamond;
                break;

            case AriadneSettingsData.OutlineKindEnum.Character:
                shapeBuilderDelegate = OutlineShape.Character;
                break;

            case AriadneSettingsData.OutlineKindEnum.Symbol:
                shapeBuilderDelegate = OutlineShape.Symbol;
                break;

            case AriadneSettingsData.OutlineKindEnum.Polygon:
                shapeBuilderDelegate = OutlineShape.Polygon;
                break;

            case AriadneSettingsData.OutlineKindEnum.Function:
                shapeBuilderDelegate = OutlineShape.Function;
                break;

            case AriadneSettingsData.OutlineKindEnum.Bitmap:
                shapeBuilderDelegate = OutlineShape.Bitmap;
                break;

            case AriadneSettingsData.OutlineKindEnum.Tiles:
                shapeBuilderDelegate = OutlineShape.Tiles;
                break;

            case AriadneSettingsData.OutlineKindEnum.Rectangles:
                shapeBuilderDelegate = OutlineShape.Rectangles;
                break;

            case AriadneSettingsData.OutlineKindEnum.Grid:
                shapeBuilderDelegate = OutlineShape.Grid;
                break;

            case AriadneSettingsData.OutlineKindEnum.GridElement:
                shapeBuilderDelegate = OutlineShape.GridElement;
                break;

            case AriadneSettingsData.OutlineKindEnum.Maze:
                shapeBuilderDelegate = OutlineShape.Maze;
                break;

            case AriadneSettingsData.OutlineKindEnum.Lines:
                shapeBuilderDelegate = OutlineShape.Lines;
                break;

            case AriadneSettingsData.OutlineKindEnum.Circles:
                shapeBuilderDelegate = OutlineShape.Circles;
                break;
            }
            if (shapeBuilderDelegate != null)
            {
                OutlineShape shape = OutlineShape.RandomInstance(r, shapeBuilderDelegate, XSize, YSize, offCenter, size);

                if (data.DistortedOutlines)
                {
                    shape = shape.DistortedCopy(r);
                }

                if (data.AsEmbeddedMaze)
                {
                    Maze.AddEmbeddedMaze(shape);
                }
                else
                {
                    Maze.OutlineShape = shape;
                }
            }
        }
Beispiel #23
0
 public bool AddEmbeddedMaze(OutlineShape shape)
 {
     this.embeddedMazeShapes.Add(shape);
     return(true);
 }
Beispiel #24
0
 public PreferTiledPattern(Random r)
     : base(Kind.Other)
 {
     this.shape = TilesOutlineShape.FromSmallBitmap(r);
     this.preferStayingInside = (r.Next(2) == 0);
 }