Example #1
0
 /// <summary>
 /// Returns a singleton MazeCode instance.
 /// </summary>
 /// <returns></returns>
 public static MazeCode Instance(int version)
 {
     if (instance[version] == null)
     {
         instance[version] = new MazeCode(version);
     }
     return(instance[version]);
 }
Example #2
0
        /// <summary>
        /// Constructor.
        /// Create a maze whose parameters are encoded in the given code (see property Code).
        /// </summary>
        /// <param name="code">a string of seven letters (case is ignored)</param>
        public Maze(string code)
        {
            int version = MazeCode.GetCodeVersion(code);

            this.dimensionsObj = MazeDimensions.Instance(version);
            this.codeObj       = MazeCode.Instance(version);

            codeObj.Decode(code
                           , out this.seed
                           , out this.xSize, out this.ySize
                           );
            this.random = RandomFactory.CreateRandom(seed);
        }
Example #3
0
        /// <summary>
        /// Constructor.
        /// Create a maze with the given dimensions.
        /// </summary>
        /// <param name="xSize"></param>
        /// <param name="ySize"></param>
        /// <param name="version"></param>
        /// <param name="seed"></param>
        internal Maze(int xSize, int ySize, int version, int seed)
        {
            this.dimensionsObj = MazeDimensions.Instance(version);
            this.codeObj       = MazeCode.Instance(version);

            this.xSize = Math.Max(dimensionsObj.MinSize, Math.Min(dimensionsObj.MaxXSize, xSize));
            this.ySize = Math.Max(dimensionsObj.MinSize, Math.Min(dimensionsObj.MaxYSize, ySize));

            // Get an initial random seed and use that to create the Random.
            if (seed < 0)
            {
                Random r = RandomFactory.CreateRandom();
                this.seed = r.Next(codeObj.SeedLimit);
            }
            else
            {
                this.seed = seed;
            }
            this.random = RandomFactory.CreateRandom(this.seed);
        }
Example #4
0
        /// <summary>
        /// Calculate maximum x and y dimensions, based on the desired Maze.Code length.
        /// </summary>
        protected void CalculateDimensions(out int xRange, out int yRange)
        {
            MazeCode codeObj   = MazeCode.Instance(codeVersion);
            double   codeLimit = Math.Pow(codeObj.CodeDigitRange, codeObj.CodeLength);

            if (codeLimit > long.MaxValue)
            {
                throw new Exception("Maze.Code is too large to be represented as a 64 bit integer");
            }

            codeLimit /= codeObj.SeedLimit;
            //           (MaxXSize - MinSize + 1)
            //           (MaxYSize - MinSize + 1)

            if (codeVersion == 0)
            {
                codeLimit /= (int)WallPosition.WP_NUM;
                codeLimit /= (MaxBorderDistance + 1);
                codeLimit /= (MaxBorderDistance + 1);
                //           (MaxXSize + 1)
                //           (MaxXSize + 1)
            }

            double x;

            if (codeVersion == 0)
            {
                /* We want to find the greatest integer MaxXSize and MaxYSize with the limitation:
                 *          (x-m) * (y-m) * x * x < c
                 * with:
                 *          x = MaxXSize + 1
                 *          y = MaxYSize + 1  =  MaxXSize / XYRatio + 1
                 *          m = MinSize
                 *          c = codeLimit
                 *          r = XYRatio
                 *
                 * This is approximately equivalent to:
                 *          x*x*x*x < c*r
                 * or
                 *          x = (c*r)^^(1/4)
                 * With m>0, that x is even too small.
                 */

                x = Math.Truncate(Math.Pow(codeLimit * XYRatio, 0.25));

                while ((x - MinSize) * (x / XYRatio - MinSize) * (x) * (x) < codeLimit)
                {
                    x = x + 1;
                }
            }
            else
            {
                /* We want to find the greatest integer MaxXSize and MaxYSize with the limitation:
                 *          (x-m) * (y-m) < c
                 * with:
                 *          x = MaxXSize + 1
                 *          y = MaxYSize + 1  =  MaxXSize / XYRatio + 1
                 *          m = MinSize
                 *          c = codeLimit
                 *          r = XYRatio
                 *
                 * This is approximately equivalent to:
                 *          x*x*x*x < c*r
                 * or
                 *          x = (c*r)^^(1/2)
                 * With m>0, that x is even too small.
                 */

                x = Math.Truncate(Math.Pow(codeLimit * XYRatio, 0.5));

                while ((x - MinSize) * (x / XYRatio - MinSize) < codeLimit)
                {
                    x = x + 1;
                }
            }

            /* Now, x is 1 greater than acceptable, i.e.
             *          x-1  =  MaxXSize + 1  =  MinSize + xRange + 1
             *          MinSize + yRange  =  MaxYSize  =  MaxXSize / XYRatio
             */
            xRange = (int)(x - MinSize - 2);
            yRange = (int)(MaxXSize / XYRatio - MinSize); // Note: MaxXSize is valid after xRange has been assigned
        }