{"id":776864,"student_id":10,"content":"{\"html\":\"\u003c!DOCTYPE html\u003e\\n\u003chtml lang=\\\"en\\\"\u003e\\n\\n\u003chead\u003e\\n \u003cmeta charset=\\\"UTF-8\\\"\u003e\\n \u003cmeta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"IE=edge\\\"\u003e\\n \u003cmeta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"\u003e\\n \u003ctitle\u003eDocument\u003c/title\u003e\\n \u003clink href=\\\"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css\\\" rel=\\\"stylesheet\\\"\u003e\\n \u003cscript src=\\\"https://code.jquery.com/jquery-3.6.0.slim.min.js\\\"\u003e\u003c/script\u003e\\n\u003c/head\u003e\\n\\n\u003cbody\u003e\\n \u003cdiv class=\\\"container pt-4\\\"\u003e\\n \u003cdiv class=\\\"row\\\"\u003e\\n \u003cdiv class=\\\"col-lg-7\\\"\u003e\\n \u003cdiv id=\\\"canvas-box\\\"\u003e\u003c/div\u003e\\n \u003cbutton class=\\\"btn btn-primary\\\" onclick=\\\"nextGeneration()\\\"\u003enextGeneration\u003c/button\u003e\\n \u003c/div\u003e\\n \\n \u003cdiv class=\\\"col-lg-5\\\"\u003e\\n \u003ctable class=\\\"table table-striped\\\"\u003e\\n \u003cthead\u003e\\n \u003ctr\u003e\\n \u003cth scope=\\\"col\\\"\u003e#\u003c/th\u003e\\n \u003cth scope=\\\"col\\\"\u003e活躍程度(active)\u003c/th\u003e\\n \u003cth scope=\\\"col\\\"\u003e是否存活\u003c/th\u003e\\n \u003cth scope=\\\"col\\\"\u003e前進百進度條\u003c/th\u003e\\n \u003cth scope=\\\"col\\\"\u003e前進距離(x)\u003c/th\u003e\\n \u003c/tr\u003e\\n \u003c/thead\u003e\\n \u003ctbody\u003e\\n \u003ctr\u003e\\n \u003ctd scope=\\\"col\\\"\u003e1\u003c/td\u003e\\n \u003ctd scope=\\\"col\\\"\u003e\\n \u003cdiv class=\\\"progress\\\"\u003e\\n \u003cdiv class=\\\"progress-bar progress-bar-striped\\\" style=\\\"width: 50%\\\"\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/td\u003e\\n \u003ctd scope=\\\"col\\\"\u003etrue/false\u003c/td\u003e\\n \u003ctd scope=\\\"col\\\"\u003e\\n \u003cdiv class=\\\"progress\\\"\u003e\\n \u003cdiv class=\\\"progress-bar progress-bar-striped bg-warning\\\" style=\\\"width: 50%\\\"\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/td\u003e\\n \u003ctd scope=\\\"col\\\"\u003e\\n 100m\\n \u003c/td\u003e\\n \u003c/tr\u003e\\n \u003c/tbody\u003e\\n \u003c/table\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n\\n \u003cstyle\u003e\\n #canvas-box {\\n width: 100%;\\n }\\n\\n #canvas-box \u003e canvas {\\n width: 100%;\\n }\\n\\n canvas {\\n border: 2px solid #999;\\n }\\n \u003c/style\u003e\\n \\n\u003cscript src=\\\"https://cdn.jsdelivr.net/npm/poly-decomp@0.2.1/build/decomp.min.js\\\"\u003e\u003c/script\u003e\\n\u003cscript src=\\\"https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.min.js\\\"\u003e\u003c/script\u003e\\n\u003c/body\u003e\\n\\n\u003c/html\u003e\",\"css\":\"/* 設定整個頁面內容水平置中、內寬為 30 像素:*/\\nbody {\\n text-align: center;\\n padding: 30px;\\n}\\n\\n/* 設定圖片的寬度為銀幕一半寬 */\\nimg { \\n max-width: 50%; \\n}\\n\\n/* 設定文字的顏色為淡黑色 */\\np {\\n color: #555555;\\n}\",\"js\":\"var generation = 20; // 一個世代的個數\\nvar rate = 0.15; // 變異機率\\nvar current = 0; //當前是第幾世代\\nvar cars = []; //存放車子角色\\n\\n// L09 初始調整: 每 20ms -\u003e 100ms\\nsetInterval(gameloop, 100);\\n\\n// 設定隨機地面\\nvar arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\\nfor (var i = 0; i \u003c 100; i++) {\\n arr.push(2 * Math.random() - 1);\\n}\\n// L09 初始調整: 從 1~-1, 修改為 0.6 ~-0.6\\nvar endX = createGround(arr, 0.6, -0.6);\\n\\n\\n// 產生下一個世代\\nfunction nextGeneration() {\\n \\n current += 1;\\n \\n if(current \u003e1) {\\n var parentA = cars[0].genes;\\n var parentB = cars[1].genes;\\n var parentC = cars[2].genes;\\n var parentD = cars[3].genes;\\n }\\n \\n cars.forEach(function (car) {\\n car.destory();\\n });\\n \\n cars.length = 0;\\n \\n // L09 初始調整: 20 改為 generation\\n for(var i=0; i\u003cgeneration; i++) {\\n if(current == 1) {\\n // 第一世代\\n var genes = randomGenes();\\n }\\n else {\\n // 第二世代隨機基因來源為 a, b, c, d\\n var genes = crossover(parentA, parentB, parentC, parentD);\\n }\\n \\n a = genes.slice(0, 8); \\n b = genes.slice(8, 12); \\n var car = createCar(a,b);\\n car.genes = genes;\\n cars.push(car);\\n \\n focusOnCar(car); \\n }\\n \\n}\\n\\n// 遊戲迴圈\\nfunction gameloop() {\\n var best = cars[0];\\n var count = 0;\\n \\n for(var i=0; i\u003ccars.length; i++) {\\n var car = cars[i];\\n if(car.x \u003e best.x) {\\n best = car;\\n }\\n // L09 初始調整: 將 true 移除\\n if(car.isDie) {\\n count += 1;\\n }\\n }\\n focusOnCar(best);\\n \\n // L09 初始調整: 20 改為 generation\\n if (count \u003e= generation) {\\n nextGeneration();\\n }\\n \\n updateTable(cars);\\n \\n cars.sort(function (a, b) {\\n return b.x - a.x;\\n });\\n}\\n\\n\\n// 產生車子基因\\nfunction randomGenes() {\\n var genes = [];\\n for(var i=0; i\u003c8; i++) {\\n // L09 初始調整: 將 100 調降為 70\\n genes.push(Math.random()*70+30); // 30 ~ 100\\n }\\n \\n for(var i=0; i\u003c2; i++) {\\n // 隨機車輪的位置(頂點 0~7)\\n genes.push(Math.floor(Math.random()*8));\\n // 隨機車輪的大小\\n // L09 初始調整: 將 50 調降為 30\\n genes.push(Math.random()*30+10); // 10 ~ 30\\n }\\n return genes;\\n}\\n\\n// 傳入父母基因產生新的子基因\\nfunction crossover(genA, genB, genC, genD) {\\n \\n var genes = [];\\n \\n for(var i=0; i\u003c12; i++) {\\n var rand = Math.floor(Math.random()*4) ; // 0~1 -\u003e 0, 1, 2, 3\\n \\n if(rand==0) genes.push(genA[i]); \\n if(rand==1) genes.push(genB[i]);\\n if(rand==2) genes.push(genC[i]);\\n if(rand==3) genes.push(genD[i]);\\n \\n }\\n return genes;\\n}\\n\\n\\n// 更新狀態表格\\nfunction updateTable(cars) {\\n \\n $('tbody').empty();\\n \\n for(var i=0; i\u003ccars.length; i++) {\\n var car = cars[i];\\n var distance = Math.floor(car.x - 300);\\n var s = `\u003ctr\u003e\\n \u003ctd scope=\\\"col\\\"\u003e${i+1}\u003c/td\u003e\\n \u003ctd scope=\\\"col\\\"\u003e\\n \u003cdiv class=\\\"progress\\\"\u003e\\n \u003cdiv class=\\\"progress-bar progress-bar-striped\\\" style=\\\"width: ${car.active}%\\\"\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/td\u003e\\n \u003ctd scope=\\\"col\\\"\u003e${car.isDie}\u003c/td\u003e\\n \u003ctd scope=\\\"col\\\"\u003e\\n \u003cdiv class=\\\"progress\\\"\u003e\\n \u003cdiv class=\\\"progress-bar progress-bar-striped bg-warning\\\" style=\\\"width: ${Math.floor(distance*100/endX)}%\\\"\u003e\u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/td\u003e\\n \u003ctd scope=\\\"col\\\"\u003e${distance}m\u003c/td\u003e\\n \u003c/tr\u003e`;\\n \\n $('tbody').append(s);\\n }\\n \\n}\"}","created_at":"2024-06-26T16:30:24.111+08:00","updated_at":"2024-06-26T16:31:19.782+08:00","name":"AI 設計越野車(進階預設版V2)","language":"web","screenshot":{"url":null},"parent_id":3,"plugin":"var Engine = Matter.Engine,\n Render = Matter.Render,\n Runner = Matter.Runner,\n Bodies = Matter.Bodies,\n Body = Matter.Body,\n Constraint = Matter.Constraint,\n Bounds = Matter.Bounds,\n Events = Matter.Events,\n MouseConstraint = Matter.MouseConstraint,\n Common = Matter.Common,\n Composite = Matter.Composite,\n Vertices = Matter.Vertices,\n World = Matter.World;\n\n Common.setDecomp(decomp)\n\n var engine = Engine.create()\n var render = Render.create({\n element: document.getElementById('canvas-box'),\n engine: engine,\n options: {\n hasBounds: true,\n showAngleIndicator: true,\n // showInternalEdges: true,\n background: 'white',\n wireframes: false,\n }\n })\n \nvar GD_UNIT_W = 100\nvar GD_UNIT_H = 20\n\n// 長度、變化、坡度最大\nfunction createGround(diffs, max = 1, min = -1) {\n var boxs = []\n\n var rotate = 0\n var posX = -100\n var posY = 500\n\n for (let i = 0; i \u003c diffs.length; i++) {\n var box = Bodies.rectangle(posX, posY, GD_UNIT_W, GD_UNIT_H, {\n label: 'ground',\n isStatic: true,\n angle: rotate,\n render: {\n fillStyle: '#000000AA',\n strokeStyle: 'black',\n lineWidth: 4\n },\n });\n boxs.push(box)\n\n posX += Math.cos(rotate) * GD_UNIT_W / 2\n posY += Math.sin(rotate) * GD_UNIT_W / 2\n \n rotate += diffs[i]\n if (rotate \u003e max) rotate = max\n if (rotate \u003c min) rotate = min\n \n posX += Math.cos(rotate) * GD_UNIT_W / 2\n posY += Math.sin(rotate) * GD_UNIT_W / 2\n }\n Composite.add(engine.world, [...boxs])\n return posX\n}\n\nconst LINE_WIDTH = 4 // 線框寬度\nconst STROKE_STYPE = 'black' // 線框顏色\n\nconst WHEEL_STROKE_STYPE = 'black' // 輪子線框顏色\nconst WHEEL_LINE_WIDTH = 4 // 輪子線框寬度\nconst WHEEL_FILL_COLOR = '#000000aa' // 輪子填充顏色\nconst WHEEL_FRICTION = 2 // 摩擦力\nconst WHEEL_POWER = 1 // 馬力\n\nconst BODY_DENSITY = 0.003\n\n\nconst group = Body.nextGroup(true)\n\nfunction createCar(vectors, wheelsArgs) {\n\n let car = Composite.create({ label: 'Car' })\n let instance = {}\n\n const positions = vectors.map((length, index) =\u003e {\n const angle = Math.PI * 2 * index / vectors.length\n const x = Math.floor(Math.cos(angle) * length)\n const y = Math.floor(Math.sin(angle) * length)\n return { x, y }\n })\n\n const bodyPath = positions.map(({ x, y }) =\u003e x + ' ' + y).join(' ')\n const bodyVertices = Vertices.fromPath(bodyPath)\n\n const body = Bodies.fromVertices(300, 300, bodyVertices, {\n label: 'car_body',\n collisionFilter: {\n group: group\n },\n render: {\n strokeStyle: STROKE_STYPE,\n lineWidth: LINE_WIDTH\n },\n friction: 100000,\n density: BODY_DENSITY\n })\n Composite.addBody(car, body)\n\n body.instance = instance\n \n\n\n // get body vertices\n let vertices = []\n body.parts.forEach(part =\u003e {\n part.vertices.forEach(v =\u003e {\n if (vertices.find(a =\u003e a.x == v.x \u0026\u0026 a.y == v.y)) return\n vertices.push(v)\n })\n })\n\n\n const wheels = []\n\n for (let i = 0; i \u003c wheelsArgs.length; i += 2) {\n let index = wheelsArgs[i]\n let length = wheelsArgs[i + 1]\n let x = vertices[index % vertices.length].x - body.position.x\n let y = vertices[index % vertices.length].y - body.position.y\n\n const wheel = Bodies.circle(300, 300, length, {\n label: 'wheel',\n // density: BODY_DENSITY,\n collisionFilter: {\n group: group\n },\n friction: WHEEL_FRICTION,\n render: {\n fillStyle: WHEEL_FILL_COLOR,\n strokeStyle: STROKE_STYPE,\n lineWidth: LINE_WIDTH\n },\n })\n\n const axel = Constraint.create({\n bodyB: body,\n pointB: { x, y },\n bodyA: wheel,\n stiffness: 1,\n length: 0\n })\n\n Composite.addBody(car, wheel)\n Composite.addConstraint(car, axel)\n\n wheels.push(wheel)\n }\n\n\n let count = 0\n \n instance.preX = 0\n instance.active = 100\n instance.isDie = false\n instance.speed = 0\n\n const id = setInterval(() =\u003e {\n \n count++\n \n instance.x = car.bodies[0].position.x\n instance.y = car.bodies[0].position.y\n instance.angle = car.bodies[0].angle\n\n if (count % 100 == 0) {\n wheels.forEach(w =\u003e Body.setAngularVelocity(w, WHEEL_POWER))\n\n instance.speed = instance.x - instance.preX\n instance.preX = instance.x\n\n if (instance.speed \u003e 50) {\n instance.active += 1\n } else {\n instance.active -= 5\n }\n\n if (instance.active \u003e 100) instance.active = 100\n\n if (instance.isDie == false) {\n if (instance.angle \u003e 3 || instance.angle \u003c -3 || instance.active \u003c= 0) {\n instance.isDie = true\n instance.active = 0\n instance.stop()\n }\n }\n }\n })\n\n instance.stop = function () {\n car.bodies.forEach(b =\u003e {\n Body.setStatic(b, true)\n })\n clearInterval(id)\n }\n\n instance.destory = instance.destroy = function () {\n World.remove(engine.world, car);\n clearInterval(id)\n }\n\n instance.car = car\n\n\n Composite.add(engine.world, [ car ])\n\n \n\n return instance\n}\n\n\nEvents.on(engine, 'collisionStart', function(event) {\n var pairs = event.pairs\n for (let i = 0; i \u003c pairs.length; i++) {\n var a = pairs[i].bodyA\n var b = pairs[i].bodyB\n if (a.label === 'car_body') {\n a.render.fillStyle = 'black'\n a.parent.instance.isDie = true\n a.parent.instance.active = 0\n a.parent.instance.stop()\n }\n if (b.label === 'car_body') {\n b.render.fillStyle = 'black'\n b.parent.instance.isDie = true\n b.parent.instance.active = 0\n b.parent.instance.stop()\n }\n }\n});\n\n\nRender.run(render)\nconst runner = Runner.create()\nRunner.run(runner, engine)\n\n\nvar offsetX = 0\nvar offsetY = 0\nEvents.on(render, 'beforeRender', updateView);\n\n\nvar targetCar = undefined\n\nfunction focusOnCar(car) {\n targetCar = car\n}\n\nfunction updateView() {\n if (targetCar == undefined) return\n var position = targetCar.car.bodies[0].position\n var vx = position.x - offsetX - 400\n var vy = position.y - offsetY - 300\n offsetX += vx\n offsetY += vy\n Bounds.translate(render.bounds, {\n x: vx,\n y: vy,\n });\n}","description":null,"note":null,"status":"public","like_student_ids":[],"is_featured":false,"views":43,"hashid":"9ygs54ke8","is_content_changed":false,"review_status":"unsubmitted","submitted_at":null,"reviewed_at":null,"advise":null,"is_deleted":false}
[]
橘蘋學習平台
橘蘋學習平台
我的作品
檢視專案頁
匯出
複製
匯入
刪除
下載 Android APP (APK)
截圖
前往網站頁面
1:1:1
1:1
full
用手機掃描下方 QRCode 進行安裝
或您也可以
下載 APK
到這台電腦
用手機掃描下方 QRCode 進行安裝
或您也可以
下載 APK
到這台電腦