示例#1
0
        public (AptNode, int) GetNthNode(int n)
        {
            if (n == 0)
            {
                return(this, n);
            }
            AptNode node = new AptNode {
                type = NodeType.EMPTY
            };

            if (children != null)
            {
                foreach (var child in children)
                {
                    (node, n) = child.GetNthNode(n - 1);
                    if (node.type != NodeType.EMPTY)
                    {
                        return(node, n);
                    }
                }
            }
            return(new AptNode {
                type = NodeType.EMPTY
            }, n);
        }
示例#2
0
        public void InsertWarp(Random r)
        {
            var node = this;

            if (node.children == null)
            {
                return;
            }

            //1 in 3 chance of applying warp to a node that has an X and a Y as children
            if (node.children.Length >= 2 && r.Next(0, 3) == 0 &&
                ((node.children[0].type == NodeType.X && node.children[1].type == NodeType.Y) ||
                 (node.children[1].type == NodeType.X && node.children[0].type == NodeType.Y)))
            {
                Console.WriteLine("WARP");
                var newChildren = new AptNode[node.children.Length - 1];
                var warp        = new AptNode {
                    type = NodeType.WARP1, children = new AptNode[5]
                };
                warp.children[0] = new AptNode {
                    type = NodeType.X
                };
                warp.children[0].parent = warp;
                warp.children[1]        = new AptNode {
                    type = NodeType.Y
                };
                warp.children[1].parent = warp;
                warp.children[4]        = new AptNode {
                    type = NodeType.CONSTANT, value = (float)r.NextDouble() * 2.0f - 1.0f
                };
                warp.children[4].parent = warp;

                //fill in the stuff the warp node needs
                while (warp.AddLeaf(GetRandomLeaf(r)))
                {
                }
                newChildren[0] = warp;
                warp.parent    = node;
                for (int i = 1; i < newChildren.Length; i++)
                {
                    newChildren[i] = node.children[i + 1];
                }
                node.children = newChildren;
            }
            else
            {
                foreach (var child in node.children)
                {
                    child.InsertWarp(r);
                }
            }
        }
示例#3
0
        // Note: assumes you are adding to a non leaf node, always
        public void AddRandom(AptNode nodeToAdd, Random r)
        {
            var addIndex = r.Next(this.children.Length);

            if (children[addIndex] == null || children[addIndex].type == NodeType.EMPTY)
            {
                children[addIndex] = nodeToAdd;
                nodeToAdd.parent   = this;
            }
            else
            {
                children[addIndex].AddRandom(nodeToAdd, r);
            }
        }
示例#4
0
        public static AptNode GenerateTree(int nodeCount, Random r)
        {
            AptNode first = GetRandomNode(r);

            for (int i = 1; i < nodeCount; i++)
            {
                first.AddRandom(GetRandomNode(r), r);
            }
            while (first.AddLeaf(GetRandomLeaf(r)))
            {
                //just keep adding leaves until we can't
            }
            ;
            first.InsertWarp(r);

            return(first);
        }
示例#5
0
        public AptNode Clone()
        {
            AptNode result = new AptNode {
            };

            result.type  = type;
            result.value = value;
            if (children != null)
            {
                result.children = new AptNode[children.Length];
                for (int i = 0; i < children.Length; i++)
                {
                    result.children[i] = children[i].Clone();
                }
            }
            return(result);
        }
示例#6
0
        public static AptNode GetRandomLeaf(Random r)
        {
            //We start at 1 because 0 is EMPTY
            var      picChance = r.Next(0, 3);
            NodeType type;

            if (picChance == 0)
            {
                type = (NodeType)r.Next(1, AptNode.NUM_LEAF_TYPES);
            }
            else
            {
                type = (NodeType)r.Next(1, AptNode.NUM_LEAF_TYPES - 1);
            }

            switch (type)
            {
            case NodeType.PICTURE:
            {
                var result = new AptNode {
                    type = type, children = new AptNode[2], value = r.Next(0, 5)
                };
                result.children[0] = new AptNode {
                    type = NodeType.X
                };
                result.children[1] = new AptNode {
                    type = NodeType.Y
                };
                return(result);
            }

            case NodeType.CONSTANT:
                return(new AptNode {
                    type = type, value = (float)r.NextDouble() * 2.0f - 1.0f
                });

            default:
                return(new AptNode {
                    type = type
                });
            }
        }
示例#7
0
 public static void ReplaceNode(AptNode nodeToMutate, AptNode newNode, Random r)
 {
     nodeToMutate.type  = newNode.type;
     nodeToMutate.value = newNode.value;
     if (nodeToMutate.children != null && newNode.children != null)
     {
         for (int i = 0; i < nodeToMutate.children.Length; i++)
         {
             if (i == newNode.children.Length)
             {
                 break;
             }
             newNode.children[i] = nodeToMutate.children[i];
         }
     }
     while (newNode.AddLeaf(GetRandomLeaf(r)))
     {
     }
     nodeToMutate.children = newNode.children;
 }
示例#8
0
 public bool AddLeaf(AptNode leafToAdd)
 {
     if (children == null)
     {
         return(false);
     }
     for (int i = 0; i < children.Length; i++)
     {
         if (children[i] == null || children[i].IsEmpty())
         {
             children[i]      = leafToAdd;
             leafToAdd.parent = this;
             return(true);
         }
         else if (!children[i].IsLeaf() && children[i].AddLeaf(leafToAdd))
         {
             return(true);
         }
     }
     return(false);
 }
示例#9
0
 public void BreedWith(AptNode partner, Random r)
 {
     var(newNode, _)      = partner.GetNthNode(r.Next(0, partner.Count()));
     var(nodeToMutate, _) = this.GetNthNode(r.Next(0, this.Count()));
     ReplaceNode(nodeToMutate, newNode, r);
 }
示例#10
0
        public static AptNode GetRandomNode(Random r)
        {
            var enum_size = Enum.GetNames(typeof(NodeType)).Length;
            //-1 because we don't include warp
            var     typeNum = r.Next(AptNode.NUM_LEAF_TYPES, enum_size - 1);
            var     type    = (NodeType)typeNum;
            AptNode result;

            switch (type)
            {
            case NodeType.FBM:
            case NodeType.BILLOW:
                result = new AptNode {
                    type = type, children = new AptNode[5]
                };
                //result.children[3] = new AptNode { type = NodeType.CONSTANT, value = (float)r.NextDouble() * 7.0f + 1.0f };
                //result.children[4] = new AptNode { type = NodeType.CONSTANT, value = (float)r.NextDouble() * 2.0f + .1f };
                break;

            case NodeType.CELL1:
                result = new AptNode {
                    type = type, children = new AptNode[3]
                };
                break;

            case NodeType.ADD:
            case NodeType.SUB:
            case NodeType.MUL:
            case NodeType.DIV:
            case NodeType.ATAN2:
            case NodeType.MIN:
            case NodeType.MAX:
            case NodeType.MOD:
            case NodeType.CLIP:
                result = new AptNode {
                    type = type, children = new AptNode[2]
                };
                break;

            case NodeType.SIN:
            case NodeType.COS:
            case NodeType.ATAN:
            case NodeType.SQUARE:
            case NodeType.LOG:
            case NodeType.FLOOR:
            case NodeType.CEIL:
            case NodeType.SQRT:
            case NodeType.ABS:
            case NodeType.NEGATE:
                result = new AptNode {
                    type = type, children = new AptNode[1]
                };
                break;

            default:
                throw new Exception("GetRandomNode failed to match the switch");
            }


            return(result);
        }