{"id":303205,"student_id":2589,"content":"","created_at":"2021-10-06T01:37:09.012+08:00","updated_at":"2023-07-23T09:36:17.432+08:00","name":"貪吃蛇 AI - 試玩版","language":"javascript","screenshot":{"url":"https://cdn5.koding.school/uploads/project/screenshot/303205/42cc851d2df50035a437f3b546693892.jpg"},"parent_id":3,"plugin":"Game.set({ width: 1200, height: 900 })\n\nsetBackdrop('black')\n\nconst SIZE = 60\nconst W = 1200 / SIZE\nconst H = 900 / SIZE\n\nconst food = {\n x: Math.floor(Math.random() * W),\n y: Math.floor(Math.random() * H),\n}\n\n\nfunction createSnakeGame (bodies) {\n \n let snake = {\n direction: 90,\n bodies,\n }\n \n snake.move = function () {\n let head = bodies.pop()\n head.x = bodies[0].x\n head.y = bodies[0].y\n if (snake.direction === 0) head.y -= 1\n if (snake.direction === 90) head.x += 1\n if (snake.direction === 180) head.y += 1\n if (snake.direction === 270) head.x -= 1\n if (bodies.some(pos =\u003e pos.x === head.x \u0026\u0026 pos.y === head.y)) gameover()\n if (head.x \u003c 0 || head.y \u003c 0 || head.x \u003e= W || head.y \u003e= H) gameover()\n if (head.x === food.x \u0026\u0026 head.y === food.y) {\n bodies.push({ x: head.x, y: head.y })\n randomFoodPos(food, bodies)\n }\n bodies.unshift(head)\n }\n \n snake.getHead = function () {\n return bodies[0]\n }\n \n snake.getTail = function () {\n return bodies[bodies.length - 1]\n }\n \n function getFood () {\n return food\n }\n \n forever(function(){\n for (let i = 0; i \u003c bodies.length - 1; i++) {\n pen.color = 'lightgreen'\n pen.fillColor = 'lightgreen'\n let a = bodies[i]\n let b = bodies[i + 1]\n if (a.x \u003e b.x) pen.drawRect(a.x * SIZE - 10, a.y * SIZE + 10, SIZE, SIZE - 20)\n if (a.x \u003c b.x) pen.drawRect(a.x * SIZE + 10, a.y * SIZE + 10, SIZE, SIZE - 20)\n if (a.y \u003e b.y) pen.drawRect(a.x * SIZE + 10, a.y * SIZE - 10, SIZE - 20, SIZE)\n if (a.y \u003c b.y) pen.drawRect(a.x * SIZE + 10, a.y * SIZE + 10, SIZE - 20, SIZE)\n pen.drawRect(b.x * SIZE + 10, b.y * SIZE + 10, SIZE - 20, SIZE - 20)\n }\n pen.fillColor = 'red'\n pen.drawRect(food.x * SIZE + 10, food.y * SIZE + 10, SIZE - 20, SIZE - 20)\n })\n \n return {\n snake,\n getFood,\n }\n \n}\n\nfunction randomFoodPos (food, bodies) {\n let pos = []\n for (var x = 0; x \u003c 20; x++) {\n for (var y = 0; y \u003c 15; y++) {\n if (bodies.some(pos =\u003e pos.x === x \u0026\u0026 pos.y === y) == false) {\n pos.push({ x, y }) \n }\n }\n }\n if (pos.length === 0) return gameover()\n pos = pos[Math.floor(Math.random() * pos.length)]\n food.x = pos.x\n food.y = pos.y\n}\n\n\nfunction gameover () {\n stop()\n drawText('gameover', 10, 10, 'red', 60)\n}\n\n\nlet arrowSprites = []\nfor (var x = 0; x \u003c 20; x++) {\n arrowSprites[x] = []\n for (var y = 0; y \u003c 15; y++) {\n let arrow = createSprite('arrow.png')\n arrow.x = (x + 0.5) * SIZE\n arrow.y = (y + 0.5) * SIZE\n arrow.opacity = 0.5\n arrow.hidden = true\n arrowSprites[x][y] = arrow\n }\n}\n\nfunction drawNumbers (numbers) {\n forever(() =\u003e {\n for (var x = 0; x \u003c 20; x++) {\n for (var y = 0; y \u003c 15; y++) {\n if (numbers[x][y] \u003e= 0) {\n drawText(numbers[x][y], x * SIZE, y * SIZE, 'white', 24)\n }\n }\n } \n })\n}\n\nfunction drawArrows (arrows) {\n forever(() =\u003e {\n for (var x = 0; x \u003c 20; x++) {\n for (var y = 0; y \u003c 15; y++) {\n if ([0, 90, 180, 270].includes(arrows[x][y])) {\n arrowSprites[x][y].hidden = false\n arrowSprites[x][y].direction = arrows[x][y]\n } else {\n arrowSprites[x][y].hidden = true\n }\n }\n }\n })\n}\n\nvar game = createSnakeGame([\n {x: 8, y: 5},\n {x: 7, y: 5},\n {x: 6, y: 5},\n {x: 5, y: 5},\n])\n\n\n\n\nvar clock = 0;\nvar snake = game.snake; // 蛇\nvar arrows = []; // 紀錄格子數字的二維陣列\nvar numbers = []; // 紀錄箭頭方向的二維陣列\n\n// 初始化格子箭頭與格子數字的二維陣列\nfor (var x = 0; x \u003c 20; x++) {\n arrows[x] = []\n numbers[x] = []\n for (var y = 0; y \u003c 15; y++) {\n arrows[x][y] = undefined\n numbers[x][y] = undefined\n }\n}\n\n// drawArrows(arrows); //繪製箭頭\n// drawNumbers(numbers); //繪製數字\nforever(gameloop); //不斷執行遊戲迴圈\nhamilton(); //創造漢米頓圈\ncreateNumbers(); //初始化格子數字\n\nfunction gameloop () {\n clock += 1\n if (clock % 1 == 0) {\n AI()\n if (key.up) snake.direction = 0\n if (key.down) snake.direction = 180\n if (key.right) snake.direction = 90\n if (key.left) snake.direction = 270\n snake.move() \n }\n}\n\n// 產生漢米頓圈\nfunction hamilton () {\n for (let x = 0; x \u003c 20; x++) {\n for (let y = 0; y \u003c 15; y++) {\n \n if (x % 2 == 0) {\n arrows[x][y] = 180\n } else {\n arrows[x][y] = 0\n }\n \n if (y == 0) arrows[x][y] = 270\n if (y == 1 \u0026\u0026 x % 2 == 1) {\n arrows[x][y] = 90\n }\n if (y == 14 \u0026\u0026 x % 2 == 0) {\n arrows[x][y] = 90\n }\n \n arrows[0][0] = 180\n arrows[19][1] = 0\n }\n }\n}\n\n// 依據箭頭方向將數字填入格子\nfunction createNumbers () {\n var x = 0;\n var y = 0;\n for (var i = 0; i \u003c 300; i++) {\n numbers[x][y] = i\n var d = arrows[x][y]\n if (d == 0) y -= 1\n if (d == 90) x += 1\n if (d == 180) y += 1\n if (d == 270) x -= 1\n }\n}\n\n// 判斷該格子是否可以作為捷徑\nfunction isShortCut (headNum, tailNum, foodNum, nextNum) {\n if (headNum \u003e foodNum) {\n if (nextNum \u003c headNum \u0026\u0026 nextNum \u003e foodNum) return false\n } else {\n if (nextNum \u003c headNum || nextNum \u003e foodNum) return false\n }\n \n if (headNum \u003e tailNum) {\n if (nextNum \u003c headNum \u0026\u0026 nextNum \u003e tailNum - 1) return false\n } else {\n if (nextNum \u003c headNum || nextNum \u003e tailNum - 1) return false\n }\n \n return true\n}\n\nfunction AI () {\n var head = snake.getHead()\n var tail = snake.getTail()\n var food = game.getFood()\n \n if (arrows[head.x][head.y] != undefined) {\n snake.direction = arrows[head.x][head.y]\n }\n \n var headNum = numbers[head.x][head.y]\n var tailNum = numbers[tail.x][tail.y]\n var foodNum = numbers[food.x][food.y]\n \n if (head.x \u003c 19) {\n var nextNum = numbers[head.x + 1][head.y]\n if (isShortCut(headNum, tailNum, foodNum, nextNum)) {\n snake.direction = 90\n }\n }\n else if (head.x \u003e 0) {\n var nextNum = numbers[head.x - 1][head.y]\n if (isShortCut(headNum, tailNum, foodNum, nextNum)) {\n snake.direction = 270\n }\n }\n else if (head.y \u003c 14) {\n var nextNum = numbers[head.x][head.y + 1]\n if (isShortCut(headNum, tailNum, foodNum, nextNum)) {\n snake.direction = 180\n }\n }\n else if (head.y \u003e 0) {\n var nextNum = numbers[head.x][head.y - 1]\n if (isShortCut(headNum, tailNum, foodNum, nextNum)) {\n snake.direction = 0\n }\n }\n}\n","description":null,"note":null,"status":"public","like_student_ids":[],"is_featured":false,"views":69,"hashid":"2pds94645","is_content_changed":false,"review_status":"unsubmitted","submitted_at":null,"reviewed_at":null,"advise":null,"is_deleted":false}
[{"id":6153009,"file_name":"arrow.png","project_id":303205,"asset_id":424462,"created_at":"2021-10-06T01:37:43.297+08:00","updated_at":"2021-10-06T01:37:43.297+08:00"}]
橘蘋學習平台
橘蘋學習平台
我的作品
檢視專案頁
匯出
複製
匯入
刪除
下載 Android APP (APK)
截圖
1:1:1
1:1
full
幫助
用手機掃描下方 QRCode 進行安裝
或您也可以
下載 APK
到這台電腦
用手機掃描下方 QRCode 進行安裝
或您也可以
下載 APK
到這台電腦