Attempting to build these circuits is highly unadvisable.
Log in to post a comment.
const branchingChance = 1.0; // min=0.01, max=1.0, step=0.01 const branchingMultiplier = 1; // min=0, max=1, step=0.01 const branchingDeathChance = 0.6; // min=0.01, max=1.0, step=0.01 const multiLeadComponentChance = 1.0; // min=0.01, max=1.0, step=0.01 const twoLeadComponentChance = 1.0; // min=0.01, max=1.0, step=0.01 const lineChance = 0.2; // min=0.01, max=1.0, step=0.01 const turnChance = 0.2; // min=0.01, max=1.0, step=0.01 const energyLossMultiplier = 0.5; // min=0.01, max=1.0, step=0.01 Turtle.prototype.drawResistor = function() { const angle = 60; const connector = 4*scale; this.pendown(); this.forward(connector); this.left(angle); this.forward(1*scale); this.right(2*angle); this.forward(2*scale); this.left(2*angle); this.forward(2*scale); this.right(2*angle); this.forward(2*scale); this.left(2*angle); this.forward(2*scale); this.right(2*angle); this.forward(2*scale); this.left(2*angle); this.forward(1*scale); this.right(angle); this.forward(connector); this.penup(); this.energy *= 0.95; } Turtle.prototype.drawInductor = function() { const connector = 4*scale; const radius = 1.5*scale; this.pendown(); this.forward(connector); this.penup(); for (let i = 0; i < 3; i++) { this.left(90); this.pendown(); this.circle(radius, 180, 40); this.penup(); this.left(90); } this.pendown(); this.forward(connector); this.penup(); this.energy *= 0.9; } Turtle.prototype.drawDiode = function() { const connector = 4*scale; const base = 1.5*scale; const length = 2.5*scale; const side = Math.sqrt(base*base+length*length); const a = Math.atan(length/base)*180/Math.PI; this.pendown(); this.forward(connector); this.left(90); this.forward(base); this.right(180-a); this.forward(side); this.left(90-a); this.right((a-270)%360); this.forward(side); this.right(180-a); this.forward(base); this.penup(); this.right(90); this.forward(length); this.left(90); this.backward(base); this.pendown(); this.forward(2*base); this.penup(); this.backward(base); this.right(90); this.pendown(); this.forward(connector); this.energy *= 0.97; this.penup(); } Turtle.prototype.drawReverseDiode = function () { this.penup(); this.forward(10.5*scale); const helper = this.clone(); helper.seth((this.h()-180)%360); helper.drawDiode(); } Turtle.prototype.drawZenerDiode = function() { const connector = 4*scale; const base = 1.5*scale; const length = 2.5*scale; const side = Math.sqrt(base*base+length*length); const a = Math.atan(length/base)*180/Math.PI; this.pendown(); this.forward(connector); this.left(90); this.forward(base); this.right(180-a); this.forward(side); this.left(90-a); this.right((a-270)%360); this.forward(side); this.right(180-a); this.forward(base); this.penup(); this.right(90); this.forward(length); this.left(90); this.backward(base); this.left(60); this.backward(base/2); this.pendown(); this.forward(base/2); this.right(60); this.forward(2*base); this.left(60); this.forward(base/2); this.penup(); this.backward(base/2); this.right(60); this.backward(base); this.right(90); this.pendown(); this.forward(connector); this.energy *= 0.97; this.penup(); } Turtle.prototype.drawRectifier = function() { const connector = 4*scale; let newTurtles = []; this.pendown(); this.forward(connector); const helper = this.clone(); this.left(45); this.drawDiode(); const a = this.clone(); a.left(45); a.forward(connector); a.drawLine(); newTurtles.push(a); this.right(90); this.drawDiode(); this.left(45); this.pendown(); this.forward(connector); this.penup(); helper.right(45); helper.drawDiode(); const b = helper.clone(); b.right(45); b.forward(connector); b.drawLine(); newTurtles.push(b); helper.left(90); helper.drawDiode(); this.energy *= 0.1; newTurtles = newTurtles.map(t => { t.energy = this.energy / 2; return t; }) return newTurtles; } Turtle.prototype.drawTransistor = function() { const connector = 8*scale; const radius = 4*scale; this.energy *= 0.5; this.pendown(); this.forward(connector); this.right(75); this.forward(radius/1.5); this.left(75); this.penup(); this.backward(1.5*scale); this.pendown(); this.forward(1.5*scale+radius/4); const helper = this.clone(); this.forward(1.5*scale+radius/4); this.penup(); this.backward(1.5*scale); this.left(75); this.pendown(); this.forward(radius/1.5); this.right(75); this.forward(connector); this.penup(); helper.right(90); helper.forward(radius/2); helper.right(90); helper.circle(radius); helper.left(90); helper.forward(connector); return [helper.spawn(1)]; } Turtle.prototype.drawOpAmp = function() { const connector = 6*scale; const base = 3*scale; const length = 5*scale; const side = Math.sqrt(base*base+length*length); const a = Math.atan(length/base)*180/Math.PI; const h = Math.round(this.h())%360; this.energy *= 0.8; this.pendown(); if (this.h() === 180) { this.left(45); this.forward(connector); this.left(45); this.forward(connector); this.left(45); } this.edgeRotate(0); this.seth(0); this.forward(connector); this.left(90); this.penup(); this.forward(base/2); this.right(180-a); this.pendown(); this.forward(side); this.left(90-a); const newTurtle = this.clone(); newTurtle.forward(connector); this.right((a-270)%360); this.forward(side); this.right(180-a); this.forward(2*base); this.penup(); this.backward(3*base/2); this.pendown(); this.left(90); this.forward(connector); this.penup(); return [newTurtle]; } Turtle.prototype.drawCapacitor = function() { const connector = 4*scale; const base = 3*scale; const gap = 1*scale; this.pendown(); this.forward(connector); this.left(90); this.penup(); this.backward(base/2); this.pendown(); this.forward(base); this.penup(); this.right(90); this.forward(gap); this.left(90); this.pendown(); this.backward(base); this.penup(); this.forward(base/2); this.right(90); this.pendown(); this.forward(connector); this.penup(); this.energy *= 0.9; } Turtle.prototype.drawGround = function() { const connector = 4*scale; const base = 3*scale; const gap = 1*scale; this.pendown(); this.forward(connector); this.edgeRotate(90); this.seth(90); this.forward(base); this.penup(); this.left(90); this.backward(base/2); const x = this.x(); for (let i = 0; i < 3; i++) { this.forward(i*base/5); this.pendown(); this.forward(base-i*2*base/5); this.penup(); this.setx(x); this.sety(this.y()+gap); } this.energy = 0; } Turtle.prototype.drawSignalGround = function() { const connector = 4*scale; const base = 1.5*scale; const gap = 1*scale; const length = 2.5*scale; const side = Math.sqrt(base*base+length*length); const a = Math.atan(length/base)*180/Math.PI; this.pendown(); this.forward(connector); this.edgeRotate(90); this.seth(90); this.forward(connector); this.left(90); this.forward(base); this.right(180-a); this.forward(side); this.left(90-a); this.right((a-270)%360); this.forward(side); this.right(180-a); this.forward(base); this.right(90); this.penup(); this.forward(length); this.energy = 0; } Turtle.prototype.drawVcc = function() { const connector = 4*scale; const base = 1.5*scale; const gap = 1*scale; const length = 2.5*scale; const side = Math.sqrt(base*base+length*length); const a = Math.atan(length/base)*180/Math.PI; this.pendown(); this.forward(connector); this.edgeRotate(270); this.seth(270); this.forward(connector); this.penup(); this.left(90); this.forward(base); this.pendown(); this.right(180-a); this.forward(side); this.left(90-a); this.right((a-270)%360); this.forward(side); this.right(180-a); this.penup(); this.forward(base); this.right(90); this.pendown(); this.forward(length); this.penup(); this.energy = 0; } Turtle.prototype.drawInput = function() { const connector = 2*scale; const base = scale; this.pendown(); this.forward(connector); this.edgeRotate(180); this.seth(180); this.forward(connector); this.penup(); this.left(90); this.forward(base/2); this.right(90); this.pendown(); this.forward(base); this.circle(base); this.penup(); this.energy = 0; } Turtle.prototype.drawOutput = function() { const connector = 2*scale; const length = 2*scale; const base = scale; const side = Math.sqrt(base*base+length*length); const a = Math.atan(length/base)*180/Math.PI; this.pendown(); this.forward(connector); this.edgeRotate(0); this.seth(0); this.forward(connector); this.penup(); this.left(90); this.forward(base); this.pendown(); this.right(180-a); this.forward(side); this.left(90-a); this.right((a-270)%360); this.forward(side); this.right(180-a); this.penup(); this.forward(base); this.right(90); this.pendown(); this.forward(length); this.penup(); this.energy = 0; } Turtle.prototype.drawLine = function() { const lut = [4, 7, 9]; const len = lut[Math.floor(Math.random()*lut.length)]*scale; this.penup(); this.forward(len); if (Math.abs(this.y()) > 80 || Math.abs(this.x()) > 70) { this.backward(len); this.end(); } else { this.backward(len); this.pendown(); this.forward(len); this.penup(); this.energy *= 0.99; } } Turtle.prototype.drawConnector = function() { const size = 6; const x = this.x(); const y = this.y(); for (let n = 1; n < size; n++) { this.left(90); this.forward(n/size); this.right(90); this.pendown(); this.circle(n/size); this.penup(); this.left(90); this.backward(n/size); this.right(90); } this.goto(x,y); this.penup(); } Turtle.prototype.edgeRotate = function(dir) { const connector = 4*scale; const h = Math.round(this.h())%360; const left = this.x() > 0 ? this.left : this.right; const right = this.x() > 0 ? this.right : this.left; let angle = (h-(dir+360))%360; for (let i = 0; angle > 0; i++, angle-=45) { if (dir > 270 || dir < 90) { left.call(this, 45); } else { right.call(this, 45); } this.forward(i%2==1 ? 2*connector : connector); } } Turtle.prototype.spawn = function(n) { const newTurtle = this.clone(); newTurtle.right(n%2==0 ? 90 : 270); newTurtle.drawLine(); newTurtle.energy = this.energy / (1+Math.random()); return newTurtle; } Turtle.prototype.end = function() { const h = Math.round(this.h())%360; if (h === 270) { this.topEnders[Math.floor(Math.random()*this.topEnders.length)].call(this); } else if (h === 0) { this.rightEnders[Math.floor(Math.random()*this.rightEnders.length)].call(this); } else if (h === 90) { this.bottomEnders[Math.floor(Math.random()*this.bottomEnders.length)].call(this); } else if (h === 180) { this.leftEnders[Math.floor(Math.random()*this.leftEnders.length)].call(this); } else if (this.y() > 0) { if (this.y() < 60 && this.x() > 60) { this.rightEnders[Math.floor(Math.random()*this.rightEnders.length)].call(this); } else { this.bottomEnders[Math.floor(Math.random()*this.bottomEnders.length)].call(this); } } else { if (this.y() > -60 && this.x() < -60) { this.leftEnders[Math.floor(Math.random()*this.leftEnders.length)].call(this); } else { this.topEnders[Math.floor(Math.random()*this.topEnders.length)].call(this); } } } Turtle.prototype.fns = [ Turtle.prototype.drawResistor, Turtle.prototype.drawInductor, Turtle.prototype.drawDiode, Turtle.prototype.drawReverseDiode, Turtle.prototype.drawZenerDiode, Turtle.prototype.drawCapacitor, ]; Turtle.prototype.spawners = [ Turtle.prototype.drawRectifier, Turtle.prototype.drawTransistor, Turtle.prototype.drawOpAmp, ]; Turtle.prototype.leftEnders = [ Turtle.prototype.drawInput, ]; Turtle.prototype.rightEnders = [ Turtle.prototype.drawOutput, ]; Turtle.prototype.topEnders = [ Turtle.prototype.drawVcc, ]; Turtle.prototype.bottomEnders = [ Turtle.prototype.drawGround, Turtle.prototype.drawSignalGround, ] let scale = 1; const initialEnergy = 1000; const maxNodes = 1000; Canvas.setpenopacity(1); const topTurtle = new Turtle(); topTurtle.energy = initialEnergy; topTurtle.penup(); topTurtle.goto(0,0); topTurtle.seth(Math.random() > 0.5 ? 270 : 180); const bottomTurtle = topTurtle.clone(); bottomTurtle.seth((bottomTurtle.h()+180)%360) let turtles = [topTurtle,bottomTurtle]; let livingTurtles = []; let newTurtles = []; let skipped = false; let nodes = 0; function walk(i) { newTurtles = livingTurtles = []; turtles.map((turtle, idx) => { if (turtle.energy < 1 && turtle.energy > 0) { if (turtle.y() > 0) { turtle.drawGround(); } else { turtle.drawVcc(); } } if (turtle.energy < 1 || turtle.x() > 100 || turtle.y() > 100 || turtle.x() < -100 || turtle.y() < -100) { turtles[idx] = null; } else { skipped = false; // Branching if (Math.random()*branchingChance > 0.99525) { turtle.drawConnector(); for (let h = branchingMultiplier+Math.round(Math.random()); h > 0; h--) { newTurtles.push(turtle.spawn(h)); } // Sometimes, kill the original turtle, so a T-connection is created. if (newTurtles.length === 2 && Math.random() >= branchingDeathChance) { turtles[idx] = null; } } // Components with more than 2 leads else if (i > 5 && Math.random()*multiLeadComponentChance > 0.9925) { const possiblyTurtles = turtle.spawners[Math.floor(Math.random()*turtle.spawners.length)].call(turtle); if (!!possiblyTurtles && possiblyTurtles.length) { newTurtles = newTurtles.concat(possiblyTurtles); } nodes++; } // Components else if (i > 1 && Math.random()*twoLeadComponentChance > 0.95) { const possiblyTurtles = turtle.fns[Math.floor(Math.random()*turtle.fns.length)].call(turtle); if (!!possiblyTurtles && possiblyTurtles.length) { newTurtles = newTurtles.concat(possiblyTurtles); } nodes++; } // Voltages and grounds else if (i > 15 && (Math.abs(turtle.y()) > 70 || Math.abs(turtle.x()) > 70)) { turtle.end(); nodes++; } // Lines else if (Math.random() <= lineChance) { turtle.drawLine(); } else { skipped = true; } // Turning if (!skipped && Math.random() < turnChance) { Math.random() > 0.5 ? turtle.left((i%5!==0 && Math.random() < 0.9) ? 45 : 90) : turtle.right((i%7!==0 && Math.random() < 0.9) ? 45 : 90); } turtle.energy *= energyLossMultiplier; } }) livingTurtles = turtles.filter(t => t != null); turtles = livingTurtles.concat(newTurtles); return nodes < maxNodes && turtles.length != 0; }