{"id":48722,"student_id":10,"content":"var SIZE = 60;\nvar count = 0;\n\nfor (var i = 0; i \u003c SIZE; i++) {\n let car = new Car();\n car.reset(200, 50, 90);\n car.score = 0;\n car.gens = randomDNA(32);\n car.status = 'running';\n car.xx = car.x;\n car.yy = car.y;\n\n forever(function(){\n\n if (car.status != 'running') return;\n\n var outputs = NN([\n car.sensorsData[0],\n car.sensorsData[1],\n car.sensorsData[2],\n car.sensorsData[3],\n car.sensorsData[4],\n car.speed\n ], car.gens);\n \n car.turn(outputs[0]*30);\n car.speedUp(outputs[1]*30);\n \n car.score += car.speed*car.speed;\n });\n}\n\nforever(function(){\n count++;\n print(count)\n if (count == 1000 || count == 2000 || count == 3000 || count == 4000) {\n for (var i=0; i\u003ccars.length; i++) {\n var x = cars[i].xx - cars[i].x;\n var y = cars[i].yy - cars[i].y;\n if (x \u003c 50 \u0026\u0026 y \u003c 50) cars[i].score -= 10000;\n cars[i].xx = cars[i].x;\n cars[i].yy = cars[i].y;\n \n }\n }\n if (count \u003e= 5000) {\n for (var i=0; i\u003ccars.length; i++) {\n cars[i].status = 'borken'\n }\n }\n \n for (var i=0; i\u003ccars.length; i++) {\n if (cars[i].status == 'running') return;\n }\n count = 0;\n \n console.log('next generation')\n \n cars.sort(function (a, b) {\n return a.score - b.score; \n });\n \n let newGens = [];\n \n for (let i=0; i\u003cSIZE - 0; i++) {\n let rand1 = Math.floor(Math.sqrt(Math.random() * SIZE*SIZE));\n let rand2 = Math.floor(Math.sqrt(Math.random() * SIZE*SIZE));\n let newDNA = crossover(cars[rand1].gens, cars[rand2].gens);\n newGens.push(newDNA);\n }\n \n // newGens.push(cars[SIZE - 1].gens);\n // newGens.push(cars[SIZE - 2].gens);\n // newGens.push(cars[SIZE - 3].gens);\n // newGens.push(cars[SIZE - 4].gens);\n // newGens.push(cars[SIZE - 5].gens);\n // newGens.push(randomDNA(32));\n // newGens.push(randomDNA(32));\n // newGens.push(randomDNA(32));\n // newGens.push(randomDNA(32));\n // newGens.push(randomDNA(32));\n \n for (var i=0; i\u003ccars.length; i++) {\n cars[i].gens = newGens[i];\n cars[i].reset(200, 50, 90)\n cars[i].score = 0;\n }\n});\n\nfunction crossover(a, b) {\n let dna = [];\n for (let i = 0; i \u003c a.length; i++) {\n dna[i] = Math.random() \u003e 0.5 ? a[i] : b[i];\n if (Math.random() \u003c 0.04) dna[i] = Math.random() * 0.2 - 0.1; // mutation\n }\n return dna;\n}\n\n\nfunction randomDNA(length) {\n let dna = [];\n dna.fitness = 0;\n for (let i = 0; i \u003c length; i++) dna.push(Math.random() * 0.2 - 0.1);\n return dna;\n}\n\n\nfunction sigmoid(x) {\n return (Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x));\n}\n\n// input*6 hidden*4 output*2\nfunction NN(inputs, weights) {\n let w = weights;\n let i = inputs;\n let a = i[0]*w[0] + i[1]*w[1] + i[2] *w[2] + i[3]*w[3] + i[4]*w[4] + i[5]*w[5];\n let b = i[0]*w[6] + i[1]*w[7] + i[2] *w[8] + i[3]*w[9] + i[4]*w[10] + i[5]*w[11];\n let c = i[0]*w[12] + i[1]*w[13] + i[2] *w[14] + i[3]*w[15] + i[4]*w[16] + i[5]*w[17];\n let d = i[0]*w[18] + i[1]*w[19] + i[2] *w[20] + i[3]*w[21] + i[4]*w[22] + i[5]*w[23];\n\n a = sigmoid(a);\n b = sigmoid(b);\n c = sigmoid(c);\n d = sigmoid(d);\n\n let e = a*w[24] + b*w[25] + c*w[26] +d*w[27];\n let f = a*w[28] + b*w[29] + c*w[30] +d*w[31];\n\n e = sigmoid(e);\n f = sigmoid(f);\n return [e, f];\n}","created_at":"2018-11-14T17:52:43.864+08:00","updated_at":"2022-11-03T17:37:23.121+08:00","name":"self driving","language":"javascript","screenshot":{"url":"/uploads/project/screenshot/48722/272a3e997ab093ffd9429c2803b975d7.jpg"},"parent_id":2,"plugin":"let lines = [];\n\nforever(function(){\n lines.forEach(L =\u003e L.render());\n})\n\nfunction Point (x, y) {\n this.x = x || 0;\n this.y = y || 0;\n}\n\n\nfunction Line (p1, p2, size, color) {\n\n this.p1 = p1;\n this.p2 = p2;\n this.size = size || 1;\n this.color = color || 'black';\n this.a = 0;\n this.b = 0;\n \n // y = ax + b;\n // a 斜率\n // b 常數\n this.update = function () {\n this.a = (this.p1.y - this.p2.y) / (this.p1.x - this.p2.x);\n \n // 這招真的很無恥,斜率 1000 的肉眼無法看出是否垂直\n // 在計算交會點的時候就很方便,不用再判斷是否為垂直線\n if (Math.abs(this.a) === Infinity) this.a = 1000;\n \n this.b = this.p1.y - this.p1.x*this.a;\n }\n this.update();\n let self = this;\n \n forever(function(){\n self.update();\n })\n\n this.touched = function (line) {\n \n if (line.calc(this.p1.x, this.p1.y) * line.calc(this.p2.x, this.p2.y) \u003e 0) return false;\n if (this.calc(line.p1.x, line.p1.y) * this.calc(line.p2.x, line.p2.y) \u003e 0) return false;\n \n let x = (line.b - this.b)/(this.a - line.a);\n let y = this.a*x + this.b;\n return {x: x, y: y};\n }\n\n this.calc = function (x, y) {\n if (Math.abs(this.a) == Infinity) return x - this.b;\n return this.a*x + this.b - y;\n }\n\n this.render = function () {\n pen.size = this.size;\n pen.color = this.color;\n pen.drawLine(this.p1.x, this.p1.y, this.p2.x, this.p2.y);\n }\n\n lines.push(this);\n}\n\n\nvar walls = []; // 存放賽道線條\nvar cars = []; // 存放所有製造出來的車子\n\n\nfunction Car (x, y) {\n \n let width = 15; // 車體中心到四個角的距離\n let sensorLength = 1000; // 感測器的長度距離\n let friction = 0; // 摩擦力\n\n let center = createSprite('dot.jpg');\n center.x = x || 320;\n center.y = y || 240;\n center.speed = 0;\n center.status = 'pause'; // pause, running, broken\n\n let p1 = new Point();\n let p2 = new Point();\n let p3 = new Point();\n let p4 = new Point();\n center.corner = [p1, p2, p3, p4];\n \n let a = center.a = new Point();\n let b = center.b = new Point();\n let c = center.c = new Point();\n let d = center.d = new Point();\n let e = center.e = new Point();\n center.censorPoints = [a, b, c, d, e];\n \n center.sensors = [\n new Line(center, a, 0, '#00000000'),\n new Line(center, b, 0, '#00000000'),\n new Line(center, c, 0, '#00000000'),\n new Line(center, d, 0, '#00000000'),\n new Line(center, e, 0, '#00000000'),\n ]\n \n center.sensorsData = [0, 0, 0, 0, 0];\n \n center.sensors.forEach((s) =\u003e s.length = Infinity);\n\n center.border = [\n new Line(p1, p2, 2),\n new Line(p2, p3, 2),\n new Line(p3, p4, 2),\n new Line(p4, p1, 2),\n ];\n \n center.updateLines = function () {\n for (var i=0; i\u003c4; i++) {\n this.border[i].update();\n }\n for (var i=0; i\u003c5; i++) {\n this.sensors[i].update();\n }\n }\n \n center.update = function () {\n \n var self = this;\n this.border.forEach((line) =\u003e {\n if (self.status == 'broken') line.color = 'gray';\n else line.color = 'black';\n });\n \n // 更新車體的四個點座標\n var offset = [30, 150, -150, -30];\n for (var i=0; i\u003c4; i++) {\n this.direction += offset[i];\n this.stepForward(width);\n this.corner[i].x = this.x;\n this.corner[i].y = this.y;\n this.stepForward(-width);\n this.direction -= offset[i];\n }\n \n // 更新感測器的線\n var offset = [-45, -22.5, 0, 22.5, 45];\n for (var i=0; i\u003c5; i++) {\n center.direction += offset[i];\n center.stepForward(sensorLength);\n center.censorPoints[i].x = center.x;\n center.censorPoints[i].y = center.y;\n center.stepForward(-sensorLength);\n center.direction -= offset[i];\n }\n \n this.updateLines();\n };\n \n center.turn = function (direction) {\n if (this.status == 'broken') return;\n this.direction += direction;\n }\n \n center.speedUp = function (speed) {\n if (speed \u003e 0.1) speed =0.1; \n if (speed \u003c -0.1) speed = -0.1; \n this.speed += speed;\n this.speed -= friction;\n if (this.speed \u003c 1) this.speed = 1;\n if (this.speed \u003c 0) this.speed = 0;\n }\n \n center.reset = function (x, y, direction) {\n this.x = x;\n this.y = y;\n this.direction = direction;\n this.speed = 0;\n this.update();\n this.status = 'running';\n }\n \n forever(function () {\n if (center.status == 'running') {\n center.stepForward(center.speed); \n }\n \n center.update();\n });\n center.update();\n \n cars.push(center);\n return center;\n}\n\n\n\nlet outer = [\n {\"x\":114,\"y\":14},{\"x\":60,\"y\":17},{\"x\":18,\"y\":66},{\"x\":16,\"y\":136},\n {\"x\":17,\"y\":303},{\"x\":22,\"y\":446},{\"x\":57,\"y\":463},{\"x\":148,\"y\":458},\n {\"x\":216,\"y\":429},{\"x\":231,\"y\":354},{\"x\":234,\"y\":256},{\"x\":256,\"y\":220},\n {\"x\":311,\"y\":211},{\"x\":372,\"y\":228},{\"x\":374,\"y\":282},{\"x\":383,\"y\":357},\n {\"x\":376,\"y\":421},{\"x\":417,\"y\":458},{\"x\":559,\"y\":460},{\"x\":607,\"y\":432},\n {\"x\":617,\"y\":384},{\"x\":621,\"y\":285},{\"x\":617,\"y\":161},{\"x\":603,\"y\":70},\n {\"x\":552,\"y\":22},{\"x\":433,\"y\":9},{\"x\":323,\"y\":12},{\"x\":196,\"y\":11},{\"x\":114,\"y\":14}\n]\nlet inner =[ \n {\"x\":92,\"y\":76},{\"x\":73,\"y\":146},{\"x\":73,\"y\":220},{\"x\":72,\"y\":304},\n {\"x\":80,\"y\":381},{\"x\":116,\"y\":381},{\"x\":150,\"y\":350},{\"x\":167,\"y\":297},\n {\"x\":172,\"y\":229},{\"x\":178,\"y\":180},{\"x\":215,\"y\":128},{\"x\":296,\"y\":123},\n {\"x\":373,\"y\":122},{\"x\":425,\"y\":172},{\"x\":458,\"y\":217},{\"x\":461,\"y\":290},\n {\"x\":470,\"y\":358},{\"x\":486,\"y\":394},{\"x\":525,\"y\":386},{\"x\":540,\"y\":358},\n {\"x\":555,\"y\":306},{\"x\":557,\"y\":232},{\"x\":549,\"y\":160},{\"x\":528,\"y\":108},\n {\"x\":454,\"y\":78},{\"x\":362,\"y\":72},{\"x\":236,\"y\":70},{\"x\":152,\"y\":72},{\"x\":92,\"y\":76}\n]\n\nfor (var i=1; i\u003couter.length; i++) {\n let p1 = new Point(outer[i - 1].x, outer[i - 1].y);\n let p2 = new Point(outer[i].x, outer[i].y);\n let l =new Line(p1, p2, 3);\n walls.push(l)\n}\n\nfor (var i=1; i\u003cinner.length; i++) {\n let p1 = new Point(inner[i - 1].x, inner[i - 1].y);\n let p2 = new Point(inner[i].x, inner[i].y);\n let l = new Line(p1, p2, 3);\n walls.push(l);\n}\n\nforever(function(){\n \n // 檢查車子是否碰到賽道邊界,碰到則將車子狀態改成 broken\n cars.forEach(function (car) {\n for (var x=0; x\u003ccar.border.length; x++) {\n for (var y=0; y\u003cwalls.length; y++) {\n if (car.border[x].touched(walls[y])) {\n car.status = 'broken';\n return;\n }\n }\n }\n });\n \n // 更新車子感測器的數值\n cars.forEach(function (car) {\n if (car.status == 'broken') return;\n for (var x=0; x\u003ccar.sensors.length; x++) {\n \n var shortest = Infinity;\n \n for (var y=0; y\u003cwalls.length; y++) {\n let pos = car.sensors[x].touched(walls[y]);\n pen.color = 'blue'\n pen.drawCircle(pos.x, pos.y, 5);\n let length = Math.sqrt((pos.x - car.x)**2 + (pos.y - car.y)**2);\n if (length \u003c shortest) {\n shortest = Math.round(length);\n car.sensorsData[x] = shortest;\n }\n }\n }\n });\n})\n","description":null,"note":null,"status":"public","like_student_ids":[],"is_featured":false,"views":467,"hashid":"meysggk6","is_content_changed":false,"review_status":"unsubmitted","submitted_at":null,"reviewed_at":null,"advise":null,"is_deleted":false}
[{"id":873735,"file_name":"dot.jpg","project_id":48722,"asset_id":96139,"created_at":"2018-11-14T22:21:21.913+08:00","updated_at":"2018-11-14T22:21:21.913+08:00"}]
Orange Apple Learning Platform
My Projects
View Project Page
Export
Remix
Import
Delete
Download Android APP (APK)
Screenshot
繁中
简中
English
日本語
1:1:1
1:1
Full Width
Scan the QRCode below with your phone to install
Or you can
download APK
to this computer
Scan the QRCode below with your phone to install
Or you can
download APK
to this computer