//Does NOT clone children, only local data to the node public MonsterTreeNode LocalClone() { MonsterTreeNode cloneNode = createEmptyClone(); cloneNode.parent = parent; //I think the GameObject shouldn't be cloned here, just the info about it (scale) //cloneNode.obj = GameObject.Instantiate(obj); cloneNode.children = new MonsterTreeNode[children.Length]; cloneNode.scale = scale; return(cloneNode); }
private MonsterTree graft(MonsterTree tree, out Dictionary <MonsterTreeNode, int> parent1Map, out Dictionary <MonsterTreeNode, int> parent2Map) { //Select Node and where to insert in this node from caller's tree int index = Random.Range(0, nodes.Count); MonsterTreeNode selectedNode = nodes[index]; int insertionPos; do { insertionPos = Random.Range(0, selectedNode.children.Length); }while(insertionPos == selectedNode.parent); //Select Node from param's tree int targetIndex = Random.Range(0, tree.nodes.Count); MonsterTreeNode targetNode = tree.nodes[targetIndex]; //Copy Caller's Tree and target's subtree MonsterTree res = this.clone(); parent1Map = new Dictionary <MonsterTreeNode, int>(); for (int i = 0; i < res.nodes.Count; ++i) { parent1Map.Add(res.nodes[i], i); } parent2Map = new Dictionary <MonsterTreeNode, int>(); Dictionary <MonsterTreeNode, int> tempMap = new Dictionary <MonsterTreeNode, int>(); for (int i = 0; i < tree.nodes.Count; ++i) { tempMap.Add(tree.nodes[i], i); } List <MonsterTreeNode> subtree = targetNode.GetSubTree(); List <MonsterTreeNode> newNodes = targetNode.CopySubTree(); for (int i = 0; i < subtree.Count; ++i) { if (tempMap.ContainsKey(subtree[i])) { parent2Map.Add(newNodes[i], tempMap[subtree[i]]); } } if (index < res.nodes.Count && index > 0 && insertionPos < res.nodes[index].children.Length && insertionPos > 0 && newNodes.Count > 0) { //Insert into Caller and add target's nodes to caller's list res.nodes[index].children[insertionPos] = newNodes[0]; res.nodes.AddRange(newNodes); } return(res); }
private MonsterTreeNode GetSubTreeHelper(List <MonsterTreeNode> nodes, MonsterTreeNode parentNode) { MonsterTreeNode copyNode = this; nodes.Add(copyNode); for (int i = 0; i < children.Length; ++i) { if (children[i] == null) { continue; } if (i == parent) { copyNode.children[i] = parentNode; } else { copyNode.children[i] = children[i].GetSubTreeHelper(nodes, this); } } return(copyNode); }
public void Mutate() { bool selfCollides = false; bool dirty = false; MonsterTree copy = this.clone(); do { for (int i = 0; i < copy.nodes.Count; ++i) { MonsterTreeNode node = nodes[i]; dirty |= mutateNode(node); } if (dirty && (selfCollides = selfIntersects())) { this.nodes = copy.nodes; this.root = copy.root; copy = clone(); dirty = false; } }while (!((selfCollides && dirty) || !dirty)); }
public CubeTreeNode(int p = -1) { parent = p; children = new MonsterTreeNode[20]; scale = randomScale(); }
public bool mutateNode(MonsterTreeNode node) { /** * Add a node * Remove a node * Move a connection's or connections' position * Change scale x, y, and z **/ float random = Random.Range(0.0f, 1.0f); if (random <= Monster.PER_NODE_MUTATION_CHANCE) { random = Random.Range(0.0f, 1.0f); if (random <= 0.1f) { //Add a node at 10% MonsterTreeNode newNode = node.createEmptyClone(); List <int> freeNodePositions = new List <int>(); int count = 0; foreach (MonsterTreeNode child in node.children) { if (child == null) { freeNodePositions.Add(count); } ++count; } if (freeNodePositions.Count != 0) { int rand = Random.Range(0, freeNodePositions.Count); int pos = freeNodePositions[rand]; node.children[pos] = newNode; this.nodes.Add(newNode); return(true); } } else if (random <= 0.2f) { //Remove a node at 10% List <int> childNodePositions = new List <int>(); int count = 0; foreach (MonsterTreeNode child in node.children) { if (count != node.parent && child != null) { childNodePositions.Add(count); } ++count; } if (childNodePositions.Count != 0) { node.children[childNodePositions[Random.Range(0, childNodePositions.Count)]] = null; } } else if (random <= 0.6f) { //Move a Connection at 40% List <int> childNodePositions = new List <int>(); List <int> freeNodePositions = new List <int>(); int count = 0; foreach (MonsterTreeNode child in node.children) { if (count != node.parent && child != null) { childNodePositions.Add(count); } else if (count != node.parent) { freeNodePositions.Add(count); } ++count; } if (childNodePositions.Count > 0) { MonsterTreeNode nodeToBeMoved = node.children[childNodePositions[Random.Range(0, childNodePositions.Count)]]; int insertionPos = Random.Range(0, freeNodePositions.Count); node.children[insertionPos] = nodeToBeMoved; return(true); } } else { //Scale at 40% node.scale += node.randomScale() / 4.0f; return(true); } } return(false); }
private void Randomize(int maxDepth) { root = new CubeTreeNode(-1); root.Randomize(maxDepth, maxDepth); nodes = root.GetSubTree(); }
private MonsterTree crossover(MonsterTree tree, out Dictionary <MonsterTreeNode, int> parent1Map, out Dictionary <MonsterTreeNode, int> parent2Map) { MonsterTree parent1 = this.clone(); MonsterTree parent2 = tree.clone(); //Get positions of all the caller's nodes parent1Map = new Dictionary <MonsterTreeNode, int>(); for (int i = 0; i < parent1.nodes.Count; ++i) { parent1Map.Add(parent1.nodes[i], i); } //Get positions of all the param's nodes parent2Map = new Dictionary <MonsterTreeNode, int>(); for (int i = 0; i < parent2.nodes.Count; ++i) { parent2Map.Add(parent2.nodes[i], i); } //Find Crossover Point (one for simplicity) int crossoverPoint = Random.Range(0, parent1.nodes.Count); //Combine node lists bases on crossover in first parent parent1.nodes.RemoveRange(crossoverPoint, parent1.nodes.Count - crossoverPoint); parent2.nodes.RemoveRange(0, min(crossoverPoint, parent2.nodes.Count)); parent1.nodes.AddRange(parent2.nodes); //Remap Parent1's nodes for (int i = 0; i < crossoverPoint; ++i) { MonsterTreeNode currNode = parent1.nodes[i]; for (int c = 0; c < currNode.children.Length; ++c) { MonsterTreeNode child = currNode.children[c]; if (child == null || c == currNode.parent) { continue; } int childPos = parent1Map[child]; if (childPos < parent1.nodes.Count) { currNode.children[c] = parent1.nodes[childPos]; } else { currNode.children[c] = null; } } } //Remap Parent2's nodes for (int i = crossoverPoint; i < parent1.nodes.Count; ++i) { MonsterTreeNode currNode = parent1.nodes[i]; for (int c = 0; c < currNode.children.Length; ++c) { MonsterTreeNode child = currNode.children[c]; if (child == null || c == currNode.parent) { continue; } int childPos = parent2Map[child]; if (childPos < parent1.nodes.Count) { currNode.children[c] = parent1.nodes[childPos]; } else { currNode.children[c] = null; } } } return(parent1); }
public static Monster ReadFromFile(string filename) { System.IO.FileStream f = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read); Monster m = new Monster(true); try{ byte[] bytes = new byte[8]; f.Read(bytes, 0, 4); m.fitness = System.BitConverter.ToSingle(bytes, 0); f.Read(bytes, 0, 4); int icount = System.BitConverter.ToInt32(bytes, 0); List <Instruction> il = new List <Instruction> (); for (int i = 0; i < icount; i++) { f.Read(bytes, 0, 4); int n = System.BitConverter.ToInt32(bytes, 0); f.Read(bytes, 0, 4); float s = System.BitConverter.ToSingle(bytes, 0); il.Add(new Instruction(n, s)); } m.set = new InstructionSet(il); f.Read(bytes, 0, 4); int ncount = System.BitConverter.ToInt32(bytes, 0); Debug.Log("NCOUNT: " + ncount); List <MonsterTreeNode> mtnl = new List <MonsterTreeNode> (); int[,] links = new int[ncount, 20]; for (int i = 0; i < ncount; i++) { CubeTreeNode mtn = new CubeTreeNode(); f.Read(bytes, 0, 4); mtn.parent = System.BitConverter.ToInt32(bytes, 0); f.Read(bytes, 0, 4); mtn.scale.x = System.BitConverter.ToSingle(bytes, 0); f.Read(bytes, 0, 4); mtn.scale.y = System.BitConverter.ToSingle(bytes, 0); f.Read(bytes, 0, 4); mtn.scale.z = System.BitConverter.ToSingle(bytes, 0); for (int j = 0; j < 20; j++) { f.Read(bytes, 0, 4); links[i, j] = System.BitConverter.ToInt32(bytes, 0); } mtnl.Add(mtn); } //Now actually link them for (int i = 0; i < ncount; i++) { MonsterTreeNode mtn = mtnl [i]; for (int j = 0; j < 20; j++) { if (links[i, j] == -1) { mtn.children [j] = null; } else { mtn.children [j] = mtnl [links [i, j]]; } } } MonsterTree mt = new MonsterTree(); mt.nodes = mtnl; mt.root = mtnl [0]; mt.monster = m; m.tree = mt; }catch { m = null; } f.Close(); return(m); }
public string WriteToFile() { ulong name1 = 0; ulong name2 = 0; List <byte> toOut = new List <byte> (); WriteBytes(System.BitConverter.GetBytes(fitness), toOut); WriteBytes(System.BitConverter.GetBytes(set.getCount()), toOut); for (int i = 0; i < set.getCount(); i++) { Instruction ins = set.getInstruction(i); WriteBytes(System.BitConverter.GetBytes(ins.getNode()), toOut); WriteBytes(System.BitConverter.GetBytes(ins.getSpeed()), toOut); } WriteBytes(System.BitConverter.GetBytes(tree.nodes.Count), toOut); for (int i = 0; i < tree.nodes.Count; i++) { MonsterTreeNode mtn = tree.nodes [i]; WriteBytes(System.BitConverter.GetBytes(mtn.parent), toOut); WriteBytes(System.BitConverter.GetBytes(mtn.scale.x), toOut); WriteBytes(System.BitConverter.GetBytes(mtn.scale.y), toOut); WriteBytes(System.BitConverter.GetBytes(mtn.scale.z), toOut); for (int j = 0; j < 20; j++) { MonsterTreeNode link = mtn.children [j]; bool isFound = false; if (link == null) { WriteBytes(System.BitConverter.GetBytes((int)-1), toOut); } else { for (int k = 0; k < tree.nodes.Count; k++) { if (link == tree.nodes [k]) { isFound = true; WriteBytes(System.BitConverter.GetBytes(k), toOut); break; } } if (!isFound) { Debug.Log("DID NOT FIND!!!"); WriteBytes(System.BitConverter.GetBytes((int)-1), toOut); } } } } byte[] bytes = new byte[toOut.Count]; for (int i = 0; i < toOut.Count; i++) { bytes [i] = toOut [i]; } GetName(bytes, ref name1, ref name2); string name = "Monsters/" + Mathf.RoundToInt(fitness) + "-" + name1 + "-" + name2 + ".mon"; System.IO.FileStream f = new System.IO.FileStream(name, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write); f.Write(bytes, 0, bytes.Length); f.Close(); return(name); }