//Initializes Population and their memories.
 public List<Dilemma> RampedHalfAndHalfInitialization(int populationsize, int memorylength)
 {
     List<Dilemma> population = new List<Dilemma>();
       for(int i = 0; i < populationsize; i++)
       {
     int fullorgrow = RandomGenerator.Next(0, 2);
     Dilemma newdilemma = new Dilemma();
     newdilemma.GenerateUniformRandomMemory(memorylength, RandomGenerator);
     //Full Method
     if(fullorgrow == 0)
     {
       newdilemma.Tree = GenerateNewUniformRandomTreeFull(config.MaxTreeDepth, 1, newdilemma.Memory, RandomGenerator, treepossibilities);
       population.Add(newdilemma);
     }
     //Grow Method
     else
     {
       newdilemma.Tree = GenerateNewUniformRandomTreeGrow(config.MaxTreeDepth, 1, newdilemma.Memory, RandomGenerator, treepossibilities);
       population.Add(newdilemma);
     }
       }
       return population;
 }
        //Play the IPD, evaluating fitness for sequencelength - 2 * memorylength
        public void PlayIPD(ref Dilemma dilemma1, ref Dilemma dilemma2, int sequencelength, double parsimonypressure, int maxtreedepth, int memorylength)
        {
            dilemma1.GenerateUniformRandomMemory(memorylength, RandomGenerator);
              dilemma2.GenerateUniformRandomMemory(memorylength, RandomGenerator);
              double fitness1 = 0.0;
              double fitness2 = 0.0;
              for(int i = 0; i < sequencelength; i++)
              {
            if (i >= 2 * memorylength)
            {
              //Add to total fitness
              fitness1 += (double)SingleFitnessCalculation(dilemma1.Tree.GetValue(dilemma1.Memory), dilemma2.Tree.GetValue(dilemma2.Memory));
              fitness2 += (double)SingleFitnessCalculation(dilemma2.Tree.GetValue(dilemma2.Memory), dilemma1.Tree.GetValue(dilemma1.Memory));
            }
            //Place it in memory
            dilemma1.Memory.Enqueue(new bool[2] { dilemma1.Tree.GetValue(dilemma1.Memory), dilemma2.Tree.GetValue(dilemma2.Memory) });
            dilemma2.Memory.Enqueue(new bool[2] { dilemma2.Tree.GetValue(dilemma2.Memory), dilemma1.Tree.GetValue(dilemma1.Memory) });
            //If the memory is bigger than is allowed, pop the shiz.
            if(dilemma1.Memory.Count > memorylength)
            {
              dilemma1.Memory.Dequeue();
            }
            if(dilemma2.Memory.Count > memorylength)
            {
              dilemma2.Memory.Dequeue();
            }
              }
              fitness1 /= ((double)sequencelength - 2.0 * (double)memorylength);
              fitness2 /= ((double)sequencelength - 2.0 * (double)memorylength);
              //Parsimony pressure:
              //Fitness = Fitness - Fitness * Parsimony Pressure * (Tree Size / Max Tree Size)
              //Parsimony Pressure is a double between 0.0 and 1.0.
              //Max tree size is 2^(Max Tree Depth) + 1

              fitness1 -= (fitness1 * (parsimonypressure * (double)dilemma1.Tree.Size / (double)((2<<maxtreedepth) + 1)));
              fitness2 -= (fitness2 * (parsimonypressure * (double)dilemma2.Tree.Size / (double)((2<<maxtreedepth) + 1)));
              dilemma1.Fitness += fitness1;
              dilemma2.Fitness += fitness2;
              fitnessevals++;
        }