/// <summary>
        /// This constructor creates a default network to work with.
        /// </summary>
        /// <param name="aoe2Directory">Directory of your age of empires game.</param>
        /// <param name="aiScript">Name of your ai script that you want to generate.</param>
        public AITrainingModule(string aoe2Directory, string aiScript)
        {
            _logger = Program.Logger;
            _logger.Info("Initializing Training module.");

            _aoe2Directory = aoe2Directory;
            _aiScript      = aiScript;

            _numberOfInitialCycles    = 100000;
            _numberOfContinuousCycles = 10000;
            _numberOfNeuronRefreshes  = 0;

            // Keep track of random number of neurons here.
            int numberOfInputNeurons  = 10;
            int numberOfHiddenNeurons = 10;
            int numberOfOutputNeurons = 8;

            double learningRate = 0.25;

            _errorList = new LinkedList <double>();

            LinearLayer  inputLayer  = new LinearLayer(numberOfInputNeurons);
            SigmoidLayer hiddenLayer = new SigmoidLayer(numberOfHiddenNeurons);
            SigmoidLayer outputLayer = new SigmoidLayer(numberOfOutputNeurons);

            // Wow, how hidden is really hidden. So that I think these connectors do is
            // insert themselves as part of the various layers. This really hides the hidden
            // layer from the network, as only the connectors then modify the hidden layer.
            // In other words "trained".
            var conn1 = new BackpropagationConnector(inputLayer, hiddenLayer);
            var conn2 = new BackpropagationConnector(hiddenLayer, outputLayer);

            _nueralNetwork = new BackpropagationNetwork(inputLayer, outputLayer);
            _nueralNetwork.SetLearningRate(learningRate);
            _nueralNetwork.EndEpochEvent += BackgroundTasks;             // hehe call back methods.

            // Needs to make initial configuration of AI.
            _logger.Warn("Begining initial training cycle...");

            // If this module is being instantiated for the first time, create a comprehensive
            // knowledge base/ network so it can continue where it last left off. Tweak the
            // query to filter outliers.
            _rawMgxStats = StreamUtilities.GetAiDataSet();

            _nueralNetwork.EndEpochEvent +=
                (object networkInput, TrainingEpochEventArgs args) =>
            {
                if (_percent % (_numberOfInitialCycles / 100) == 0 && _percent > 0)
                {
                    _logger.Info(string.Format("Precent completed {0}%", _percent / (_numberOfInitialCycles / 100)));
                }

                _percent++;
            };

            _nueralNetwork.Learn(CompileTrainingSet(_rawMgxStats), _numberOfInitialCycles);
            _logger.Warn("Finished initial training cycle.");

            // Get the latest dataset so we can generate some kind of graph and push the data set to database.
            var knowledgeBase = StreamUtilities.GetLatestAiEntry().ToList();
            var aiTrainingSet = CompileTrainingSet(knowledgeBase);

            _currentStats = knowledgeBase[knowledgeBase.Count - 1];

            // push data, hacked to show simple output
            //double[] veryFirstInput
            //	 =
            //{
            //	0.2,0.2,0.2,0.2,0.2,
            //	0.2,0.2,0.2,0.2,0.2
            //};

            _climber = new HillClimbing(aiTrainingSet[0].InputVector, _nueralNetwork);
            // _climber = new HillClimbing(veryFirstInput, _nueralNetwork);


            // Hardcoding these dimensions
            int ordinalTracker = 1;

            for (int i = 0; i < 4; i++)
            {
                for (int j = i + 1; j < 5; j++)
                {
                    //write normalized data
                    StreamUtilities.SubmitPlotableData(_climber.GenerateTopologyData(i, j), ordinalTracker);

                    //write unnormalized data.
                    StreamUtilities.SubmitPlotableUnnormailizedData(_climber.GenerateUnormalizedTopologyData(i, j), ordinalTracker);
                    _logger.Debug(string.Format("Writing Axis{0} and Axis{1} with ordinal {2}.", i, j, ordinalTracker));
                    ordinalTracker++;
                }
            }

            // If input table == output, then a new game is needed
            if (StreamUtilities.CheckIfNewGameIsNeeded())
            {
                TriggerNewGame();
            }
        }