示例#1
0
        public ConstructionBlock Mirror()
        {
            string bblock = "";

            for (int y = 0; y < Height; y++)
            {
                for (int x = Width - 1; x >= 0; x--)
                {
                    bblock += this.block [x, y];
                }
            }
            var res = new ConstructionBlock(bblock, this.Width, this.Height, this.ID);

            foreach (var exit in this.exits)
            {
                res.AddExit(this.Width - 1 - exit.X, exit.Y, exit.MirrorDirection(), exit.CanBeClosed);
            }
            foreach (var obj in this.objects)
            {
                if (Array.IndexOf(obj.Variations, "M") > -1)
                {
                    res.AddObject(obj.ID, this.Width - 1 - obj.X, obj.Y, obj.Probability, new string[] { });
                }
            }
            return(res);
        }
示例#2
0
        public ConstructionBlock Flip()
        {
            string bblock = "";

            for (int y = Height - 1; y >= 0; y--)
            {
                for (int x = 0; x < Width; x++)
                {
                    bblock += this.block [x, y];
                }
            }
            var res = new ConstructionBlock(bblock, this.Width, this.Height, this.ID);

            foreach (var exit in this.exits)
            {
                res.AddExit(exit.X, this.Height - 1 - exit.Y, exit.FlipDirection(), exit.CanBeClosed);
            }
            foreach (var obj in this.objects)
            {
                if (Array.IndexOf(obj.Variations, "F") > -1)
                {
                    res.AddObject(obj.ID, obj.X, this.Height - 1 - obj.Y, obj.Probability, new string[] { });
                }
            }
            return(res);
        }
示例#3
0
 public void PlaceBlock(ConstructionBlock block, int x, int y)
 {
     for (int j = 0; j < block.Height; j++)
     {
         for (int i = 0; i < block.Width; i++)
         {
             //if (i + x >= 0 && i + x < maxX && j + y >= 0 && j + y < maxY && this.IsUsed [i + x, j + y] == false) {
             if (this.IsValid(i + x, j + y) && this.IsUsed [i + x, j + y] == false)
             {
                 this.Data [i + x, j + y]   = block.GetTile(i, j);
                 this.IsUsed [i + x, j + y] = true;
                 this.UsedArea++;
             }
         }
     }
     foreach (var exit in block.Exits)
     {
         var i = exit.X + x;
         var j = exit.Y + y;
         if (this.IsOpenExit(i, j, exit.Direction))
         {
             var nexit = new BlockExit {
                 X = i, Y = j, Direction = exit.Direction, CanBeClosed = exit.CanBeClosed
             };
             this.exits.Add(nexit);
         }
     }
     foreach (var obj in block.Objects)
     {
         var nobj = new BlockObject();
         nobj.ID          = obj.ID;
         nobj.Probability = obj.Probability;
         nobj.X           = obj.X + x;
         nobj.Y           = obj.Y + y;
         this.Objects.Add(nobj);
     }
     if (block.StartPoint != null)
     {
         this.StartCell.X = block.StartPoint.X + x;
         this.StartCell.Y = block.StartPoint.Y + y;
     }
     if (block.EndPoint != null)
     {
         this.EndCell.X = block.EndPoint.X + x;
         this.EndCell.Y = block.EndPoint.Y + y;
     }
     this.blockCount++;
     minX = (x < minX) ? (x > 0) ? x : 0 : minX;
     minY = (y < minY) ? (y > 0) ? y : 0 : minY;
     maxX = (x + block.Width > maxX) ? x + block.Width : maxX;
     maxY = (y + block.Height > maxY) ? y + block.Height : maxY;
 }
示例#4
0
 public bool CanPlaceBlock(ConstructionBlock block, int x, int y)
 {
     for (int j = y; j < y + block.Height; j++)
     {
         for (int i = x; i < x + block.Width; i++)
         {
             if (this.IsValid(i, j) == false || this.IsUsed [i, j] == true)
             {
                 return(false);
             }
         }
     }
     return(true);
 }
示例#5
0
        /// <summary>
        /// Places a random block inside the level, using the still open exits. If <c>false</c> is returned
        /// it means that no blocks can be added animaore (within a tolerance level).
        /// </summary>
        /// <returns><c>true</c>, if random block was added, <c>false</c> otherwise.</returns>
        /// <param name="blocks">Blocks.</param>
        public bool AddRandomBlock(ProbabilityVector <ConstructionBlock> blocks)
        {
            var exit = exits.Random();
            var iter = 0;
            var x    = 0;
            var y    = 0;

            if (exit != null)
            {
                // search for a valid exit
                while (this.IsOpenExit(exit.X, exit.Y, exit.Direction) == false && iter++ < MAX_ITERATIONS)
                {
                    if (exit.CanBeClosed)
                    {
                        // the exit was closed, we can just close it and remove it
                        //this.Data [exit.X, exit.Y] = this.CloseTile;
                        //this.exits.Remove (exit);
                    }
                    exit = exits.Random();
                }
                // got one, now search for a block with a valid connection
                ConstructionBlock next   = null;
                BlockExit         access = null;
                do
                {
                    next   = blocks.Random();
                    access = next.GetAccess(exit.Direction);
                    if (access != null)
                    {
                        x  = exit.X - access.X;
                        y  = exit.Y - access.Y;
                        x += (access.Direction == "W") ? 1 : (access.Direction == "E") ? -1 : 0;
                        y += (access.Direction == "N") ? 1 : (access.Direction == "S") ? -1 : 0;
                        if (this.CanPlaceBlock(next, x, y) == false)
                        {
                            access = null;
                        }
                    }
                } while (access == null && iter++ < MAX_ITERATIONS);
                // found a good block? place it
                if (iter < MAX_ITERATIONS)
                {
                    // BEFORE placing the block remove the used exit
                    this.exits.Remove(exit);
                    this.PlaceBlock(next, x, y);
                    return(true);
                }
            }
            return(false);
        }
示例#6
0
        public bool AddBlock(ConstructionBlock next)
        {
            // search for a valid exit
            BlockExit access;
            BlockExit exit;
            var       iter = 0;
            var       x    = 0;
            var       y    = 0;

            do
            {
                exit = exits.Random();
                while (this.IsOpenExit(exit.X, exit.Y, exit.Direction) == false && iter++ < MAX_ITERATIONS)
                {
                    if (exit.CanBeClosed)
                    {
                        // the exit was closed, we can just close it and remove it
                        //this.Data [exit.X, exit.Y] = this.CloseTile;
                        //this.exits.Remove (exit);
                    }
                    exit = exits.Random();
                }
                access = next.GetAccess(exit.Direction);
                if (access != null)
                {
                    x  = exit.X - access.X;
                    y  = exit.Y - access.Y;
                    x += (access.Direction == "W") ? 1 : (access.Direction == "E") ? -1 : 0;
                    y += (access.Direction == "N") ? 1 : (access.Direction == "S") ? -1 : 0;
                    if (this.CanPlaceBlock(next, x, y) == false)
                    {
                        access = null;
                    }
                }
            } while (access == null && iter++ < MAX_ITERATIONS);
            if (iter < MAX_ITERATIONS)
            {
                // BEFORE placing the block remove the used exit
                this.exits.Remove(exit);
                this.PlaceBlock(next, x, y);
                return(true);
            }
            return(false);
        }
示例#7
0
        public ConstructionBlock RotateCW()
        {
            var newWidth  = block.GetLength(1);
            var newHeight = block.GetLength(0);

            char[,] newMatrix = new char[newWidth, newHeight];
            for (var oy = 0; oy < newWidth; oy++)
            {
                for (var ox = 0; ox < newHeight; ox++)
                {
                    var nx = newWidth - oy - 1;
                    var ny = ox;
                    newMatrix [nx, ny] = block [ox, oy];
                }
            }
            ////////
            string bblock = "";

            for (int y = 0; y < newHeight; y++)
            {
                for (int x = 0; x < newWidth; x++)
                {
                    bblock += newMatrix [x, y];
                }
            }
            var res = new ConstructionBlock(bblock, newWidth, newHeight, this.ID);

            foreach (var exit in this.exits)
            {
                var nx = newWidth - exit.Y - 1;
                var ny = exit.X;
                res.AddExit(nx, ny, exit.RotateDirectionCW(), exit.CanBeClosed);
            }
            foreach (var obj in this.objects)
            {
                if (Array.IndexOf(obj.Variations, "CW") > -1)
                {
                    var nx = newWidth - obj.Y - 1;
                    var ny = obj.X;
                    res.AddObject(obj.ID, nx, ny, obj.Probability, new string[] { });
                }
            }
            return(res);
        }
示例#8
0
        public void BuildBlock(XmlNode xblock)
        {
            var data  = Regex.Replace(xblock.InnerText, @"\s+", "");
            var id    = XmlUtilities.GetString(xblock, "id");
            var block = new ConstructionBlock(
                data,
                XmlUtilities.GetInt(xblock, "width"),
                XmlUtilities.GetInt(xblock, "height"),
                XmlUtilities.GetString(xblock, "id")
                );
            var children = xblock.ChildNodes;

            for (int i = 0; i < children.Count; i++)
            {
                switch (children [i].Name)
                {
                case "end":
                    block.EndPoint = new BlockObject {
                        ID          = "end",
                        X           = XmlUtilities.GetInt(children [i], "x"),
                        Y           = XmlUtilities.GetInt(children [i], "y"),
                        Probability = 1f
                    };
                    break;

                case "exit":
                    block.AddExit(
                        XmlUtilities.GetInt(children [i], "x"),
                        XmlUtilities.GetInt(children [i], "y"),
                        XmlUtilities.GetString(children [i], "direction"),
                        XmlUtilities.GetBool(children [i], "canBeClosed", false)
                        );
                    break;

                case "object":
                    block.AddObject(
                        XmlUtilities.GetString(children [i], "ref"),
                        XmlUtilities.GetInt(children [i], "x"),
                        XmlUtilities.GetInt(children [i], "y"),
                        XmlUtilities.GetFloat(children [i], "probability"),
                        XmlUtilities.GetStringArray(children [i], "variations")
                        );
                    break;

                case "start":
                    block.StartPoint = new BlockObject {
                        ID          = "start",
                        X           = XmlUtilities.GetInt(children [i], "x"),
                        Y           = XmlUtilities.GetInt(children [i], "y"),
                        Probability = 1f
                    };
                    break;

                default:
                    break;
                }
            }
            var pb = XmlUtilities.GetInt(xblock, "occurs");

            this.blocks.Add(block, pb);
            this.blocksById.Add(block.ID, block);
            Logger.Debug("WorldFactory", "BuildBlock", "Built block:\n" + block.ToString());
            var variations = XmlUtilities.GetStringArray(xblock, "variations");

            if (Array.IndexOf(variations, "CCW") >= 0)
            {
                var ccwblock = block.RotateCCW();
                this.blocks.Add(ccwblock, pb);
                Logger.Debug("WorldFactory", "BuildBlock", "Built block CCW:\n" + ccwblock.ToString());
            }
            if (Array.IndexOf(variations, "CW") >= 0)
            {
                var cwblock = block.RotateCW();
                this.blocks.Add(cwblock, pb);
                Logger.Debug("WorldFactory", "BuildBlock", "Built block CW:\n" + cwblock.ToString());
            }
            if (Array.IndexOf(variations, "F") >= 0)
            {
                var fblock = block.Flip();
                this.blocks.Add(fblock, pb);
                Logger.Debug("WorldFactory", "BuildBlock", "Built block F:\n" + fblock.ToString());
            }
            if (Array.IndexOf(variations, "FM") >= 0)
            {
                var fmblock = block.FlipMirror();
                this.blocks.Add(fmblock, pb);
                Logger.Debug("WorldFactory", "BuildBlock", "Built block FM:\n" + fmblock.ToString());
            }
            if (Array.IndexOf(variations, "M") >= 0)
            {
                var mblock = block.Mirror();
                this.blocks.Add(mblock, pb);
                Logger.Debug("WorldFactory", "BuildBlock", "Built block M:\n" + mblock.ToString());
            }
        }