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); }
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); }
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; }
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); }
/// <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); }
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); }
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); }
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()); } }