public Monster Asexual() { MonsterTree childTree = this.tree.Asexual(); InstructionSet childSet = this.set.Asexual(); return(new Monster(childTree, childSet)); }
private MonsterTree clone() { MonsterTree newTree = new MonsterTree(); newTree.nodes = root.CopySubTree(); newTree.root = newTree.nodes[0]; return(newTree); }
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); }
static InstructionSet RemapInstructionSet(Monster parent, MonsterTree childTree, Dictionary <MonsterTreeNode, int> parent1Map) { InstructionSet ret = parent.set.Asexual(); //Get position map of node to position in array Dictionary <MonsterTreeNode, int> childMap = new Dictionary <MonsterTreeNode, int>(); for (int i = 0; i < childTree.nodes.Count; ++i) { childMap.Add(childTree.nodes[i], i); } //Find map from parent to child tree positions, or -1 if parent didn't pass down this node to child Dictionary <int, int> positionRemap = new Dictionary <int, int>(); foreach (KeyValuePair <MonsterTreeNode, int> pair in parent1Map) { if (childMap.ContainsKey(pair.Key)) { positionRemap.Add(pair.Value, childMap[pair.Key]); } else { positionRemap.Add(pair.Value, -1); } } //Remap instructions based on map for (int i = 0; i < ret.getCount(); ++i) { Instruction instruction = ret.getInstruction(i); //Remap if found if (positionRemap.ContainsKey(instruction.getNode())) { if (positionRemap[instruction.getNode()] != -1) { instruction.setNode(positionRemap[instruction.getNode()]); } else // if(instruction.getNode() >= childTree.NodeCount()){ //Remove Instruction if now out of bounds { ret.removeInstructionAt(i--); } } //Do nothing if not found but in bounds } return(ret); }
public Monster Breed(Monster other) { float rand = Random.Range(0.0f, 1.0f); if (rand <= SEXUAL_REPRO_CHANCE) { Dictionary <MonsterTreeNode, int> parent1Map; Dictionary <MonsterTreeNode, int> parent2Map; MonsterTree childTree = this.tree.Breed(other.tree, out parent1Map, out parent2Map); InstructionSet remappedSet1 = RemapInstructionSet(this, childTree, parent1Map); InstructionSet remappedSet2 = RemapInstructionSet(other, childTree, parent2Map); InstructionSet childSet = remappedSet1.Breed(remappedSet2); return(new Monster(childTree, childSet)); } else { return(Asexual()); } }
public MonsterTree Breed(MonsterTree tree, out Dictionary <MonsterTreeNode, int> parent1Map, out Dictionary <MonsterTreeNode, int> parent2Map) { while (true) { try{ float type = UnityEngine.Random.Range(0.0f, 1.0f); if (type <= Monster.CROSSOVER_CHANCE) { //Crossover return(crossover(tree, out parent1Map, out parent2Map)); } else { //Grafting return(graft(tree, out parent1Map, out parent2Map)); } } catch { Debug.Log("Bad Tree: Ignoring"); } } }
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)); }
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 void SetMonsterTree(MonsterTree tree) { this.tree = tree; this.tree.monster = this; }
public Monster(MonsterTree tree, InstructionSet set) { SetMonsterTree(tree); SetInstructions(set); }
public Monster(MonsterTree tree) { SetMonsterTree(tree); SetInstructions(new InstructionSet()); }
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); }