public static void CreateJson() { // Init randomizer Random rand = new Random(0); // Generate a simple instance Instance instance = new Instance() { Name = "testinstance" }; instance.Containers = new List <Container> { new Container() { ID = 0, Mesh = new MeshCube() { Length = 600, Width = 400, Height = 300 } } }; instance.Pieces = new List <VariablePiece>(); for (int i = 0; i < 10; i++) { var piece = new VariablePiece() { ID = i }; piece.AddComponent(0, 0, 0, rand.Next(50, 400), rand.Next(50, 400), rand.Next(50, 400)); piece.SetFlags(new (int, int)[] { (0, rand.Next(0, 2)) });
/// <summary> /// Converts a simplified representation of an instance (used for JSON serialization) to a proper instance. /// </summary> /// <param name="jsonInstance">The instance in simplified presentation.</param> /// <returns>The converted instance.</returns> public static Instance FromJsonInstance(JsonInstance jsonInstance) { // Create instance with given parameters Instance instance = new Instance { Name = jsonInstance.Name }; instance.Containers.AddRange(jsonInstance.Containers.Select(c => new Container() { ID = c.ID, Mesh = new MeshCube() { Length = c.Length, Width = c.Width, Height = c.Height } })); instance.Pieces.AddRange(jsonInstance.Pieces.Select(p => { var convp = new VariablePiece() { ID = p.ID, }; if (p.Flags != null) { convp.SetFlags(p.Flags.Select(f => (f.FlagId, f.FlagValue))); } foreach (var comp in p.Cubes) { convp.AddComponent(comp.X, comp.Y, comp.Z, comp.Length, comp.Width, comp.Height); } return(convp); })); if (jsonInstance.Rules != null && jsonInstance.Rules.FlagRules != null) { instance.Rules = new RuleSet() { FlagRules = jsonInstance.Rules.FlagRules.Select(r => new FlagRule() { FlagId = r.FlagId, RuleType = r.RuleType, Parameter = r.Parameter, }).ToList(), } } ; // Seal it foreach (var container in instance.Containers) { container.Seal(); } foreach (var piece in instance.Pieces) { piece.Seal(); } // Return new instance return(instance); }
/// <summary> /// Generates a tetris "Block" /// </summary> /// <param name="random">The randomizer to use</param> /// <param name="pieceID">The ID of the piece</param> /// <param name="minSize">The minimal size</param> /// <param name="maxSize">The maximal size</param> /// <param name="roundedDecimals">The number of decimal places</param> /// <returns>The generated piece</returns> public static VariablePiece GenerateTetrisBlock(Random random, ref int pieceID, double minSize, double maxSize, int roundedDecimals) { VariablePiece piece = new VariablePiece(); piece.ID = ++pieceID; piece.AddComponent(0, 0, 0, Math.Round(minSize + random.NextDouble() * (maxSize - minSize), roundedDecimals), Math.Round(minSize + random.NextDouble() * (maxSize - minSize), roundedDecimals), Math.Round(minSize + random.NextDouble() * (maxSize - minSize), roundedDecimals)); piece.Seal(); return(piece); }
/// <summary> /// Generates a tetris "L" /// </summary> /// <param name="random">The randomizer to use</param> /// <param name="pieceID">The ID of the piece</param> /// <param name="minSize">The minimal size</param> /// <param name="maxSize">The maximal size</param> /// <param name="roundedDecimals">The number of decimal places</param> /// <returns>The generated piece</returns> public static VariablePiece GenerateTetrisL(Random random, ref int pieceID, double minSize, double maxSize, int roundedDecimals, double lengthBreak) { double length = Math.Round(minSize + random.NextDouble() * (maxSize - minSize), roundedDecimals); double width = Math.Round(minSize + random.NextDouble() * (maxSize - minSize), roundedDecimals); double height = Math.Round(minSize + random.NextDouble() * (maxSize - minSize), roundedDecimals); double breakLength = length * lengthBreak; double breakHeight = height * lengthBreak; VariablePiece piece = new VariablePiece(); piece.ID = ++pieceID; piece.AddComponent(0, 0, 0, breakLength, width, height); piece.AddComponent(breakLength, 0, 0, length - breakLength, width, breakHeight); piece.Seal(); return(piece); }
/// <summary> /// Generates a set of performance-test tetris-pieces /// </summary> /// <param name="count">The number of pieces to generate</param> /// <param name="minSize">The minimal size of the pieces</param> /// <param name="maxSize">The maximal size of the pieces</param> /// <param name="minEquals">The number of minimal equals</param> /// <param name="maxEquals">The number of maximal equals</param> /// <param name="seed">The seed used for generation</param> /// <param name="roundedDecimals">The number of decimal places</param> /// <returns>The generated pieces</returns> public static List <VariablePiece> GeneratePerformanceTestTetrisPieces(int count, double minSize, double maxSize, int minEquals, int maxEquals, int seed = 0, int roundedDecimals = 0) { // Init Random random = new Random(seed); List <VariablePiece> pieces = new List <VariablePiece>(); int pieceID = 0; // Generate a set of tetris pieces for (int i = 0; i < count; i++) { // Generate the next shape to add int nextTetrisShape = random.Next(1000); VariablePiece nextTetrisItem = null; if (nextTetrisShape <= 30) { nextTetrisItem = GenerateTetrisU(random, ref pieceID, minSize, maxSize, roundedDecimals, 0.5); } else { if (nextTetrisShape >= 950) { nextTetrisItem = GenerateTetrisT(random, ref pieceID, minSize, maxSize, roundedDecimals, 0.5); } else { if (nextTetrisShape <= 300) { nextTetrisItem = GenerateTetrisL(random, ref pieceID, minSize, maxSize, roundedDecimals, 0.5); } else { nextTetrisItem = GenerateTetrisBlock(random, ref pieceID, minSize, maxSize, roundedDecimals); } } } // Possibly make it non rotatable if (random.NextDouble() > 0.9) { nextTetrisItem.ForbiddenOrientations = new HashSet <int>(MeshConstants.ORIENTATIONS_THIS_SIDE_UP); } // Possibly give a non-standard material double materialChance = random.NextDouble(); if (materialChance > 0.8) { if (materialChance > 0.9) { nextTetrisItem.Material = new Material() { MaterialClass = MaterialClassification.Explosive }; } else { nextTetrisItem.Material = new Material() { MaterialClass = MaterialClassification.FlammableGas }; } } // Possibly make piece not stackable double stackableChance = random.NextDouble(); if (stackableChance > 0.95) { nextTetrisItem.Stackable = false; } // Add it pieces.Add(nextTetrisItem); // Clone the new item to get sufficient equal items int equalCount = minEquals + random.Next(maxEquals - minEquals) - 1; for (int j = 0; j < equalCount && i < count; j++, i++) { VariablePiece clone = nextTetrisItem.Clone(); clone.ID = ++pieceID; pieces.Add(clone); } } // Return return(pieces); }
/// <summary> /// Generates a set of pieces /// </summary> /// <param name="count">The number of pieces to generate</param> /// <param name="minSize">The minimal size of the pieces</param> /// <param name="maxSize">The maximal size of the pieces</param> /// <param name="minEquals">The number of minimal equals</param> /// <param name="maxEquals">The number of maximal equals</param> /// <param name="seed">The seed used for generation</param> /// <param name="roundedDecimals">The number of decimal places</param> /// <returns>The generated pieces</returns> public static List <VariablePiece> GeneratePieces(int count, double minSize, double maxSize, int minEquals, int maxEquals, int seed = 0, int roundedDecimals = 0) { // Init Random random = new Random(seed); List <VariablePiece> pieces = new List <VariablePiece>(); // Generate as many pieces as desired for (int i = 0; i < count;) { // Init piece VariablePiece piece = new VariablePiece() { ID = i, }; // Add the parallelepiped component piece.AddComponent(0, 0, 0, Math.Round(minSize + random.NextDouble() * (maxSize - minSize), roundedDecimals), Math.Round(minSize + random.NextDouble() * (maxSize - minSize), roundedDecimals), Math.Round(minSize + random.NextDouble() * (maxSize - minSize), roundedDecimals)); // Seal it piece.Seal(); // Possibly make it non rotatable double forbiddenOrientationsChance = random.NextDouble(); if (forbiddenOrientationsChance > 0.9) { piece.ForbiddenOrientations = new HashSet <int>(MeshConstants.ORIENTATIONS.Except(MeshConstants.ORIENTATIONS_THIS_SIDE_UP)); } // Possibly give a non-standard material double materialChance = random.NextDouble(); if (materialChance > 0.8) { if (materialChance > 0.9) { piece.Material = new Material() { MaterialClass = MaterialClassification.Explosive }; } else { piece.Material = new Material() { MaterialClass = MaterialClassification.FlammableGas }; } } // Possibly make piece not stackable double stackableChance = random.NextDouble(); if (stackableChance > 0.9) { piece.Stackable = false; } // Clone the piece to generate sufficient 'equals' int equalCount = random.Next(minEquals, maxEquals + 1); for (int j = 0; i < count && j < equalCount; j++, i++) { VariablePiece clonePiece = piece.Clone(); clonePiece.ID = i + 1; pieces.Add(clonePiece); } } // Return return(pieces); }
/// <summary> /// Generates a set of tetris-pieces /// </summary> /// <param name="count">The number of pieces to generate</param> /// <param name="minSize">The minimal size of the pieces</param> /// <param name="maxSize">The maximal size of the pieces</param> /// <param name="minEquals">The number of minimal equals</param> /// <param name="maxEquals">The number of maximal equals</param> /// <param name="seed">The seed used for generation</param> /// <param name="roundedDecimals">The number of decimal places</param> /// <param name="lengthBreak">The length break influencing the clipping of pieces</param> /// <returns>The generated pieces</returns> public static List <VariablePiece> GenerateTetrisPieces(int count, double minSize, double maxSize, int minEquals, int maxEquals, int weightBox = 1, int weightL = 1, int weightT = 1, int weightU = 1, int seed = 0, int roundedDecimals = 0, double lengthBreakL = 0.5, double lengthBreakT = 0.5, double lengthBreakU = 0.5) { // Init Random random = new Random(seed); List <VariablePiece> pieces = new List <VariablePiece>(); int pieceID = 0; Func <ShapeType, int> shapeWeigher = (ShapeType type) => { switch (type) { case ShapeType.L: return(weightL); case ShapeType.T: return(weightT); case ShapeType.U: return(weightU); case ShapeType.Box: return(weightBox); default: throw new ArgumentException("No such shape available: " + type.ToString()); } }; // Generate a set of tetris pieces for (int i = 0; i < count; i++) { // Generate the next shape to add ShapeType nextTetrisShape = GetRandomShapeType(random, shapeWeigher); VariablePiece nextTetrisItem = null; switch (nextTetrisShape) { case ShapeType.L: { // Generate an L nextTetrisItem = GenerateTetrisL(random, ref pieceID, minSize, maxSize, roundedDecimals, lengthBreakL); } break; case ShapeType.Box: { // Generate a simple block nextTetrisItem = GenerateTetrisBlock(random, ref pieceID, minSize, maxSize, roundedDecimals); } break; case ShapeType.T: { // Generate a T nextTetrisItem = GenerateTetrisT(random, ref pieceID, minSize, maxSize, roundedDecimals, lengthBreakT); } break; case ShapeType.U: { // Generate a U nextTetrisItem = GenerateTetrisU(random, ref pieceID, minSize, maxSize, roundedDecimals, lengthBreakU); } break; default: break; } // Possibly make it non rotatable if (random.NextDouble() > 0.9) { nextTetrisItem.ForbiddenOrientations = new HashSet <int>(MeshConstants.ORIENTATIONS_THIS_SIDE_UP); } // Possibly give a non-standard material double materialChance = random.NextDouble(); if (materialChance > 0.8) { if (materialChance > 0.9) { nextTetrisItem.Material = new Material() { MaterialClass = MaterialClassification.Explosive }; } else { nextTetrisItem.Material = new Material() { MaterialClass = MaterialClassification.FlammableGas }; } } // Possibly make piece not stackable double stackableChance = random.NextDouble(); if (stackableChance > 0.95) { nextTetrisItem.Stackable = false; } // Add it pieces.Add(nextTetrisItem); // Clone the new item to get sufficient equal items int equalCount = minEquals + random.Next(maxEquals - minEquals) - 1; for (int j = 0; j < equalCount && i < count; j++, i++) { VariablePiece clone = nextTetrisItem.Clone(); clone.ID = ++pieceID; pieces.Add(clone); } } // Return return(pieces); }
/// <summary> /// Reads an instance file from the given path. /// </summary> /// <param name="path">The path to the instance file</param> /// <returns>The read instance</returns> public static Instance ReadXML(string path) { // Prepare XML data XmlDocument document = new XmlDocument(); document.Load(path); Instance instance = new Instance(); // Name if (document.SelectSingleNode("//Instance").Attributes["Name"] != null) { instance.Name = document.SelectSingleNode("//Instance").Attributes["Name"].Value; } else { instance.Name = "Default"; } // Read containers XmlNode containersRoot = document.SelectSingleNode("//Instance/Containers"); List <Container> containers = new List <Container>(); if (containersRoot != null) { foreach (var childNode in containersRoot.ChildNodes.OfType <XmlNode>()) { Container container = new Container(); container.LoadXML(childNode); containers.Add(container); } } // Read pieces XmlNode piecesRoot = document.SelectSingleNode("//Instance/Pieces"); List <VariablePiece> pieces = new List <VariablePiece>(); if (piecesRoot != null) { foreach (var childNode in piecesRoot.ChildNodes.OfType <XmlNode>()) { VariablePiece piece = new VariablePiece(); piece.LoadXML(childNode); pieces.Add(piece); } } // Add all items instance.Containers.AddRange(containers); instance.Pieces.AddRange(pieces); // Read solutions XmlNode solutionsRoot = document.SelectSingleNode("//Instance/Solutions"); List <COSolution> solutions = new List <COSolution>(); if (solutionsRoot != null) { foreach (var childNode in solutionsRoot.ChildNodes.OfType <XmlNode>()) { COSolution solution = instance.CreateSolution(false, MeritFunctionType.None); solution.LoadXML(childNode); solutions.Add(solution); } } // Return return(instance); }