{"id":679292,"student_id":2589,"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 \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\":\"\"}","created_at":"2024-01-15T21:47:39.248+08:00","updated_at":"2024-01-15T21:49:36.741+08:00","name":"用 AI 設計越野車(初階)_正課_試玩版","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 = 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}\n\nvar generation = 20; // 一個世代的個數\nvar rate = 0.15; // 變異機率\nvar current = 0; //當前是第幾世代\nvar cars = []; //存放車子角色\n\nsetInterval(gameloop, 100);\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}\nvar endX = createGround(arr, 0.6, -0.6); // 產生地形\n\n\n// // 產生下一個世代\nfunction nextGeneration() {\n\n current += 1;\n \n console.log('第' + current + '世代');\n \n cars.sort(function (a, b) {\n return b.x - a.x\n })\n\n if (cars.length \u003e 0) {\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 cars.forEach(car =\u003e car.destory());\n cars.length = 0;\n }\n\n for (var i = 0; i \u003c generation; i++) {\n if (current \u003e 1) {\n var genes = crossover(parentA, parentB, parentC, parentD);\n } else {\n var genes = randomGenes();\n }\n var a = genes.slice(0, 8);\n var b = genes.slice(8, 12);\n var car = createCar(a, b);\n focusOnCar(car);\n cars.push(car);\n car.genes = genes\n }\n}\n\n// // 遊戲迴圈\nfunction gameloop() {\n var best = cars[0];\n var count = 0;\n\n for (var i = 0; i \u003c cars.length; i++) {\n var car = cars[i];\n if (car.x \u003e best.x) {\n best = car;\n }\n if (car.isDie) {\n count += 1;\n }\n }\n focusOnCar(best);\n if (count \u003e= generation) {\n nextGeneration();\n }\n\n cars.sort(function (a, b) {\n return b.x - a.x\n })\n updateTable(cars);\n}\n\n\n// // 產生車子基因\nfunction randomGenes() {\n const genes = []\n for (var i = 0; i \u003c 8; i++) {\n genes.push(Math.random() * 70 + 30)\n }\n for (var i = 0; i \u003c 2; i++) {\n genes.push(Math.floor(Math.random() * 8)); //隨機位置\n genes.push(30 * Math.random() + 10); //隨機大小\n }\n return genes\n}\n\n\n// 傳入父母基因產生新的子基因\nfunction crossover(genA, genB, genC, genD) {\n const genes = []\n for (var i = 0; i \u003c 12; i++) {\n var rand = Math.random()\n if (rand \u003c 0.25) {\n genes.push(genA[i])\n } else if (rand \u003c 0.5) {\n genes.push(genB[i])\n } else if (rand \u003c 0.75) {\n genes.push(genC[i])\n } else {\n genes.push(genD[i])\n }\n }\n const randgenes = randomGenes()\n for (var i = 0; i \u003c 12; i++) {\n if (Math.random() \u003c rate) {\n genes[i] = randgenes[i]\n }\n }\n return genes\n}\n\n\n// 更新狀態表格\nfunction updateTable(cars) {\n $('tbody').empty()\n cars.forEach(function (car, idx) {\n var distance = Math.floor(car.x - 300)\n $('tbody').append(`\n \u003ctr\u003e\n \u003ctd scope=\"col\"\u003e${idx + 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: ${ distance * 100 / endX}%\"\u003e\u003c/div\u003e\n \u003c/div\u003e\n \u003c/td\u003e\n \u003ctd scope=\"col\"\u003e\n ${distance}m\n \u003c/td\u003e\n \u003c/tr\u003e\n `)\n })\n}\n\nnextGeneration()","description":null,"note":null,"status":"public","like_student_ids":[],"is_featured":false,"views":94,"hashid":"gk4snymm5","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
到這台電腦