{"id":49205,"student_id":10,"content":"// var car = new Car(10, 20);\n// car.reset(300, 50, 90);\n\n// forever(function () {\n// if (key.right) car.turn(3);\n// if (key.left) car.turn(-3);\n// if (key.up) car.speedUp(0.05);\n// if (key.down) car.speedUp(-0.1);\n// });\n\nvar SIZE = 60; // 每個世代的個數\nvar DNA_LENGTH = 30; // DNA 的長度\nvar generation = 0; // 紀錄目前是第幾代\nvar clock = 0; // 計數器\n\nfor (var i = 0; i \u003c SIZE; i++) {\n let car = new Car(10, 20);\n car.addSensor(45);\n car.addSensor(0);\n car.addSensor(-45);\n car.reset(300, 50, 90);\n car.score = 0;\n car.speed = 0;\n car.gens = randomDNA(DNA_LENGTH);\n\n forever(function(){\n if (car.status != 'running') return;\n var outputs = NN(car.sensorsData.concat(car.speed), car.gens);\n car.turn(outputs[0]*3);\n car.speedUp(outputs[1]);\n car.score += car.speed**1.5 + car.speed;\n if (car.speed == 0) car.status = 'broken';\n });\n}\n\nforever(function(){\n clock++;\n print('generation:' + generation, 10, 10);\n for (var i=0; i\u003ccars.length; i++) {\n if (cars[i].status == 'running') return;\n }\n nextGeneration();\n});\nwhen('keyup','space', nextGeneration);\n\nfunction nextGeneration () {\n cars.sort(function (a, b) {\n return b.score - a.score;\n });\n \n var newGens = [];\n for (var i=0; i\u003cSIZE; i++) {\n var newDNA = crossover(cars[0].gens, cars[1].gens, 0.1);\n newGens.push(newDNA);\n }\n \n for (var i=0; i\u003ccars.length; i++) {\n cars[i].gens = newGens[i];\n cars[i].reset(300, 50, 90);\n cars[i].score = 0;\n cars[i].speed = 0;\n }\n \n count = 0;\n generation++;\n}\n\nfunction crossover(a, b, rate) {\n var dna = [];\n for (var i = 0; i \u003c DNA_LENGTH; i++) {\n dna[i] = Math.random() \u003e 0.5 ? a[i] : b[i];\n if (Math.random() \u003c rate) dna[i] = Math.random() * 2 - 1;\n }\n return dna;\n}\n\nfunction randomDNA(length) {\n var dna = [];\n for (var i = 0; i \u003c length; i++) dna.push(Math.random() * 2 - 1);\n return dna;\n}\n\nfunction sigmoid(x) {\n return (Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x));\n}\n\nfunction NN(inputs, weights) {\n var w = weights;\n var i = inputs;\n var a = i[0]*w[0] + i[1]*w[1] + i[2]*w[2] + i[3]*w[3];\n var b = i[0]*w[4] + i[1]*w[5] + i[2]*w[6] + i[3]*w[7];\n var c = i[0]*w[8] + i[1]*w[9] + i[2]*w[10] + i[3]*w[11];\n var d = i[0]*w[12] + i[1]*w[13] + i[2]*w[14] + i[3]*w[15];\n var e = i[0]*w[16] + i[1]*w[17] + i[2]*w[18] + i[3]*w[19];\n \n a = sigmoid(a);\n b = sigmoid(b);\n c = sigmoid(c);\n d = sigmoid(d);\n e = sigmoid(e);\n \n var f = a*w[20] + b*w[21] + c*w[22] + d*w[23];\n var g = a*w[21] + b*w[22] + c*w[23] + d*w[24];\n \n f = sigmoid(f);\n g = sigmoid(g);\n \n return [f, g];\n}","created_at":"2018-11-17T14:11:44.645+08:00","updated_at":"2019-11-08T09:03:38.195+08:00","name":"無人駕駛車 week3","language":"javascript","screenshot":{"url":"https://cdn9.koding.school/uploads/project/screenshot/49205/16eb9a08e5766159c733d0e353fe131e.jpg"},"parent_id":48758,"plugin":"function Point (x, y) {\n this.x = x || 0;\n this.y = y || 0;\n this.moveTo = function (pos) {\n this.x = pos.x;\n this.y = pos.y;\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:斜率 b:常數\n this.update = function () {\n // 計算斜率\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 // 計算常數項\n this.b = this.p1.y - this.p1.x*this.a;\n }\n \n // 取得兩線斷相交的座標,如果沒有相交就回傳 undefined\n this.touched = function (line) {\n\n if (!this.isCrossWith(line)) return; // undefined\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 // 兩線斷是否相交\n this.isCrossWith = function (line) {\n return line.calc(this.p1.x, this.p1.y) * line.calc(this.p2.x, this.p2.y) \u003c 0 \u0026\u0026\n this.calc(line.p1.x, line.p1.y) * this.calc(line.p2.x, line.p2.y) \u003c 0\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 var self = this;\n forever(function(){\n self.update();\n self.render();\n });\n \n this.update(); // 初始化更新\n}\n\n\nvar walls = []; // 存放賽道線條\nvar cars = []; // 存放所有製造出來的車子\n\n\nfunction Car (w, h) {\n \n let width = w || 15; // 車體寬度\n let height = h || 30; // 車體長度\n let throat = 0.2; // 怠速\n let Friction = 0.01 // 摩擦力\n let sensorLength = 1000; // 感測器的長度距離\n\n let center = createSprite('dot.jpg');\n center.speed = 0;\n center.displaySensor = true; // 畫面是否顯示感測線\n center.power = 0.05;\n center.status = 'running'; // running, broken\n \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 // 車體的四個邊\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.censorPoints = [];\n // 感測器的線段\n center.sensors = []\n // sensors 角度\n center.offset = [];\n // 感測器讀取的資料\n center.sensorsData = [];\n \n center.update = function () {\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 this.updateCornersPos();\n this.updateSensorsPos();\n this.updateLines();\n };\n \n center.updateCornersPos = function () {\n center.stepForward(height/2);\n center.direction += 90;\n center.stepForward(width/2);\n p1.moveTo(center);\n center.direction += 90;\n center.stepForward(height);\n p2.moveTo(center);\n center.direction += 90;\n center.stepForward(width);\n p3.moveTo(center);\n center.direction += 90;\n center.stepForward(height);\n p4.moveTo(center);\n center.direction += 90;\n center.stepForward(width/2);\n center.direction += 90;\n center.stepForward(height/2);\n center.direction += 180;\n }\n \n center.updateSensorsPos = function () {\n for (var i=0; i\u003cthis.offset.length; i++) {\n center.direction += this.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 -= this.offset[i];\n }\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\u003cthis.offset.length; i++) {\n this.sensors[i].update();\n }\n }\n \n center.turn = function (direction) {\n if (this.status == 'broken') return;\n if (direction \u003e this.speed) direction = this.speed;\n if (direction \u003c -this.speed) direction = -this.speed;\n this.direction += direction;\n }\n \n center.speedUp = function (speed) {\n if (this.status == 'broken') return;\n if (speed \u003e this.power) speed = this.power;\n this.speed += speed;\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.update();\n this.status = 'running';\n }\n \n center.addSensor = function (direction) {\n let point = new Point();\n let line = new Line(this, point, 0, '#00000000');\n this.censorPoints.push(point);\n this.sensors.push(line);\n this.offset.push(direction);\n }\n \n forever(function () {\n if (center.status == 'running') {\n center.speed -= Friction;\n if (this.speed \u003c 0) this.speed = 0;\n center.stepForward(center.speed);\n }\n center.update();\n });\n \n center.update(); // 初始化更新\n \n cars.push(center);\n return center;\n}\n\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 var target = {};\n \n for (var y=0; y\u003cwalls.length; y++) {\n let pos = car.sensors[x].touched(walls[y]);\n if (pos) {\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 target = pos;\n }\n }\n \n }\n \n car.sensorsData[x] = shortest;\n if (car.displaySensor) {\n pen.color = '#aaa';\n pen.size = 1;\n pen.drawLine(car.x, car.y, target.x, target.y);\n pen.fillColor = 'red';\n pen.drawCircle(target.x, target.y, 3);\n }\n \n }\n });\n})\n \n\n\n// let map = [[{\"x\":21,\"y\":64},{\"x\":21,\"y\":64},{\"x\":21,\"y\":44},{\"x\":36,\"y\":28},{\"x\":54,\"y\":17},{\"x\":79,\"y\":12},{\"x\":206,\"y\":12},{\"x\":324,\"y\":13},{\"x\":456,\"y\":13},{\"x\":548,\"y\":13},{\"x\":569,\"y\":19},{\"x\":588,\"y\":31},{\"x\":601,\"y\":47},{\"x\":611,\"y\":69},{\"x\":612,\"y\":88},{\"x\":612,\"y\":113},{\"x\":613,\"y\":403},{\"x\":609,\"y\":426},{\"x\":598,\"y\":446},{\"x\":581,\"y\":461},{\"x\":559,\"y\":470},{\"x\":524,\"y\":470},{\"x\":342,\"y\":470},{\"x\":272,\"y\":470},{\"x\":257,\"y\":464},{\"x\":247,\"y\":449},{\"x\":243,\"y\":432},{\"x\":243,\"y\":413},{\"x\":244,\"y\":393},{\"x\":253,\"y\":378},{\"x\":262,\"y\":364},{\"x\":275,\"y\":349},{\"x\":394,\"y\":197},{\"x\":397,\"y\":182},{\"x\":393,\"y\":169},{\"x\":376,\"y\":165},{\"x\":362,\"y\":166},{\"x\":214,\"y\":166},{\"x\":206,\"y\":171},{\"x\":203,\"y\":182},{\"x\":202,\"y\":197},{\"x\":204,\"y\":395},{\"x\":202,\"y\":417},{\"x\":194,\"y\":435},{\"x\":180,\"y\":451},{\"x\":161,\"y\":466},{\"x\":134,\"y\":469},{\"x\":107,\"y\":468},{\"x\":55,\"y\":469},{\"x\":37,\"y\":464},{\"x\":27,\"y\":451},{\"x\":19,\"y\":431},{\"x\":20,\"y\":411},{\"x\":19,\"y\":268},{\"x\":19,\"y\":102},{\"x\":21,\"y\":64}],\n// [{\"x\":123,\"y\":84},{\"x\":123,\"y\":84},{\"x\":205,\"y\":83},{\"x\":331,\"y\":84},{\"x\":461,\"y\":85},{\"x\":517,\"y\":85},{\"x\":529,\"y\":92},{\"x\":530,\"y\":103},{\"x\":529,\"y\":374},{\"x\":526,\"y\":388},{\"x\":513,\"y\":394},{\"x\":372,\"y\":394},{\"x\":359,\"y\":385},{\"x\":363,\"y\":370},{\"x\":447,\"y\":253},{\"x\":474,\"y\":217},{\"x\":482,\"y\":197},{\"x\":488,\"y\":178},{\"x\":485,\"y\":151},{\"x\":478,\"y\":128},{\"x\":462,\"y\":106},{\"x\":444,\"y\":95},{\"x\":413,\"y\":95},{\"x\":341,\"y\":94},{\"x\":216,\"y\":95},{\"x\":189,\"y\":95},{\"x\":161,\"y\":100},{\"x\":144,\"y\":113},{\"x\":133,\"y\":125},{\"x\":125,\"y\":140},{\"x\":122,\"y\":157},{\"x\":122,\"y\":176},{\"x\":121,\"y\":188},{\"x\":120,\"y\":381},{\"x\":116,\"y\":394},{\"x\":104,\"y\":395},{\"x\":99,\"y\":386},{\"x\":99,\"y\":371},{\"x\":97,\"y\":122},{\"x\":98,\"y\":101},{\"x\":123,\"y\":84}],\n// [{\"x\":110,\"y\":82},{\"x\":110,\"y\":82}]]\n\n\n\nlet map = [[{\"x\":19,\"y\":111},{\"x\":28,\"y\":64},{\"x\":86,\"y\":22},{\"x\":244,\"y\":16},{\"x\":494,\"y\":11},{\"x\":592,\"y\":83},{\"x\":631,\"y\":207},{\"x\":610,\"y\":378},{\"x\":565,\"y\":455},{\"x\":414,\"y\":465},{\"x\":132,\"y\":462},{\"x\":24,\"y\":431},{\"x\":9,\"y\":310},{\"x\":16,\"y\":161},{\"x\":19,\"y\":110}],[{\"x\":117,\"y\":122},{\"x\":456,\"y\":100},{\"x\":521,\"y\":177},{\"x\":537,\"y\":314},{\"x\":469,\"y\":371},{\"x\":303,\"y\":373},{\"x\":131,\"y\":344},{\"x\":111,\"y\":226},{\"x\":117,\"y\":122}]]\n\n// let map = [[{\"x\":5,\"y\":51},{\"x\":5,\"y\":35},{\"x\":13,\"y\":20},{\"x\":23,\"y\":12},{\"x\":41,\"y\":6},{\"x\":66,\"y\":6},{\"x\":575,\"y\":8},{\"x\":592,\"y\":10},{\"x\":605,\"y\":17},{\"x\":617,\"y\":27},{\"x\":625,\"y\":41},{\"x\":627,\"y\":56},{\"x\":627,\"y\":74},{\"x\":625,\"y\":423},{\"x\":624,\"y\":438},{\"x\":621,\"y\":453},{\"x\":612,\"y\":465},{\"x\":595,\"y\":474},{\"x\":573,\"y\":474},{\"x\":417,\"y\":473},{\"x\":404,\"y\":471},{\"x\":391,\"y\":462},{\"x\":381,\"y\":447},{\"x\":377,\"y\":432},{\"x\":375,\"y\":414},{\"x\":375,\"y\":209},{\"x\":371,\"y\":198},{\"x\":360,\"y\":193},{\"x\":344,\"y\":190},{\"x\":329,\"y\":191},{\"x\":259,\"y\":190},{\"x\":247,\"y\":193},{\"x\":238,\"y\":203},{\"x\":235,\"y\":212},{\"x\":235,\"y\":412},{\"x\":232,\"y\":426},{\"x\":223,\"y\":442},{\"x\":209,\"y\":459},{\"x\":190,\"y\":470},{\"x\":41,\"y\":470},{\"x\":26,\"y\":468},{\"x\":13,\"y\":456},{\"x\":7,\"y\":442},{\"x\":4,\"y\":424},{\"x\":5,\"y\":54}],[{\"x\":108,\"y\":374},{\"x\":108,\"y\":113},{\"x\":112,\"y\":102},{\"x\":120,\"y\":96},{\"x\":501,\"y\":97},{\"x\":509,\"y\":101},{\"x\":514,\"y\":111},{\"x\":512,\"y\":371},{\"x\":509,\"y\":381},{\"x\":500,\"y\":387},{\"x\":486,\"y\":382},{\"x\":486,\"y\":368},{\"x\":488,\"y\":122},{\"x\":482,\"y\":114},{\"x\":129,\"y\":111},{\"x\":120,\"y\":117},{\"x\":118,\"y\":371},{\"x\":112,\"y\":384},{\"x\":109,\"y\":376}]]\n// let map = [[{\"x\":2,\"y\":2},{\"x\":638,\"y\":3},{\"x\":637,\"y\":476},{\"x\":3,\"y\":476},{\"x\":3,\"y\":4}],[{\"x\":83,\"y\":76},{\"x\":550,\"y\":75},{\"x\":549,\"y\":399},{\"x\":450,\"y\":399},{\"x\":452,\"y\":77},{\"x\":170,\"y\":77},{\"x\":171,\"y\":395},{\"x\":91,\"y\":395},{\"x\":86,\"y\":76}],[{\"x\":264,\"y\":178},{\"x\":356,\"y\":181},{\"x\":356,\"y\":474},{\"x\":263,\"y\":475},{\"x\":262,\"y\":177}],[{\"x\":4,\"y\":435},{\"x\":13,\"y\":462},{\"x\":35,\"y\":474},{\"x\":218,\"y\":475},{\"x\":248,\"y\":469},{\"x\":263,\"y\":441}],[{\"x\":170,\"y\":133},{\"x\":181,\"y\":94},{\"x\":218,\"y\":78},{\"x\":407,\"y\":77},{\"x\":436,\"y\":90},{\"x\":451,\"y\":127}],[{\"x\":356,\"y\":420},{\"x\":365,\"y\":458},{\"x\":404,\"y\":476}],[{\"x\":593,\"y\":475},{\"x\":625,\"y\":467},{\"x\":637,\"y\":426}],[{\"x\":638,\"y\":51},{\"x\":628,\"y\":18},{\"x\":611,\"y\":12},{\"x\":568,\"y\":4}],[{\"x\":46,\"y\":4},{\"x\":28,\"y\":9},{\"x\":14,\"y\":22},{\"x\":6,\"y\":48},{\"x\":4,\"y\":69}]]\n// map.forEach(function (points) {\n// for (var i=1; i\u003cpoints.length; i++) {\n// let p1 = new Point(points[i - 1].x, points[i - 1].y);\n// let p2 = new Point(points[i].x, points[i].y);\n// let l = new Line(p1, p2, 3);\n// walls.push(l)\n// }\n// });\n\nfunction loadMap (map) {\n map.forEach(function (points) {\n for (var i=1; i\u003cpoints.length; i++) {\n let p1 = new Point(points[i - 1].x, points[i - 1].y);\n let p2 = new Point(points[i].x, points[i].y);\n let l = new Line(p1, p2, 3);\n walls.push(l)\n }\n }); \n}\n\nloadMap(map);\n","description":null,"note":null,"status":"public","like_student_ids":[],"is_featured":false,"views":304,"hashid":"vngsv945","is_content_changed":false,"review_status":"unsubmitted","submitted_at":null,"reviewed_at":null,"advise":null,"is_deleted":false}
[{"id":882571,"file_name":"dot.jpg","project_id":49205,"asset_id":96139,"created_at":"2018-11-17T14:11:44.658+08:00","updated_at":"2018-11-17T14:11:44.658+08:00"}]
橘蘋學習平台
橘蘋學習平台
我的作品
檢視專案頁
匯出
複製
匯入
刪除
下載 Android APP (APK)
截圖
1:1:1
1:1
full
幫助
用手機掃描下方 QRCode 進行安裝
或您也可以
下載 APK
到這台電腦
用手機掃描下方 QRCode 進行安裝
或您也可以
下載 APK
到這台電腦