NEAT::GeneticPopulation* CoCheckersExperiment::createInitialPopulation(int populationSize)
    {
        GeneticPopulation *population = new GeneticPopulation(
            shared_ptr<CoCheckersExperiment>((CoCheckersExperiment*)this->clone())
        );
        vector<GeneticNodeGene> genes;

        genes.push_back(GeneticNodeGene("Bias","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("X1","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("Y1","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("X2","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("Y2","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("DeltaX","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("DeltaY","NetworkSensor",0,false));
        genes.push_back(GeneticNodeGene("Output_ab","NetworkOutputNode",1,false,ACTIVATION_FUNCTION_SIGMOID));
        genes.push_back(GeneticNodeGene("Output_bc","NetworkOutputNode",1,false,ACTIVATION_FUNCTION_SIGMOID));
        genes.push_back(GeneticNodeGene("Output_ac","NetworkOutputNode",1,false,ACTIVATION_FUNCTION_SIGMOID));
#if CHECKERS_EXPERIMENT_ENABLE_BIASES
        genes.push_back(GeneticNodeGene("Bias_b","NetworkOutputNode",1,false,ACTIVATION_FUNCTION_SIGMOID));
        genes.push_back(GeneticNodeGene("Bias_c","NetworkOutputNode",1,false,ACTIVATION_FUNCTION_SIGMOID));
#endif

        for (int a=0;a<populationSize;a++)
        {
            shared_ptr<GeneticIndividual> individual(new GeneticIndividual(genes,true,1.0));

            for (int b=0;b<0;b++)
            {
                individual->testMutate();
            }

            population->addIndividual(individual);
        }

        shared_ptr<NEAT::CoEvoGeneticGeneration> coEvoGeneration =
            static_pointer_cast<NEAT::CoEvoGeneticGeneration>(population->getGeneration());

        //Create the tests
        for (int a=0;a<(population->getIndividualCount()/10);a++)
        {
            shared_ptr<NEAT::GeneticIndividual> individual(new GeneticIndividual(genes,true,1.0));

            //This function clones the individual to make a test
            coEvoGeneration->addTest(individual);
        }

        coEvoGeneration->bootstrap();

        cout << "Finished creating population\n";
        return population;
    }
  GeneticPopulation* ModNeatExperiment7::createInitialPopulation(int populationSize) {
  	GeneticPopulation *population = new GeneticPopulation();
  	vector<GeneticNodeGene> genes;

  	// Set-up the CCPPN which encodes the substrate weights

  	////// CCPPN encoding a 3 layered sandwich substrate's weights
  	// Configuration of the CCPPN's Input layer
  	genes.push_back(GeneticNodeGene("X1", "NetworkSensor", 0, false)); // position on the X axis in the substrate's link start layers
  	genes.push_back(GeneticNodeGene("Y1", "NetworkSensor", 0, false)); // position on the Y axis in the substrate's link start layers
  	genes.push_back(GeneticNodeGene("Z1", "NetworkSensor", 0, false)); // position on the Z axis in the substrate's link start layers

  	genes.push_back(GeneticNodeGene("X2", "NetworkSensor", 0, false)); // position on the X axis in the substrate's link end layers
  	genes.push_back(GeneticNodeGene("Y2", "NetworkSensor", 0, false)); // position on the Y axis in the substrate's link end layers
  	genes.push_back(GeneticNodeGene("Z2", "NetworkSensor", 0, false)); // position on the Z axis in the substrate's link end layers
    
    #ifdef USE_BIASES
  	 genes.push_back(GeneticNodeGene("Bias", "NetworkSensor", 0, false)); // bias for the CPPN
    #endif // USE_BIASES

    #ifdef USE_DELTAS
  	 genes.push_back(GeneticNodeGene("DeltaX", "NetworkSensor", 0, false)); // offset between the two nodes on the X axis
  	 genes.push_back(GeneticNodeGene("DeltaY", "NetworkSensor", 0, false)); // offset between the two nodes on the Y axis
  	 genes.push_back(GeneticNodeGene("DeltaZ", "NetworkSensor", 0, false)); // offset between the two nodes on the Z axis
    #endif // USE_DELTAS

    #ifdef MODULAR_HNEAT
    	screen << "Laying out a heterogeneous controller CPPN" << endl;
    	genes.push_back(GeneticNodeGene("T1", "NetworkSensor", 0, false)); // position in the body
    	genes.push_back(GeneticNodeGene("T2", "NetworkSensor", 0, false)); // offset between the two nodes on the Z axis
      #ifdef USE_DELTAS
  	   genes.push_back(GeneticNodeGene("DeltaT", "NetworkSensor", 0, false)); // offset between the two nodes on the Z axis
      #endif  // USE_DELTAS
    #endif  // MODULAR_HNEAT

    #ifndef MODULAR_HNEAT
  	 screen << "Laying out a homogeneous controller CPPN" << endl;
    #endif

  	// Configuration of the CCPPN's Output layer
  	genes.push_back(GeneticNodeGene("Output", "NetworkOutputNode", 1, false, ACTIVATION_FUNCTION_SIGMOID)); // weight for link between layers A and B

    #ifdef USE_BIASES
  	 genes.push_back(GeneticNodeGene("Bias_out", "NetworkOutputNode", 1, false, ACTIVATION_FUNCTION_SIGMOID)); // bias for the second sandwich layer
    #endif // USE_BIASES

  	// Create the initial population
  	for (int a = 0; a < populationSize; a++) {
  		shared_ptr<GeneticIndividual> individual(new GeneticIndividual(genes, true, 1.0));

  		for (int b = 0; b < 0; b++) {
  			individual->testMutate();
  		}

  		population->addIndividual(individual);
  	}

  	screen << "Finished creating population\n";

    // store population and individual size
    popSize = population->getIndividualCount();
    // screen << "\n individual count: " << popSize << "\n";

  	return population;
  }