@use PhysicalControl. @use Link. @use Stationary. @use MultiBody. @use GeneticAlgorithm. Controller myControl. PhysicalControl : myControl { + variables: population, neuron-types (list). numcreatures, generation, lastgenworstfitness (int). + to init: numcreatures = 1. #no saw-wave atm neuron-types = {"sin", "cos" "atan", "sum-threshold", "sign-of", "min", "max", "if", "mem", "log", "expt", "devide", "interpolate", "differentiate"}. for x = 0, x < numcreatures, x++: { population{x} = {}. population{x}{0} = {0,0,0}. population{x}{1} = generate-genome. } for x = 0; x < numcreatures; x++: { display creature population{x}. } + to generate-genome: genome, numchildren (list). numlegs (int). root (object). genome{0} = make-root. #genome can have 1-4 legs, with a higher chance of an even number numchildren = {1, 2, 2, 3, 4, 4}. numlegs = numchildren{random[|numchildren|]}. for x = 0; x < numlegs; x++: { genome{x} = make-child genome{0} add-child with-child genome{x}. } + to make-root: length, height, width (int). neurons (list). length = random[5.0]. height = random[5.0]. width = random[5.0]. number-of-neurons = random[3]. for x = 0; x < number-of-neurons; x++: { neurons{x} = neurons-types[random[|neuron-types|]]. } return Node init is-root? 1 with-length length with-height height with-width width with-neurons neurons connects-p-at {} connects-c-at {} with-children {}. + to make-child: length, height, width (int). neurons, parent-connection (list). length = random[4.0]. height = random[4.0]. width = random[4.0]. number-of-neurons = random[3]. for x = 0; x < number-of-neurons; x++: { neurons{x} = neurons-types[random[|neuron-types|]]. } parent-connection = {random[length], random[height], random[width]}. return Node init is-root? 0 with-length length with-height height with-width width with-neurons neurons connects-p-at parent-connection connects-c-at {} with-children {}. + to display creature c: size, color, parts (list). shape (object). nodes = copylist c{1} size = (neurons{x} get-length, neurons{x} get-width, neurons{x} get-height). shape = (new Cube init-with size legSize). color = random[(1.0, 1.0, 1.0)]. # call add-parts } + to add-parts to-multi body (object) with-nodes nodes (list): size, color (list). shape, leg (object). if nodes{0} get-children == 0: { size = (nodes{0} get-length, nodes{0} get-width, nodes{0} get-height). shape = (new Cube init-with size size). color = random[(1.0, 1.0, 1.0)]. leg = new Link. leg set-shape to shape. leg set-color to color. return leg } else { size = (nodes{0} get-length, nodes{0} get-width, nodes{0} get-height). shape = (new Cube init-with size size). color = random[(1.0, 1.0, 1.0)]. leg = new Link. leg set-shape to shape. leg set-color to color. children = nodes{0} get-children. for x = 0; x < |children|; x++: { # recursive call } } } Object: Node { + variables: # length = x, height = y, width = z. # if root? == 1, Node is a root. root?, length, width, height (int). connect-to-parent, connect-to-children, children, neurons (list). + to init is-root? r (int) with-length l (int) with-height h (int) with-width w (int) with-neurons n (list) connects-p-at p (list) connents-c-at c (list) with-children child (list): root? = r. length = l. width = w. height = h. connect-to-parent = p. connect-to-children = c. neurons = n. children = child. + to add-child with-child child (object): push child onto children. add-connection. + to add-connection: new-connection = {rand[length], rand[height], rand[width]} push new-connection onto connect-to-children. + to remove-child child-id id (int): remove children {id}. remove connect-to-children {id}. + to get-children: return children. + to get-neurons: return neurons. + to get-length: return length. + to get-height: return height. + to get-width: return width. } Object : CreatureGA { + variables: modifier (float). memory, last (list). + to init: + to get-effectors inputs input (list) neurons node (list): last = input. effectors = [] while |nodes| > 0: { if nodes[0] == "sin": { x = sin num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "cos": { x = cos num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "atan": { x = atan num input[0] num input[1] num input[2]. pi = 3.14159265. x = x/pi. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "sum-threshold": { x = sum-threshold num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "sign-of": { x = sign-of num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "min": { x = min num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "max": { x = max num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "if": { x = if num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "mem": { x = mem num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "saw-wave": { x = saw-wave num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "log": { x = log num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "expt": { x = expt num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "devide": { x = devide num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "interpolate": { x = interpolate num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } else if nodes[0] == "differentiate": { x = differentiate num input[0] num input[1] num input[2]. input[random[2]] = x. unprepend nodes. } } + to avg num a (int) num b (int) num c (int): return (a+b+c)/3. + to sin num a (int) num b (int) num c (int): sin(avg num a num b num c). + to cos num a (int) num b (int) num c (int): cos(avg num a num b num c). + to atan num a (int) num b (int) num c (int): #because avg is always between [-1,1], atan does not need scaling atan(avg num a num b num c). + to sum-threshold num a (int) num b (int) num c (int): if (a+b)>=c: { return 1. } return -1. + to sign-of num a (int) num b (int) num c (int): if (a*b*c)>=0: { return 1. } return -1. + to min num a (int) num b (int) num c (int): return min(a,b,c). + to max num a (int) num b (int) num c (int): return max(a,b,c). + to if num a (int) num b (int) num c (int): if a>=0: { return b. } return c. + to mem num a (int) num b (int) num c (int): inputs = {a,b,c} push inputs[randon[2]] onto memory. return unprepend memory. + to saw-wave num a (int) num b (int) num c (int): + to log num a (int) num b (int) num c (int): #scaled [-1,1] x = avg num a num b num c if x <= 0 { return -1. } else if log(x)/log(10) > 1 { return 1. } return log(x)/log(10). + to expt num a (int) num b (int) num c (int): #scaled [-1,1] e = 2.71828183. return e^(avg num a num b num c)/e. + to devide num a (int) num b (int) num c (int): #scaled [-1,1] if (b-c) > 0.00001 or (b-c) < -0.00001: { return 0. } if (b-c)==0: { return (a/.0000001)/10000000. } if (a/(b-c))/10000000 > 1: { return 1. } return (a/(b-c))/10000000. + to interpolate num a (int) num b (int) num c (int): x = 0.5*(c+1). return (a*x)+b*(1-x). + to differentiate num a (int) num b (int) num c (int): return (avg num a num b num c) - (avg num last[0] num last[1] num last[2]). }