Ejemplo n.º 1
0
    //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);
    }
Ejemplo n.º 2
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);
    }
Ejemplo n.º 3
0
    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);
    }
Ejemplo n.º 4
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));
    }
Ejemplo n.º 5
0
 public CubeTreeNode(int p = -1)
 {
     parent   = p;
     children = new MonsterTreeNode[20];
     scale    = randomScale();
 }
Ejemplo n.º 6
0
    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);
    }
Ejemplo n.º 7
0
 private void Randomize(int maxDepth)
 {
     root = new CubeTreeNode(-1);
     root.Randomize(maxDepth, maxDepth);
     nodes = root.GetSubTree();
 }
Ejemplo n.º 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);
    }
Ejemplo n.º 9
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);
    }
Ejemplo n.º 10
0
    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);
    }