private static JsonNeuron[] GetOutputNeurons(NeuralGenome target)
        {
            float x, y;
            float deltaY = 0;

            x = 1f - xPadding;
            if (target.Outputs.Count() == 1)
            {
                y = 0.5f;
            }
            else
            {
                y      = yPadding;
                deltaY = (1f - 2 * yPadding) / target.Outputs.Count();
            }
            var outputNeurons = target.Outputs.Select(n =>
            {
                var pos    = GetNeuronPos(n, x, y);
                var result = new JsonNeuron
                {
                    x     = pos.X,
                    y     = pos.Y,
                    innov = n.InnovationNb,
                    color = new[] { 1f, 0.917f, 0.721f },
                    label = "O"
                };

                y += deltaY;
                return(result);
            }).ToArray();

            return(outputNeurons);
        }
        private static JsonNeuron[] GetRemainingNeurons(NeuralGenome target)
        {
            var remainingNodes = target.Neurons.Values
                                 .Where(n =>
                                        !target.Inputs.Contains(n) &&
                                        !target.Outputs.Contains(n) &&
                                        !target.Biasses.Contains(n) &&
                                        n.group == null)
                                 .ToArray();

            //  Compute the positions
            foreach (var node in remainingNodes)
            {
                Vector2 pos;

                if (!NeuronPos.ContainsKey(node.InnovationNb))
                {
                    pos = GetRandomPos(randomPosTries);
                    NeuronPos.Add(node.InnovationNb, pos);
                }
            }

            var remainingNeurons = remainingNodes.Select(n =>
            {
                JsonNeuron result;

                if (typeof(MemoryNeuron).IsAssignableFrom(n.GetType()))
                {
                    result = new JsonNeuron
                    {
                        x     = NeuronPos[n.InnovationNb].X,
                        y     = NeuronPos[n.InnovationNb].Y,
                        innov = n.InnovationNb,
                        color = new[] { 0.949f, 1, 0 },
                        label = string.Format("{0}<", (n as MemoryNeuron).TargetNeuron)
                    };
                }
                else
                {
                    result = new JsonNeuron
                    {
                        x     = NeuronPos[n.InnovationNb].X,
                        y     = NeuronPos[n.InnovationNb].Y,
                        innov = n.InnovationNb,
                    };
                }

                return(result);
            }).ToArray();

            return(remainingNeurons);
        }
        private static JsonNeuron[] GetInputNeurons(NeuralGenome target)
        {
            float x, y;
            float deltaY = 0;

            // Inputs
            x = xPadding;
            y = yPadding;
            var inputs = target.Inputs.Concat(target.Biasses);

            deltaY = (1f - 2 * yPadding) / inputs.Count();
            var inputNeurons = inputs.Select(n =>
            {
                JsonNeuron result;

                var pos = GetNeuronPos(n, x, y);
                if (target.Inputs.Contains(n))
                {
                    result = new JsonNeuron
                    {
                        x     = pos.X,
                        y     = pos.Y,
                        innov = n.InnovationNb,
                        color = new[] { 1f, 0.721f, 0.992f },
                        label = "I"
                    };
                }
                else
                {
                    result = new JsonNeuron
                    {
                        x     = pos.X,
                        y     = pos.Y,
                        innov = n.InnovationNb,
                        color = new[] { 0.627f, 0.160f, 1f },
                        label = "B"
                    };
                }
                y += deltaY;
                return(result);
            }).ToArray();

            return(inputNeurons);
        }
        private static void ProcessNetworkGroups(
            NeuralGenome target,
            List <JsonNeuron> jsonNeurons,
            List <JsonEdge> jsonEdges)
        {
            var groups = target.Neurons.Values.Where(x => x.group != null)
                         .GroupBy(x => x.group)
                         .ToArray();

            if (groups == null || groups.Length == 0)
            {
                return;
            }

            foreach (var group in groups)
            {
                var innov = group.First().InnovationNb;

                if (!NeuronPos.ContainsKey(innov))
                {
                    NeuronPos.Add(innov, GetRandomPos(randomPosTries));
                }
                var pos = NeuronPos[innov];

                var jsonNeuron = new JsonNeuron
                {
                    x     = pos.X,
                    y     = pos.Y,
                    innov = innov,
                    color = new[] { 0.101F, 0.882F, 1 },
                    label = group.Key
                };

                jsonNeurons.Add(jsonNeuron);

                var start = target.NeuralGenes
                            .Select(x => x.Synapse)
                            .Where(x =>
                                   target.Neurons[x.incoming].group != group.Key &&
                                   target.Neurons[x.outgoing].group == group.Key);

                var end = target.NeuralGenes
                          .Select(x => x.Synapse)
                          .Where(x =>
                                 target.Neurons[x.incoming].group == group.Key &&
                                 target.Neurons[x.outgoing].group != group.Key);

                foreach (var edge in start)
                {
                    jsonEdges.Add(new JsonEdge
                    {
                        start = edge.incoming,
                        end   = innov,
                        w     = edge.Weight
                    });
                }

                foreach (var edge in end)
                {
                    jsonEdges.Add(new JsonEdge
                    {
                        start = innov,
                        end   = edge.outgoing,
                        w     = edge.Weight
                    });
                }
            }
        }