{"id":294661,"student_id":10,"content":"{\"html\":\"\u003c!DOCTYPE html\u003e\\n\u003chtml lang=\\\"en\\\"\u003e\\n\u003chead\u003e\\n \u003cmeta charset=\\\"UTF-8\\\"\u003e\\n \u003cmeta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"\u003e\\n \u003cmeta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"ie=edge\\\"\u003e\\n \u003ctitle\u003eDocument\u003c/title\u003e\\n \u003cscript src=\\\"https://cdn.jsdelivr.net/npm/vue/dist/vue.js\\\"\u003e\u003c/script\u003e\\n \u003clink rel=\\\"stylesheet\\\" href=\\\"index.css\\\"\u003e\\n\u003c/head\u003e\\n\u003cbody\u003e\\n \u003cdiv id=\\\"game\\\"\u003e\\n \u003cdiv class=\\\"grid\\\"\u003e\\n \u003cdiv v-for=\\\"(_, y) in 8\\\" class=\\\"row\\\"\u003e\\n \u003cdiv v-for=\\\"(_, x) in 8\\\" class=\\\"col\\\" :class=\\\"getClassOf(x, y)\\\" @click=\\\"place(x, y)\\\"\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\\n \u003cp\u003e{{gameInfo}}\u003c/p\u003e\\n \u003c/div\u003e\\n \u003cscript src=\\\"othello.js\\\"\u003e\u003c/script\u003e\\n \u003cscript src=\\\"ai.js\\\"\u003e\u003c/script\u003e\\n \u003cscript\u003e\\n \\n \u003c/script\u003e\\n\u003c/body\u003e\\n\u003c/html\u003e\",\"css\":\"body {\\n text-align: center;\\n background-color: #ffc859;\\n font-family: monospace;\\n padding: 30px;\\n}\\n.grid {\\n display: inline-block;\\n border: 1px solid black;\\n}\\n.row {\\n display: flex;\\n}\\n.col {\\n position: relative;\\n width: 50px;\\n height: 50px;\\n text-align: center;\\n line-height: 50px;\\n box-sizing: border-box;\\n border: 1px solid black;\\n}\\n.col.black::after,\\n.col.white::after,\\n.col.hint::after {\\n content: '';\\n position: absolute;\\n top: 50%;\\n left: 50%;\\n width: 35px;\\n height: 35px;\\n border: 1px solid black;\\n border-radius: 50%;\\n transform: translate(-50%, -50%);\\n transition: background-color 1s step-end;\\n}\\n.col.black::after {\\n background-color: black;\\n}\\n.col.white::after {\\n background-color: white;\\n}\\n.col.hint::after {\\n border-style: dashed;\\n}\",\"js\":\"class Othello {\\n\\n constructor() {\\n this.width = 8\\n this.height = 8\\n this.grid = {}\\n this.turn = 'b'\\n this.logs = []\\n this.steps = 0\\n this.offsets = [{\\n x: 1, y: 0\\n }, {\\n x: -1, y: 0\\n }, {\\n x: 0, y: 1\\n }, {\\n x: 0, y: -1\\n }, {\\n x: 1, y: 1\\n }, {\\n x: -1, y: -1\\n }, {\\n x: 1, y: -1\\n }, {\\n x: -1, y: 1\\n }]\\n\\n this.initGrid()\\n }\\n\\n initGrid() {\\n for (let y = -2; y \u003c 10; y++) {\\n this.grid[y] = {}\\n for (let x = -2; x \u003c 10; x++) {\\n this.grid[y][x] = ''\\n }\\n }\\n this.grid[3][3] = 'b'\\n this.grid[4][4] = 'b'\\n this.grid[4][3] = 'w'\\n this.grid[3][4] = 'w'\\n }\\n\\n getValidPos() {\\n const arr = []\\n for (let x = 0; x \u003c 8; x++) {\\n for (let y = 0; y \u003c 8; y++) {\\n if (this.place(x, y)) {\\n arr.push({\\n x, y\\n })\\n this.undo()\\n }\\n }\\n }\\n return arr\\n }\\n\\n place(x, y) {\\n if (this.grid[y][x] !== '') return false\\n\\n let isValid = false\\n this.offsets.forEach(o =\u003e {\\n if (this.grid[y + o.y][x + o.x] === this.turn) return\\n if (this.fillLine(x, y, o.x, o.y)) isValid = true\\n })\\n\\n if (isValid) {\\n this.logs.unshift({\\n x, y, status: this.grid[y][x], steps: this.steps\\n })\\n this.grid[y][x] = this.turn\\n this.switch()\\n this.steps++\\n }\\n\\n return isValid\\n }\\n\\n fillLine(x, y, vx, vy) {\\n\\n while (true) {\\n x += vx\\n y += vy\\n const target = this.grid[y][x]\\n if (target === '') return false\\n if (target === this.turn) break\\n }\\n\\n while (true) {\\n x -= vx\\n y -= vy\\n const target = this.grid[y][x]\\n if (target === '') return true\\n if (target === this.turn) return true\\n if (target !== this.turn) {\\n this.logs.unshift({\\n x, y, status: this.grid[y][x], steps: this.steps\\n })\\n this.grid[y][x] = this.turn\\n }\\n }\\n }\\n\\n switch () {\\n this.turn = this.turn === 'b' ? 'w': 'b'\\n }\\n\\n undo() {\\n if (this.steps \u003e 0) {\\n this.steps--\\n while (this.logs[0] \u0026\u0026 this.logs[0].steps === this.steps) {\\n const diff = this.logs.shift()\\n this.grid[diff.y][diff.x] = diff.status\\n }\\n this.switch()\\n }\\n }\\n\\n clone() {\\n const virtual = new Othello()\\n virtual.grid = JSON.parse(JSON.stringify(this.grid))\\n virtual.logs = JSON.parse(JSON.stringify(this.logs))\\n virtual.turn = this.turn\\n virtual.steps = this.steps\\n return virtual\\n }\\n}\\n\\nfunction AI(game) {\\n const startTime = Date.now()\\n const result = alphabeta(game.clone(), 4)\\n console.log(`cost: ${Date.now() - startTime}ms`)\\n return result\\n}\\n\\nfunction alphabeta(game, deep, alpha = -Infinity, beta = Infinity) {\\n\\n let best = {\\n x: undefined,\\n y: undefined,\\n score: game.turn === 'w' ? Infinity: -Infinity\\n }\\n\\n for (let x = 0; x \u003c 8; x++) {\\n for (let y = 0; y \u003c 8; y++) {\\n if (game.place(x, y)) {\\n\\n let result = deep \u003e 0 ? alphabeta(game, deep - 1, alpha, beta): (\\n {\\n x, y, score: evaluation(game.grid)\\n }\\n )\\n\\n if (game.turn === 'w' \u0026\u0026 result.score \u003e best.score) {\\n alpha = best.score = result.score\\n best.x = x\\n best.y = y\\n }\\n\\n if (game.turn === 'b' \u0026\u0026 result.score \u003c best.score) {\\n beta = best.score = result.score\\n best.x = x\\n best.y = y\\n }\\n\\n game.undo()\\n\\n if (alpha \u003e beta) return best\\n }\\n }\\n }\\n\\n return best\\n}\\n\\nfunction evaluation(grid) {\\n let score = 0\\n for (let x = 0; x \u003c 8; x++) {\\n for (let y = 0; y \u003c 8; y++) {\\n let i = 1\\n if (x === 0 || x === 7) i *= 10\\n if (y === 0 || y === 7) i *= 10\\n if (grid[y][x] === 'b') score += i\\n if (grid[y][x] === 'w') score -= i\\n }\\n }\\n return score\\n}\\n\\nconst game = new Othello()\\n\\nnew Vue({\\n el: '#game',\\n data: {\\n game,\\n validPos: game.getValidPos(),\\n },\\n methods: {\\n getClassOf(x, y) {\\n const s = this.game.grid[y][x]\\n if (this.validPos.some(pos =\u003e pos.x === x \u0026\u0026 pos.y === y)) return ['hint']\\n if (s === 'b') return ['black']\\n if (s === 'w') return ['white']\\n },\\n place(x, y) {\\n if (this.game.place(x, y)) {\\n this.validPos = this.game.getValidPos()\\n if (this.validPos.length === 0) {\\n this.game.switch()\\n } else {\\n this.runAI()\\n }\\n }\\n },\\n runAI() {\\n setTimeout(() =\u003e {\\n this.validPos = this.game.getValidPos()\\n if (this.validPos.length === 0) return\\n\\n const result = AI(this.game)\\n game.place(result.x, result.y)\\n\\n this.validPos = this.game.getValidPos()\\n if (this.validPos.length === 0) {\\n this.game.switch()\\n this.runAI()\\n }\\n }, 3000)\\n }\\n },\\n computed: {\\n gameInfo() {\\n let w = 0\\n let b = 0\\n for (let y = 0; y \u003c 8; y++) {\\n for (let x = 0; x \u003c 8; x++) {\\n if (this.game.grid[y][x] === 'w') w++\\n if (this.game.grid[y][x] === 'b') b++\\n }\\n }\\n return `${b} : ${w}`\\n }\\n }\\n})\"}","created_at":"2021-09-03T18:08:21.324+08:00","updated_at":"2021-09-03T18:18:47.389+08:00","name":"OthelloAI 副本","language":"web","screenshot":{"url":null},"parent_id":294656,"plugin":"","description":null,"note":null,"status":"public","like_student_ids":[],"is_featured":false,"views":166,"hashid":"wdks4grwg","is_content_changed":false,"review_status":"unsubmitted","submitted_at":null,"reviewed_at":null,"advise":null,"is_deleted":false}
[{"id":5905493,"file_name":"koding.png","project_id":294661,"asset_id":302342,"created_at":"2021-09-03T18:08:21.332+08:00","updated_at":"2021-09-03T18:08:21.332+08:00"}]
橘蘋學習平台
橘蘋學習平台
我的作品
檢視專案頁
匯出
複製
匯入
刪除
下載 Android APP (APK)
截圖
前往網站頁面
1:1:1
1:1
full
用手機掃描下方 QRCode 進行安裝
或您也可以
下載 APK
到這台電腦
用手機掃描下方 QRCode 進行安裝
或您也可以
下載 APK
到這台電腦