예제 #1
0
    public Monster Asexual()
    {
        MonsterTree    childTree = this.tree.Asexual();
        InstructionSet childSet  = this.set.Asexual();

        return(new Monster(childTree, childSet));
    }
예제 #2
0
    private MonsterTree clone()
    {
        MonsterTree newTree = new MonsterTree();

        newTree.nodes = root.CopySubTree();
        newTree.root  = newTree.nodes[0];
        return(newTree);
    }
예제 #3
0
    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);
    }
예제 #4
0
    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);
    }
예제 #5
0
    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());
        }
    }
예제 #6
0
 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");
         }
     }
 }
예제 #7
0
    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));
    }
예제 #8
0
    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);
    }
예제 #9
0
 public void SetMonsterTree(MonsterTree tree)
 {
     this.tree         = tree;
     this.tree.monster = this;
 }
예제 #10
0
 public Monster(MonsterTree tree, InstructionSet set)
 {
     SetMonsterTree(tree);
     SetInstructions(set);
 }
예제 #11
0
 public Monster(MonsterTree tree)
 {
     SetMonsterTree(tree);
     SetInstructions(new InstructionSet());
 }
예제 #12
0
    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);
    }