public SettedBlock[,] GenerateMixed(out int MaxHeight)
        {
            SettedBlock[,] BlockMap = new SettedBlock[rawScheme.GetLength(0), rawScheme.GetLength(1) + 1];
            MaxHeight = 0;
            int curMaxHeight = 0;

            for (int i = 0; i < rawScheme.GetLength(0); ++i)
            {
                SettedBlock[] layer    = GenerateSegmentedLayer(i, out curMaxHeight);
                bool          isHigher = false;
                int           curStart = 0;
                for (int j = 0; j < layer.Length; ++j)
                {
                    if (!isHigher)
                    {
                        if (layer[j].Height >= GlobalMaximumHeight)
                        {
                            isHigher     = true;
                            curStart     = j;
                            curMaxHeight = GlobalMaximumHeight - 1;
                        }
                    }
                    else
                    {
                        if (layer[j].Height < GlobalMaximumHeight)
                        {
                            isHigher = false;
                            for (int k = curStart; k < j; ++k)
                            {
                                layer[k].Height %= GlobalMaximumHeight;
                            }
                        }
                    }
                }
                if (isHigher)
                {
                    for (int k = curStart; k < layer.Length; ++k)
                    {
                        layer[k].Height %= GlobalMaximumHeight;
                    }
                }
                if (curMaxHeight > MaxHeight)
                {
                    MaxHeight = curMaxHeight;
                }
                for (int j = 0; j < layer.Length; ++j)
                {
                    BlockMap[i, j] = layer[j];
                }
            }
            return(BlockMap);
        }
        SettedBlock[] GenerateFlowLayer(int layerNum, out int MaxHeight)
        {
            SettedBlock[] layer = new SettedBlock[rawScheme.GetLength(1) + 1];
            MaxHeight = 0;

            layer[0] = new SettedBlock()
            {
                ID = -1, Height = 0
            };
            int minHeight = 0;

            for (int i = 1; i < rawScheme.GetLength(1) + 1; ++i)
            {
                layer[i].ID = rawScheme[layerNum, i - 1].ID;
                switch (rawScheme[layerNum, i - 1].Set)
                {
                case ColorType.Normal:
                    layer[i].Height = layer[i - 1].Height;
                    break;

                case ColorType.Dark:
                    layer[i].Height = layer[i - 1].Height - 1;
                    break;

                case ColorType.Light:
                    layer[i].Height = layer[i - 1].Height + 1;
                    break;
                }
                if (i != 1 && (i - 1) % Properties.Settings.Default.FlowLength == 0)
                {
                    layer[i].Height = 0;
                }
                minHeight = layer[i].Height < minHeight ? layer[i].Height : minHeight;
            }
            for (int i = 0; i < rawScheme.GetLength(1) + 1; ++i)
            {
                layer[i].Height = layer[i].Height - minHeight;
                if (layer[i].Height > MaxHeight)
                {
                    MaxHeight = layer[i].Height;
                }
            }
            return(layer);
        }
        public SettedBlock[,] GenerateSegmented(out int MaxHeight)
        {
            SettedBlock[,] BlockMap = new SettedBlock[rawScheme.GetLength(0), rawScheme.GetLength(1) + 1];
            MaxHeight = 0;
            for (int i = 0; i < rawScheme.GetLength(0); ++i)
            {
                SettedBlock[] layer = GenerateSegmentedLayer(i, out int curMaxHeight);

                if (curMaxHeight > MaxHeight)
                {
                    MaxHeight = curMaxHeight;
                }
                for (int j = 0; j < layer.Length; ++j)
                {
                    BlockMap[i, j] = layer[j];
                }
            }
            return(BlockMap);
        }
        SettedBlock[] GenerateSegmentedLayer(int layerNum, out int MaxHeight)
        {
            SettedBlock[] layer = new SettedBlock[rawScheme.GetLength(1) + 1];
            MaxHeight = 0;

            List <MBlock> mBlocks = new List <MBlock>();
            UnsettedBlock last    = new UnsettedBlock {
                ID = -1, Set = ColorType.Normal
            };
            MBlock curMBlock = new MBlock();

            curMBlock.Add(new UnsettedBlock {
                ID = -1, Set = ColorType.Normal
            });
            bool isUp = rawScheme[layerNum, 0].Set == ColorType.Light;

            for (int i = 0; i < rawScheme.GetLength(1); ++i)
            {
                if (!isUp)
                {
                    if (rawScheme[layerNum, i].Set == ColorType.Dark || rawScheme[layerNum, i].Set == ColorType.Normal)
                    {
                        curMBlock.Add(rawScheme[layerNum, i]);
                    }
                    else
                    {
                        isUp = true;
                        curMBlock.Add(rawScheme[layerNum, i]);
                    }
                }
                else
                {
                    if (rawScheme[layerNum, i].Set == ColorType.Light || rawScheme[layerNum, i].Set == ColorType.Normal)
                    {
                        curMBlock.Add(rawScheme[layerNum, i]);
                    }
                    else
                    {
                        isUp = false;
                        mBlocks.Add(curMBlock.Clone() as MBlock);
                        curMBlock = new MBlock();
                        curMBlock.Add(rawScheme[layerNum, i]);
                    }
                }
            }
            mBlocks.Add(curMBlock.Clone() as MBlock);
            foreach (MBlock mb in mBlocks)
            {
                mb.Calculate();
            }
            int minH = 0;

            for (int j = 1; j < mBlocks.Count; ++j)
            {
                if (mBlocks[j].StartH >= mBlocks[j - 1].EndH)
                {
                    mBlocks[j].Shift = mBlocks[j].StartH - mBlocks[j - 1].EndH + 1;
                    if (minH > mBlocks[j].Shift)
                    {
                        minH = mBlocks[j].Shift;
                    }
                    for (int k = j - 1; k >= 0; --k)
                    {
                        if (mBlocks[k].EndH <= mBlocks[k + 1].StartH)
                        {
                            mBlocks[k].Shift += mBlocks[k + 1].StartH - mBlocks[k].EndH + 1;
                        }
                    }
                }
            }
            int curPos = -1;

            for (int j = 0; j < mBlocks.Count; ++j)
            {
                if (MaxHeight < mBlocks[j].StartH)
                {
                    MaxHeight = mBlocks[j].StartH;
                }
                if (MaxHeight < mBlocks[j].EndH)
                {
                    MaxHeight = mBlocks[j].EndH;
                }
                SettedBlock[] cur = mBlocks[j].Get();
                for (int k = 0; k < cur.Length; ++k)
                {
                    layer[++curPos] = cur[k];
                }
            }
            return(layer);
        }