Exemplo n.º 1
0
        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)) });
Exemplo n.º 2
0
        /// <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);
        }
Exemplo n.º 8
0
        /// <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);
        }