public AFallingBlockPuzzle(
        int width,
        int height,
        int[] blockSizes,
        bool cornerAllowed,
        bool loopX)
    {
        _blockSizes = new int[blockSizes.Length];
        int maxBlockSize = 0;

        for (int i = 0; i < blockSizes.Length; i++)
        {
            _blockSizes[i] = blockSizes[i];
            if (maxBlockSize < blockSizes[i])
            {
                maxBlockSize = blockSizes[i];
            }
        }
        this.erasedYList = new List <int>();
        _width           = width;
        _height          = height;
        _extendedHeight  = height + ((maxBlockSize + 1) / 2);        // include bottom and upper dummy lines
        _startY          = height - 1;
        _startX          = _width / 2;
        _loopX           = loopX;
        _cells           = new int[_width * _extendedHeight];
        _tmpShape        = new Shape(maxBlockSize);
        _shapes          = new List <Shape>();
        _random          = new System.Random();
        var generator = new ShapeGenerator(maxBlockSize);

        generator.Generate(_shapes, _blockSizes, cornerAllowed);
        Reset();
    }