/// <summary>
        /// Tree_traverses the specified parent.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="start_point">The start_point.</param>
        /// <returns></returns>
        public int tree_traverse(Indevidual parent, int start_point)
        {
            //holds the trees legth from point given
            int counter = 1;
            int len     = 1;

            for (int i = 0; len != 0; i++)
            {
                //add byte to sub tree1 array
                //subtree[i] = (byte)parent.Program[buffer];
                counter++;
                start_point++;

                if (parent.Program[start_point] < Terminal_set_Start && parent.Program[start_point] > Terminal_set_End)
                {
                    //if the node is a functional node then trase the sub tree
                    if (parent.Program[start_point] >= Functional_set_Start && parent.Program[start_point] <= Functional_set_End)
                    {
                        len++;  //increase the length
                    }
                    else if (parent.Program[start_point] == End)
                    {
                        len--;  //decrease the length
                    }
                }
                //if the node is a terminal node it will be
                //counted on the next loop round
            }
            return(counter);
        }
        /// <summary>
        /// Selection_torniments the specified torniment_size.
        /// </summary>
        /// <param name="torniment_size">The torniment_size.</param>
        /// <returns></returns>
        public Indevidual selection_torniment(int torniment_size)
        {
            Random     rnd  = new Random(Guid.NewGuid().GetHashCode());
            Indevidual best = null;

            //choose and indevidual at randome
            Indevidual first = Generation[rnd.Next(0, population_Size)];

            //uses tornimnt size to search x number of indeviduals
            //increases selection pressure (higher pressure fitter indeviduals)
            //equivalent to copetitive challange
            for (int i = 0; i < torniment_size; i++)
            {
                //choose second randome indevidual to compare with
                Indevidual second = Generation[rnd.Next(0, population_Size)];

                //if the first indevidual is fitter than the second
                //then return the first
                if (first.Fitness > second.Fitness)
                {
                    best = first;
                }
                else
                {
                    //else return the second
                    best = second;
                }
            }

            gw.ListEventsAlgorithm.Add(":: Indevidual: " + best + " chosen through Torniment selection ::");

            //return best Indevidual
            return(best);
        }
        /// <summary>
        /// Setups this instance.
        /// </summary>
        public void setup()
        {
            //add to generation counter
            GenCounter++;

            gw.ListEventsAlgorithm.Add("::Genetic programming SETUP::");
            gw.ListEventsAlgorithm.Add("::Generation: " + GenCounter + " ::");

            //generate a generation of specified size
            for (int i = 0; i != population_Size; i++)
            {
                Indevidual ind = new Indevidual();
                gw.ListEventsAlgorithm.Add(":: New Indevidual created for Generation ::");

                Grow();

                ind.TreeNo     = i + 1;
                ind.Program    = GrownProgram;
                ind.Tree       = GetInterpTree(ind.Program);
                ind.TreeString = Draw_tree(ind.Program);

                gw.ListEventsAlgorithm.Add(":: indevidual " + treeCounter + " added to Generation ::");

                //ind.Fitness = ;
                //will have to guage trees fitness

                treeCounter++;

                //add tree to inital generation
                Generation.Add(ind);
            }
        }
        /// <summary>
        /// Fitness functions gives a tree its fitness rating.
        /// </summary>
        /// <param name="total_Damage">The total_ damage.</param>
        /// <param name="indevidual">The indevidual.</param>
        public void fitness_function(int total_Damage, Indevidual indevidual)
        {
            //here the fitness of an indevidual will be set
            // as the game intends to evaluate the AI's tree based on performace
            // this method will be used to update the fitnesses of the trees
            //in the list rather than evaluate them here directly
            int fitness = (total_Damage / indevidual.Program.Length);

            indevidual.Fitness = fitness;


            gw.ListEventsAlgorithm.Add(" ::Fitness calculated:: ");
            gw.ListEventsAlgorithm.Add(indevidual.ToString());
        }
        /// <summary>
        /// Sub_tree_or_node_selection from the specified parent.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="xoPoint">The xo point.</param>
        /// <param name="rnd">The random.</param>
        /// <param name="subtree">The subtree.</param>
        /// <returns></returns>
        public List <byte> sub_tree_or_node_selection(Indevidual parent, int xoPoint, Random rnd, List <byte> subtree)
        {
            //if the vale at that index is a functional node
            //then go about tracing the sub tree
            if (parent.Program[xoPoint] >= Functional_set_Start && parent.Program[xoPoint] <= Functional_set_End)
            {
                //lengh of the sub tree found
                int len = 1;

                subtree.Add((byte)parent.Program[xoPoint]);
                xoPoint++;

                for (int i = 0; len != 0; i++)
                {
                    //if the node is a functional node then trase the sub tree
                    if (parent.Program[xoPoint] >= Functional_set_Start && parent.Program[xoPoint] <= Functional_set_End)
                    {
                        subtree.Add((byte)parent.Program[xoPoint]);
                        len++;  //increase the length
                    }
                    else if (parent.Program[xoPoint] >= Terminal_set_Start && parent.Program[xoPoint] <= Terminal_set_End)
                    {
                        subtree.Add((byte)parent.Program[xoPoint]);
                    }
                    else if (parent.Program[xoPoint] == End)
                    {
                        subtree.Add((byte)parent.Program[xoPoint]);
                        len--;  //decrease the length
                    }


                    //add byte to sub tree1 array
                    //subtree.Add((byte)parent.Program[xoPoint]);
                    xoPoint++;
                }
            }
            else if (parent.Program[xoPoint] >= Terminal_set_Start && parent.Program[xoPoint] <= Terminal_set_End)
            {
                //if the node is a terminal node (leaf node) just add
                //it to the array
                subtree.Add(parent.Program[xoPoint]);
            }

            //return what has been selected
            return(subtree);
        }
        /// <summary>
        /// Evolves the mating pool of this instance.
        /// </summary>
        public void evolve()
        {
            Indevidual parent1, parent2, childInd;

            gw.ListEventsAlgorithm.Add(":: Evolve ::");

            for (int i = 0; i != population_Size; i++)
            {
                treeCounter++;

                //take from the current generation using torniment
                parent1 = selection_torniment(torniment_size);
                parent2 = selection_torniment(torniment_size);

                //based on the mutation rate
                //crossover
                byte[] child = crossover_subtree(parent1, parent2);
                //mutation
                child = mutation_bit_flip(child);

                //create new indevidual for the mating pool
                childInd        = new Indevidual();
                childInd.TreeNo = treeCounter;
                //childInd.Fitness
                childInd.Program    = child;
                childInd.Tree       = GetInterpTree(childInd.Program);
                childInd.TreeString = Draw_tree(childInd.Program);
                //add to the maiting pool
                mating_pool.Add(childInd);
                //crossover thouse in the mating pool and read to
                //generation for more evaluation
            }
            //add to the generation conter
            GenCounter++;
            //create a new list to copy the next generation into
            Generation = new List <Indevidual>(mating_pool);
            //clear mating pool
            mating_pool.Clear();
        }
        /// <summary>
        /// Crossover_subtrees the specified parent1.
        /// </summary>
        /// <param name="parent1">The parent1.</param>
        /// <param name="parent2">The parent2.</param>
        /// <returns>byte[] offspring</returns>
        public byte[] crossover_subtree(Indevidual parent1, Indevidual parent2)
        {
            //brings back length of list but take one away to access last element
            //(indexed from 0)
            int xoPoint1 = parent1.Program.Length - 1,
            //xoPoint1End,
                xoPoint2 = parent2.Program.Length - 1;
            //xoPoint2End;
            //byte[]
            //parent1start = new byte[],
            //subtree1 = null,
            //parent1end = null,
            //parent2start = null,
            //subtree2 = null;
            //parent2end = null;
            List <byte>
            parent1start     = new List <byte>(),
                subtree1     = new List <byte>(),
                parent1end   = new List <byte>(),
                parent2start = new List <byte>(),
                subtree2     = new List <byte>(),
                parent2end   = new List <byte>();

            Random rnd = new Random(Guid.NewGuid().GetHashCode());

            //first random point is index of tree parent 1
            //keep generating untill its not an end node
            for (int k = 0; parent1.Program[xoPoint1] == End; k++)
            {
                xoPoint1 = rnd.Next(1, parent1.Program.Length - 1);
            }
            //second random point is index of tree parent 2
            //keep generating untill its not an end node
            for (int j = 0; parent2.Program[xoPoint2] == End; j++)
            {
                xoPoint2 = rnd.Next(1, parent2.Program.Length - 1);
            }

            //get first section of parent tree 1
            //add it to first section array
            for (int i = 0; i != xoPoint1; i++)
            {
                parent1start.Add(parent1.Program[i]);
            }

            //collect the sub tree or node from parent 1
            subtree1 = sub_tree_or_node_selection(parent1, xoPoint1, rnd, subtree1);
            //collect the sub tree or node from parent 2
            subtree2 = sub_tree_or_node_selection(parent2, xoPoint2, rnd, subtree2);

            //get the last section from parent tree 1
            //for offspring
            int point = (parent1start.Count + subtree1.Count);

            for (int i = point; i < parent1.Program.Length; i++)
            {
                parent1end.Add(parent1.Program[i]);
                //+1? to points
            }

            //create child of the right size
            byte[] child = new byte[parent1start.Count + subtree2.Count + parent1end.Count];

            parent1start.CopyTo(child, 0);
            subtree2.CopyTo(child, parent1start.Count);
            parent1end.CopyTo(child, parent1start.Count + subtree2.Count);

            //add events to list
            gw.ListEventsAlgorithm.Add(":: Crossover Sub Tree / Node ::");
            gw.ListEventsAlgorithm.Add(":: parent1: " + Draw_tree(parent1.Program) + " ::");
            gw.ListEventsAlgorithm.Add(":: Mutation " + Draw_tree(parent2.Program) + " ::");
            gw.ListEventsAlgorithm.Add(":: offspring: " + Draw_tree(child) + " ::");

            return(child);
        }