void Create()
        {
            Block testBlock = new Block(testSpec.Stage, testSpec.NumRows);

            testBlock.CreateRandomBlock();

            // Set place to be the test place
            int testPlace;

            testPlace = testSpec.Stage + (testSpec.Stage % 2);

            if (testSpec.TestBellLoc != 1)
            {
                Random rand = new Random();
                testPlace = rand.Next(1, testPlace + 1);
            }

            blowSet = new BlowSet(testSpec.Stage, testSpec.NumRows, testSpec.TenorWeight, testSpec.ErrorType, true);

            // No need for an audio suffix in a Gap test (this is used to distinguish A and B in an A/B test)
            blowSet.PopulateBlows(testBlock, testPlace, string.Empty);
            blowSet.CreateRandomSpacing(testSpec.ErrorSize, Constants.Rounding);
            blowSet.SetUnstruck();

            // Set up test spec-dependent elements of the screen object
            // When practicing in a Gap Test, gaps are rounded to the nearest 10ms so that bells will align
            // if zero gap error is selected
            int baseGap = BaseGaps.BaseGap(testSpec.Stage, testSpec.TenorWeight, 10);

            testSpec.BaseGap = baseGap;
            testSpec.GapMin  = 20;

            // If test bell is 1st's place of a handstroke row, need to adjust GapMax to have a higher value
            // because of the handstroke gap
            if (testSpec.NumRows % 2 == 1 && testPlace == 1)
            {
                testSpec.GapMax = Convert.ToInt32(Math.Round(((double)testSpec.BaseGap * 3) / 50)) * 50;
            }
            else
            {
                testSpec.GapMax = Convert.ToInt32(Math.Round(((double)baseGap * 2) / 50)) * 50;
            }
        }
        void Create()
        {
            // Choose whether A or B will have the errors
            Random rand = new Random();

            testSpec.AHasErrors = rand.Next(0, 2) == 0;

            // Create the test block
            Block testBlock = new Block(testSpec.Stage, testSpec.NumRows);

            testBlock.CreateRandomBlock();

            blowSetA = new BlowSet(testSpec.Stage, testSpec.NumRows, testSpec.TenorWeight,
                                   testSpec.ErrorType, testSpec.AHasErrors);
            blowSetA.PopulateBlows(testBlock, testSpec.TestBellLoc, "a");

            // No rounding in an A/B test
            blowSetA.CreateEvenSpacing(1);
            blowSetA.SetUnstruck();

            blowSetB = new BlowSet(testSpec.Stage, testSpec.NumRows, testSpec.TenorWeight,
                                   testSpec.ErrorType, !testSpec.AHasErrors);
            blowSetB.PopulateBlows(testBlock, testSpec.TestBellLoc, "b");

            // No rounding in an A/B test
            blowSetB.CreateEvenSpacing(1);
            blowSetB.SetUnstruck();

            if (testSpec.AHasErrors == true)
            {
                if (testSpec.ErrorType == 1)
                {
                    blowSetA.CreateStrikingError(testSpec.ErrorSize);
                }
                else
                {
                    blowSetA.CreateCompassError(testSpec.ErrorSize);
                }
            }
            else
            {
                if (testSpec.ErrorType == 1)
                {
                    blowSetB.CreateStrikingError(testSpec.ErrorSize);
                }
                else
                {
                    blowSetB.CreateCompassError(testSpec.ErrorSize);
                }
            }

            // Set up test spec-dependent elements of the screen object
            int baseGap = BaseGaps.BaseGap(testSpec.Stage, testSpec.TenorWeight, 1);

            testSpec.BaseGap = baseGap;

            // Set the timing for the animation (when not showing the bells)
            screenA.AnimationDuration = blowSetA.Blows.Last().GapCumulative + 1000;
            screenB.AnimationDuration = blowSetB.Blows.Last().GapCumulative + 1000;
            testSpec.ResultEntered    = false;

            testSpec.ShowGaps = false;
        }