예제 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="c">colonyCenter</param>
        /// <param name="isQueen"></param>
        private void spawnAnt(Vector2Int c, int spawnRadius, NervousSystem toHave, bool isQueen)
        {
            int rx = UnityEngine.Random.Range(-spawnRadius, spawnRadius);
            int rz = UnityEngine.Random.Range(-spawnRadius, spawnRadius);

            // Finding the highest airblock here
            int y = 0;

            while (Terrain.WorldManager.Instance.GetBlock(c.x + rx, y, c.y + rz).GetType() != typeof(Terrain.AirBlock))
            {
                y++;
            }
            // The offsets here for mere display of gameobject position

            GameObject obj;

            if (isQueen)
            {
                obj        = UnityEngine.Object.Instantiate(Terrain.WorldManager.Instance.queenAntPrefab, new Vector3(c.x + rx, y, c.y + rz), Quaternion.identity);
                this.queen = obj;
            }
            else
            {
                obj = UnityEngine.Object.Instantiate(Terrain.WorldManager.Instance.antPrefab, new Vector3(c.x + rx, y, c.y + rz), Quaternion.identity);
            }


            obj.GetComponent <Ant>().setColony(this);
            obj.GetComponent <Ant>().setPosition(new Vector3Int(c.x + rx, y, c.y + rz));
            obj.GetComponent <Ant>().setNervousSystem(toHave);
            obj.GetComponent <Ant>().colonyId = this.colonyId;
            toHave.antOn = obj.GetComponent <Ant>();
            this.colony.Add(obj);
        }
예제 #2
0
        void Awake()
        {
            this.totalHealth = ConfigurationManager.Instance.initialHealth;
            this.currhealth  = this.totalHealth;

            // Create the nervous system
            ns       = new NervousSystem();
            ns.antOn = this;
        }
예제 #3
0
 /// <summary>
 /// Return bool whether two nodes are connected in the Nervous system
 /// </summary>
 private static bool connectionExists(int i, int j, NervousSystem ns)
 {
     foreach (var c in ns.connections)
     {
         if ((c.id_in == i && c.id_out == j) || (c.id_in == j && c.id_out == i))
         {
             return(true);
         }
     }
     return(false);
 }
예제 #4
0
        public SerializableNS(NervousSystem toSerialize)
        {
            this.nodes       = new List <Node>();
            this.connections = new List <Connection>();

            foreach (var n in toSerialize.nodes)
            {
                Node newN = new Node(n.c, n.val, new List <Connection>(n.attached), n.id);
                this.nodes.Add(newN);
            }



            foreach (var c in toSerialize.connections)
            {
                this.connections.Add(new Connection(c.id_in, c.id_out, c.enabled, c.innovationNum));
            }
        }
예제 #5
0
        public void putColony(int spawnRadius, NervousSystem antNS, NervousSystem queenNS)
        {
            int        l = ConfigurationManager.Instance.Chunk_Diameter * ConfigurationManager.Instance.World_Diameter;
            Vector2Int c = new Vector2Int(UnityEngine.Random.Range(spawnRadius / 2, l / 2 - spawnRadius / 2),
                                          UnityEngine.Random.Range(spawnRadius / 2, l / 2 - spawnRadius / 2));


            // Spawn all ants
            for (int i = 0; i < ConfigurationManager.Instance.antsPerColony; i++)
            {
                NervousSystem newNS = new NervousSystem(antNS.nodes, antNS.connections);
                spawnAnt(c, spawnRadius, newNS, false);
            }
            // Spawning queen
            NervousSystem newNSqueen = new NervousSystem(queenNS.nodes, queenNS.connections);

            spawnAnt(c, spawnRadius, newNSqueen, true);
        }
예제 #6
0
        /// <summary>
        /// Second type of NEAT structural mutation
        ///
        /// a single new connection gene with a random weight is added connecting two previously unconnected nodes
        /// </summary>
        /// <returns></returns>
        public static void MutateByConnection(NervousSystem toMutate)
        {
            // Randomly find two unconnected nodes

            List <int> L1 = new List <int>();

            for (int i = 0; i < toMutate.nodes.Count; i++)
            {
                L1.Add(i);
            }
            var rnd    = new System.Random();
            var result = L1.OrderBy(item => rnd.Next());


            foreach (var i in result)
            {
                foreach (var j in result)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    if ((toMutate.nodes[i].c == 'i' && toMutate.nodes[j].c == 'i') || (toMutate.nodes[i].c == 'o' && toMutate.nodes[j].c == 'o'))
                    {
                        continue;
                    }
                    if (connectionExists(i, j, toMutate))
                    {
                        continue;
                    }

                    // May add new connection here on nodes i and j
                    Connection newC = new Connection(i, j, true, ++toMutate.innovationNumberNow);
                    toMutate.connections.Add(newC);
                    toMutate.nodes[i].attached.Add(newC);
                    toMutate.nodes[j].attached.Add(newC);

                    return;
                }
            }

            Debug.Log("Tried to add a connection but the nervous system was fully connected");
        }
예제 #7
0
        /// <summary>
        /// First type of NEAT structural mutation
        ///
        /// An existing connection is split and the new node placed where the old connection was
        /// </summary>
        /// <returns></returns>
        public static void MutateByNode(NervousSystem toMutate)
        {
            // Randomly choose a connection
            int randomI = Random.Range(0, toMutate.connections.Count);
            // Disable this connection
            Connection gone = toMutate.connections[randomI];

            toMutate.connections.Remove(gone);


            // Add two new connections
            Connection c1 = new Connection(gone.id_in, toMutate.nodes.Count, 1, true, ++toMutate.innovationNumberNow);
            Connection c2 = new Connection(toMutate.nodes.Count, gone.id_out, gone.weight, true, ++toMutate.innovationNumberNow);

            toMutate.connections.Add(c1);
            toMutate.connections.Add(c2);

            List <Connection> newNodeC = new List <Connection>();

            newNodeC.Add(c1);
            newNodeC.Add(c2);
            // Add the new node
            toMutate.nodes.Add(new Node('h', 0, newNodeC, toMutate.nodes.Count));
        }
예제 #8
0
 public void setNervousSystem(NervousSystem n)
 {
     this.ns = n;
 }
예제 #9
0
 /// <summary>
 /// Return the compatibility distance between two nervous systems, used for speciation
 ///
 /// See section 3.3 Protecting Innovation through Speciation in (Stanley et. al)
 /// </summary>
 /// <param name="n1"></param>
 /// <param name="n2"></param>
 /// <returns></returns>
 private float compatDistiance(NervousSystem n1, NervousSystem n2)
 {
     return(0);
 }
예제 #10
0
 /// <summary>
 /// Used when loading the top colony
 /// </summary>
 public Colony(NervousSystem antNS, NervousSystem queenNS)
 {
     colony = new List <GameObject>();
     putColony(ConfigurationManager.Instance.spawnRadius, antNS, queenNS);
 }
예제 #11
0
        /// <summary>
        /// Create a new colony based off a single parent for now.
        ///
        /// Mutate each nervous system by the proper probabilities before passing it on.
        /// </summary>
        /// <param name="spawnRadius"></param>
        /// <param name="singleParent"></param>
        /// <param name="randomChoice"></param>
        public void spawnColony(int spawnRadius, Colony singleParent, bool randomChoice = false)
        {
            int        l = ConfigurationManager.Instance.Chunk_Diameter * ConfigurationManager.Instance.World_Diameter;
            Vector2Int c;

            // Choose a center location in this colony
            if (randomChoice)
            {
                c = new Vector2Int(UnityEngine.Random.Range(spawnRadius / 2, l / 2 - spawnRadius / 2),
                                   UnityEngine.Random.Range(spawnRadius / 2, l / 2 - spawnRadius / 2));
            }
            else
            {
                c = new Vector2Int(l / 4, l / 4);
                if (colonyId == 1)
                {
                    c.y += l / 2;
                }
                else if (colonyId == 2)
                {
                    c.y += l / 2;
                    c.x += l / 2;
                }
                else if (colonyId == 3)
                {
                    c.x += l / 2;
                }
            }


            // Spawn all ants
            for (int i = 0; i < ConfigurationManager.Instance.antsPerColony; i++)
            {
                NervousSystem newNS;
                if (singleParent.bestAnt == null)
                {
                    newNS = new NervousSystem(singleParent.colony[i].GetComponent <Ant>().getNervousSystem().nodes,
                                              singleParent.colony[i].GetComponent <Ant>().getNervousSystem().connections);
                }
                else
                {
                    newNS = new NervousSystem(singleParent.bestAnt.GetComponent <Ant>().getNervousSystem().nodes,
                                              singleParent.bestAnt.GetComponent <Ant>().getNervousSystem().connections);
                }
                for (int k = 0; k < UnityEngine.Random.Range(1, 5); k++)
                {
                    if (UnityEngine.Random.Range(0f, 1f) < ConfigurationManager.Instance.connectionMutationRate)
                    {
                        NeuroEvolution.MutateByConnection(newNS);
                    }
                    if (UnityEngine.Random.Range(0f, 1f) < ConfigurationManager.Instance.nodeMutationRate)
                    {
                        NeuroEvolution.MutateByConnection(newNS);
                    }
                }

                spawnAnt(c, spawnRadius, newNS, false);
            }

            NervousSystem newNSqueen = new NervousSystem(singleParent.queen.GetComponent <Ant>().getNervousSystem().nodes,
                                                         singleParent.queen.GetComponent <Ant>().getNervousSystem().connections);

            for (int k = 0; k < UnityEngine.Random.Range(1, 5); k++)
            {
                // Spawning the queen
                if (UnityEngine.Random.Range(0f, 1f) < ConfigurationManager.Instance.connectionMutationRate)
                {
                    NeuroEvolution.MutateByConnection(newNSqueen);
                }
                if (UnityEngine.Random.Range(0f, 1f) < ConfigurationManager.Instance.nodeMutationRate)
                {
                    NeuroEvolution.MutateByNode(newNSqueen);
                }
            }
            spawnAnt(c, spawnRadius, newNSqueen, true);
        }