/// <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); }
void Awake() { this.totalHealth = ConfigurationManager.Instance.initialHealth; this.currhealth = this.totalHealth; // Create the nervous system ns = new NervousSystem(); ns.antOn = this; }
/// <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); }
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)); } }
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); }
/// <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"); }
/// <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)); }
public void setNervousSystem(NervousSystem n) { this.ns = n; }
/// <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); }
/// <summary> /// Used when loading the top colony /// </summary> public Colony(NervousSystem antNS, NervousSystem queenNS) { colony = new List <GameObject>(); putColony(ConfigurationManager.Instance.spawnRadius, antNS, queenNS); }
/// <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); }