public void CreateGenes(IInitialGeneSequence initialGeneSequence)
 {
     this.CreateGeneSequence(initialGeneSequence, true);
 }
        private void CreateGeneSequence(IInitialGeneSequence initialGeneSequence, bool mutate)
        {
            int xSize = WIDTH;
            int ySize = HEIGHT;

            // Set up inital MAX gene heights - centered initially using ySize
            // provided. And MIN is fixed as a constant value for this excercise.
            int maxGeneH = ySize / 2;
            int minGeneH = 20;

            // Set up inital MAX gene widths - centered initially using xSize
            // provided. And MIN is fixed as a constant value for this excercise.
            int maxGeneW = xSize / 3;
            int minGeneW = 20;

            // Set up inital MIN / MAX gene width for eyes using the size
            // of the overall face as limit.
            int maxGeneEyeW = GenotypeWidths[Genes.FACE_GENE] / 20;
            int minGeneEyeW = 15;

            // Set up inital MIN / MAX gene height for nose using the size
            // of the overall face as limit.
            int maxGeneNoseH = GenotypeHeights[Genes.FACE_GENE] / 15;
            int minGeneNoseH = 5;

            // Set up inital MIN / MAX gene width for nose using the size
            // of the overall face as limit.
            int maxGeneNoseW = GenotypeWidths[Genes.FACE_GENE] / 4;
            int minGeneNoseW = GenotypeWidths[Genes.FACE_GENE] / 3;

            // If we are being asked to mutate OR there is a random mutation
            // play god with the genes by changing some of the values within the
            // gene structures.

            // GENE[0] = face rectangle
            if (mutate || (RAND.NextDouble() < GenotypeMutationRate))
            {
                this.GenotypeColours[Genes.FACE_GENE] = AvailableColours[(int)(RAND.NextDouble() * AvailableColours.Length)];
                GenotypeWidths[Genes.FACE_GENE]       = (int)((initialGeneSequence.FaceGene * (maxGeneW - minGeneW)) + minGeneW);
                GenotypeHeights[Genes.FACE_GENE]      = (int)((initialGeneSequence.FaceGene * (maxGeneH - minGeneH)) + minGeneH);
            }

            // GENE[1] = left eye circle
            if (mutate || (RAND.NextDouble() < GenotypeMutationRate))
            {
                this.GenotypeColours[Genes.LEFT_EYE_GENE] = AvailableEyeColours[(int)(initialGeneSequence.LeftEyeGene * AvailableEyeColours.Length)];
                GenotypeWidths[Genes.LEFT_EYE_GENE]       = (int)((initialGeneSequence.LeftEyeGene * (maxGeneEyeW - minGeneEyeW)) + minGeneEyeW);
                // make eye semetrical - round
                GenotypeHeights[Genes.LEFT_EYE_GENE] = GenotypeWidths[Genes.LEFT_EYE_GENE];
            }

            // GENE[2] = right eye circle
            if (mutate || (RAND.NextDouble() < GenotypeMutationRate))
            {
                // make sure that the eyes are both the same color
                this.GenotypeColours[Genes.RIGHT_EYE_GENE] = this.GenotypeColours[Genes.LEFT_EYE_GENE];
                GenotypeWidths[Genes.RIGHT_EYE_GENE]       = (int)((initialGeneSequence.RightEyeGene * (maxGeneEyeW - minGeneEyeW)) + minGeneEyeW);
                // make eye semetrical - round
                GenotypeHeights[Genes.RIGHT_EYE_GENE] = GenotypeWidths[Genes.RIGHT_EYE_GENE];
            }


            // GENE[3] = nose rectangle
            if (mutate || (RAND.NextDouble() < GenotypeMutationRate))
            {
                GenotypeWidths[Genes.NOSE_GENE]  = (int)((initialGeneSequence.NoseGene * (maxGeneNoseW - minGeneNoseW)) + minGeneNoseW);
                GenotypeHeights[Genes.NOSE_GENE] = (int)((initialGeneSequence.NoseGene * (maxGeneNoseH - minGeneNoseH)) + minGeneNoseH);
            }


            // GENE[4] = left top bone rectangle
            if (mutate || (RAND.NextDouble() < GenotypeMutationRate))
            {
                this.GenotypeColours[Genes.LEFTBONE_TOP_GENE] = AvailableColours[(int)(initialGeneSequence.LeftBoneTopGene * AvailableColours.Length)];
                // Ensure that right bone can only grow to 1/8 height of the face rectangle
                maxGeneH = GenotypeHeights[Genes.FACE_GENE] / 20;
                GenotypeWidths[Genes.LEFTBONE_TOP_GENE]  = (int)((initialGeneSequence.LeftBoneTopGene * (maxGeneW - minGeneW)) + minGeneW);
                GenotypeHeights[Genes.LEFTBONE_TOP_GENE] = (int)((initialGeneSequence.LeftBoneTopGene * (maxGeneH - minGeneH)) + minGeneH);
            }

            // GENE[5] = right top bone rectangle
            // Color is the same as top left bone gene. As it is really the same bone.
            // But make the right top bone rectangle the same width/height as the left top bone rectangle.
            // I made them different to begin with, but preffered the look of my organism, with uniform
            // bone width, heights. I am not going for the Elephant man Skull type here. Maybe next time.
            this.GenotypeColours[Genes.RIGHTBONE_TOP_GENE] = this.GenotypeColours[Genes.LEFTBONE_TOP_GENE];
            GenotypeWidths[Genes.RIGHTBONE_TOP_GENE]       = GenotypeWidths[Genes.LEFTBONE_TOP_GENE];
            GenotypeHeights[Genes.RIGHTBONE_TOP_GENE]      = GenotypeHeights[Genes.LEFTBONE_TOP_GENE];

            // GENE[6] = teeth rectangle
            if (mutate || (RAND.NextDouble() < GenotypeMutationRate))
            {
                this.GenotypeColours[Genes.TEETH_GENE] = AvailableColours[(int)(initialGeneSequence.TeethGene * AvailableColours.Length)];
                // Ensure that teeth can only grow to 1/2 width of the face rectangle
                maxGeneW = GenotypeWidths[Genes.FACE_GENE] / 2;
                // Ensure that teeth can only grow to 1/2 height of the total ySize parameter
                maxGeneH = ySize / 2;
                GenotypeWidths[Genes.TEETH_GENE]  = (int)((initialGeneSequence.TeethGene * (maxGeneW - minGeneW)) + minGeneW);
                GenotypeHeights[Genes.TEETH_GENE] = (int)((initialGeneSequence.TeethGene * (maxGeneH - minGeneH)) + minGeneH);
            }

            // GENE[7] = left bottom bone rectangle
            // Color is allowed to be random.
            // But make the left bottom bone rectangle the same width/height as the left top bone rectangle
            // could have made them different, but that would involve switching different values when
            // drawing the shape to get the centering on the screen correct. This will do.
            this.GenotypeColours[Genes.LEFTBONE_BOTTOM_GENE] = AvailableColours[(int)(initialGeneSequence.LeftBoneBottomGene * AvailableColours.Length)];
            GenotypeWidths[Genes.LEFTBONE_BOTTOM_GENE]       = GenotypeWidths[Genes.LEFTBONE_TOP_GENE];
            GenotypeHeights[Genes.LEFTBONE_BOTTOM_GENE]      = GenotypeHeights[Genes.LEFTBONE_TOP_GENE];

            // GENE[8] = right bottom bone rectangle
            // Color is the same as bottom left bone gene. As it is really the same bone.
            // But make the right bottom bone rectangle the same width/height as the right top bone rectangle
            // could have made them different, but that would involve switching different values when
            // drawing the shape to get the centering on the screen correct. This will do.
            this.GenotypeColours[Genes.RIGHTBONE_BOTTOM_GENE] = this.GenotypeColours[Genes.LEFTBONE_BOTTOM_GENE];
            GenotypeWidths[Genes.RIGHTBONE_BOTTOM_GENE]       = GenotypeWidths[Genes.LEFTBONE_BOTTOM_GENE];
            GenotypeHeights[Genes.RIGHTBONE_BOTTOM_GENE]      = GenotypeHeights[Genes.LEFTBONE_BOTTOM_GENE];
        }