{"id":298252,"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 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 \u003clink rel=\\\"stylesheet\\\" href=\\\"https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css\\\"\u003e\\n \u003clink rel=\\\"stylesheet\\\" href=\\\"css/index.css\\\"\u003e\\n \u003cscript src=\\\"https://cdn.jsdelivr.net/npm/vue/dist/vue.js\\\"\u003e\u003c/script\u003e\\n\u003c/head\u003e\\n\\n\u003cbody\u003e\\n \u003cdiv id=\\\"game\\\" style=\\\"width: 500px;\\\" class=\\\"text-center m-auto py-5\\\"\u003e\\n \u003ch1 class=\\\"py-3 text-center\\\"\u003eAlpha-Beta Algorithm\u003c/h1\u003e\\n \u003cdiv id=\\\"board\\\" class=\\\"my-3\\\" v-bind:class=\\\"{reverse: black}\\\"\u003e\\n \u003ctemplate v-for=\\\"(row, x) in grid\\\"\u003e\\n \u003cdiv v-for=\\\"(col, y) in row\\\" v-bind:style=\\\"{backgroundColor: color(x, y)}\\\" @click=\\\"click(x, y)\\\"\u003e\\n \u003cimg src=\\\"b_pawn.svg\\\" v-if=\\\"col === 'b_pawn'\\\"\u003e\\n \u003cimg src=\\\"b_rook.svg\\\" v-if=\\\"col === 'b_rook'\\\"\u003e\\n \u003cimg src=\\\"b_knight.svg\\\" v-if=\\\"col === 'b_knight'\\\"\u003e\\n \u003cimg src=\\\"b_bishop.svg\\\" v-if=\\\"col === 'b_bishop'\\\"\u003e\\n \u003cimg src=\\\"b_king.svg\\\" v-if=\\\"col === 'b_king'\\\"\u003e\\n \u003cimg src=\\\"b_queen.svg\\\" v-if=\\\"col === 'b_queen'\\\"\u003e\\n\\n \u003cimg src=\\\"w_pawn.svg\\\" v-if=\\\"col === 'w_pawn'\\\"\u003e\\n \u003cimg src=\\\"w_rook.svg\\\" v-if=\\\"col === 'w_rook'\\\"\u003e\\n \u003cimg src=\\\"w_knight.svg\\\" v-if=\\\"col === 'w_knight'\\\"\u003e\\n \u003cimg src=\\\"w_bishop.svg\\\" v-if=\\\"col === 'w_bishop'\\\"\u003e\\n \u003cimg src=\\\"w_king.svg\\\" v-if=\\\"col === 'w_king'\\\"\u003e\\n \u003cimg src=\\\"w_queen.svg\\\" v-if=\\\"col === 'w_queen'\\\"\u003e\\n \u003c/div\u003e\\n \u003c/template\u003e\\n \u003c/div\u003e\\n \u003cp class=\\\"font-weight-bold\\\"\u003e{{message}}\u003c/p\u003e\\n \u003cbutton class=\\\"mb-3\\\" @click=\\\"runAI\\\"\u003e{{chess.turn === 'w' ? 'White' : 'Black'}} AI\u003c/button\u003e\\n \u003cselect class=\\\"mb-2 form-control\\\" v-model=\\\"depth\\\"\u003e\\n \u003coption value=\\\"1\\\"\u003e1\u003c/option\u003e\\n \u003coption value=\\\"2\\\"\u003e2\u003c/option\u003e\\n \u003coption value=\\\"3\\\"\u003e3\u003c/option\u003e\\n \u003coption value=\\\"4\\\"\u003e4\u003c/option\u003e\\n \u003coption value=\\\"5\\\"\u003e5\u003c/option\u003e\\n \u003coption value=\\\"6\\\"\u003e6\u003c/option\u003e\\n \u003coption value=\\\"7\\\"\u003e7\u003c/option\u003e\\n \u003c/select\u003e\\n \u003ctable class=\\\"table table-striped\\\"\u003e\\n \u003ctr\u003e\\n \u003cth\u003e#\u003c/th\u003e\\n \u003cth\u003ecost\u003c/th\u003e\\n \u003cth\u003edepth\u003c/th\u003e\\n \u003c/tr\u003e\\n \u003ctr v-for=\\\"(log, idx) in logs\\\"\u003e\\n \u003ctd\u003e{{idx + 1}}\u003c/td\u003e\\n \u003ctd\u003e{{log.cost/1000}}s\u003c/td\u003e\\n \u003ctd\u003e{{log.depth}}\u003c/td\u003e\\n \u003c/tr\u003e\\n \u003c/table\u003e\\n \u003c/div\u003e\\n \u003cscript src=\\\"./game/chess.js\\\"\u003e\u003c/script\u003e\\n \u003cscript src=\\\"./algorithm/evaluation.js\\\"\u003e\u003c/script\u003e\\n \u003cscript src=\\\"./algorithm/alphabeta.js\\\"\u003e\u003c/script\u003e\\n \u003cscript src=\\\"./game/index.js\\\"\u003e\u003c/script\u003e\\n\u003c/body\u003e\\n\\n\u003c/html\u003e\",\"css\":\"#board {\\n margin: auto;\\n height: 500px;\\n width: 500px;\\n display: grid;\\n grid-template-columns: repeat(8, 1fr);\\n border: 2px solid black;\\n transition: transform 1.5s;\\n}\\n\\n#board \u003e div {\\n border: 2px solid black;\\n position: relative;\\n}\\n\\n#board \u003e div \u003e img {\\n width: 85%;\\n height: 85%;\\n top: 7.5%;\\n left: 7.5%;\\n display: block;\\n position: absolute;\\n transition: transform 1.5s;\\n}\",\"js\":\"class Chess {\\n \\n constructor() {\\n this.status = 'playing' // 'playing', 'white win', 'black win'\\n this.turn = 'w' // 'w', 'b'\\n this.logs = []\\n this.grid = {\\n 0: { 0: 'b_rook', 1: 'b_knight', 2: 'b_bishop', 3: 'b_king', 4: 'b_queen', 5: 'b_bishop', 6: 'b_knight', 7: 'b_rook' },\\n 1: { 0: 'b_pawn', 1: 'b_pawn', 2: 'b_pawn', 3: 'b_pawn', 4: 'b_pawn', 5: 'b_pawn', 6: 'b_pawn', 7: 'b_pawn' },\\n 2: { 0: '', 1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '' },\\n 3: { 0: '', 1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '' },\\n 4: { 0: '', 1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '' },\\n 5: { 0: '', 1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '' },\\n 6: { 0: 'w_pawn', 1: 'w_pawn', 2: 'w_pawn', 3: 'w_pawn', 4: 'w_pawn', 5: 'w_pawn', 6: 'w_pawn', 7: 'w_pawn' },\\n 7: { 0: 'w_rook', 1: 'w_knight', 2: 'w_bishop', 3: 'w_king', 4: 'w_queen', 5: 'w_bishop', 6: 'w_knight', 7: 'w_rook' },\\n }\\n }\\n\\n clone() {\\n let virtualChess = new Chess()\\n virtualChess.turn = this.turn\\n virtualChess.logs = JSON.parse(JSON.stringify(this.logs))\\n virtualChess.grid = JSON.parse(JSON.stringify(this.grid))\\n return virtualChess\\n }\\n\\n move(fromX, fromY, toX, toY) {\\n if (this.status !== 'playing') return\\n if (this.grid[fromX][fromY][0] !== this.turn) return\\n\\n if (this.grid[toX][toY] == 'w_king') this.status = 'black win'\\n if (this.grid[toX][toY] == 'b_king') this.status = 'white win'\\n\\n if ((toX === 0 || toX === 7) \u0026\u0026 this.grid[fromX][fromY].split('_')[1] === 'pawn') {\\n this.grid[fromX][fromY] = this.turn + '_queen'\\n }\\n\\n this._move(fromX, fromY, toX, toY)\\n\\n this.turn = this.turn === 'w' ? 'b' : 'w'\\n }\\n\\n getReachedBlock(fromX, fromY) {\\n let from = this.grid[fromX][fromY]\\n if (from === '' || from[0] !== this.turn || this.status !== 'playing') return []\\n\\n switch (from.split('_')[1]) {\\n case 'rook': return this._rook(fromX, fromY)\\n case 'bishop': return this._bishop(fromX, fromY)\\n case 'queen': return this._queen(fromX, fromY)\\n case 'king': return this._king(fromX, fromY)\\n case 'knight': return this._knight(fromX, fromY)\\n case 'pawn': return this._pawn(fromX, fromY)\\n }\\n }\\n\\n undo() {\\n if (this.logs.length == 0) return\\n let lastMod = this.logs.pop()\\n while (lastMod.length \u003e 0) {\\n let mod = lastMod.pop()\\n if (mod[0] === 'remove') this.grid[mod[1]][mod[2]] = mod[3]\\n if (mod[0] === 'create') this.grid[mod[1]][mod[2]] = ''\\n }\\n this.turn = this.turn === 'w' ? 'b' : 'w'\\n this.status = 'playing'\\n }\\n\\n _move(fromX, fromY, toX, toY) {\\n this.logs.push([\\n ['remove', fromX, fromY, this.grid[fromX][fromY]],\\n ['remove', toX, toY, this.grid[toX][toY]],\\n ['create', toX, toY, this.grid[fromX][fromY]],\\n ])\\n this.grid[toX][toY] = this.grid[fromX][fromY]\\n this.grid[fromX][fromY] = ''\\n }\\n\\n _rook(fromX, fromY) {\\n return this._line(fromX, fromY, 0, 1)\\n .concat(this._line(fromX, fromY, 1, 0))\\n .concat(this._line(fromX, fromY, 0, -1))\\n .concat(this._line(fromX, fromY, -1, 0))\\n }\\n\\n _bishop(fromX, fromY) {\\n return this._line(fromX, fromY, 1, 1)\\n .concat(this._line(fromX, fromY, -1, 1))\\n .concat(this._line(fromX, fromY, 1, -1))\\n .concat(this._line(fromX, fromY, -1, -1))\\n }\\n\\n _queen(fromX, fromY) {\\n return this._bishop(fromX, fromY).concat(this._rook(fromX, fromY))\\n }\\n\\n _king(x, y) {\\n let steps = [ \\n {x: x-1,y: y-1}, {x: x+0,y: y-1}, {x: x+1,y: y-1},\\n {x: x-1,y: y+0}, {x: x+1,y: y+0},\\n {x: x-1,y: y+1}, {x: x+0,y: y+1}, {x: x+1,y: y+1},\\n ]\\n return steps.filter(this._isInRange).filter(this._isCover.bind(this))\\n }\\n\\n _knight(fromX, fromY) {\\n let steps = [\\n { x: fromX + 2, y: fromY + 1 },\\n { x: fromX + 2, y: fromY - 1 },\\n { x: fromX - 2, y: fromY + 1 },\\n { x: fromX - 2, y: fromY - 1 },\\n { x: fromX + 1, y: fromY + 2 },\\n { x: fromX + 1, y: fromY - 2 },\\n { x: fromX - 1, y: fromY + 2 },\\n { x: fromX - 1, y: fromY - 2 },\\n ]\\n return steps.filter(this._isInRange).filter(this._isCover.bind(this))\\n }\\n\\n _pawn(fromX, fromY) {\\n if (fromX === 0 || fromX === 7) return []\\n let steps = []\\n\\n if (this.turn == 'b') {\\n if (this.grid[fromX + 1][fromY] === '') steps.push({ x: fromX + 1, y: fromY })\\n if (fromY !== 7 \u0026\u0026 this.grid[fromX + 1][fromY + 1][0] === 'w') steps.push({ x: fromX + 1, y: fromY + 1 })\\n if (fromY !== 0 \u0026\u0026 this.grid[fromX + 1][fromY - 1][0] === 'w') steps.push({ x: fromX + 1, y: fromY - 1 })\\n if (fromX === 1 \u0026\u0026 this.grid[fromX + 2][fromY] === '') steps.push({ x: fromX + 2, y: fromY })\\n } else {\\n if (this.grid[fromX - 1][fromY] === '') steps.push({ x: fromX - 1, y: fromY })\\n if (fromY !== 7 \u0026\u0026 this.grid[fromX - 1][fromY + 1][0] === 'b') steps.push({ x: fromX - 1, y: fromY + 1 })\\n if (fromY !== 0 \u0026\u0026 this.grid[fromX - 1][fromY - 1][0] === 'b') steps.push({ x: fromX - 1, y: fromY - 1 })\\n if (fromX === 6 \u0026\u0026 this.grid[fromX - 2][fromY] === '') steps.push({ x: fromX - 2, y: fromY })\\n }\\n return steps\\n }\\n\\n _isCover(pos) {\\n return this.grid[pos.x][pos.y] === '' || this.grid[pos.x][pos.y][0] !== this.turn\\n }\\n\\n _isInRange(pos) {\\n return pos.x \u003e= 0 \u0026\u0026 pos.x \u003c= 7 \u0026\u0026 pos.y \u003e= 0 \u0026\u0026 pos.y \u003c= 7\\n }\\n\\n _line(fromX, fromY, offsetX, offsetY) {\\n const steps = []\\n for (let i = 1; i \u003c 8; i++) {\\n const x = fromX + offsetX * i\\n const y = fromY + offsetY * i\\n if (!this._isInRange({ x, y })) break\\n if (this.grid[x][y] === '' || this.grid[x][y][0] !== this.turn) {\\n steps.push({ x, y })\\n }\\n if (this.grid[x][y] !== '') break\\n }\\n return steps\\n }\\n}\\n\\nfunction AI(turn, depth) {\\n let virtualChess = chess.clone()\\n let { from, to } = alphabeta(virtualChess, -Infinity, +Infinity, depth, turn)\\n chess.move(from.x, from.y, to.x, to.y)\\n}\\n\\nfunction alphabeta(chess, alpha, beta, depth, turn) {\\n\\n if (depth === 0) return { score: getScore(chess.grid) }\\n\\n let from = {}\\n let to = {}\\n\\n for (let x = 0; x \u003c 8; x++) {\\n for (let y = 0; y \u003c 8; y++) {\\n let arr = chess.getReachedBlock(x, y)\\n for (let i = 0; i \u003c arr.length; i++) {\\n let pos = arr[i]\\n chess.move(x, y, pos.x, pos.y)\\n let { score } = alphabeta(chess, alpha, beta, depth - 1, turn === 'b' ? 'w' : 'b')\\n\\n if (turn === 'b' \u0026\u0026 score \u003e alpha) {\\n alpha = score\\n from = { x, y }\\n to = pos\\n }\\n if (turn === 'w' \u0026\u0026 score \u003c beta) {\\n beta = score\\n from = { x, y }\\n to = pos\\n }\\n\\n chess.undo()\\n\\n if (alpha \u003e= beta) return { score: (turn === 'b' ? alpha : beta), from, to }\\n }\\n }\\n }\\n return { score: (turn === 'b' ? alpha : beta), from, to }\\n}\\n\\nfunction getScore(grid) {\\n var score = 0\\n for (let x = 0; x \u003c 8; x++) {\\n for (let y = 0; y \u003c 8; y++) {\\n if (grid[x][y] == 'b_pawn') score += 10\\n if (grid[x][y] == 'b_rook') score += 100\\n if (grid[x][y] == 'b_knight') score += 50\\n if (grid[x][y] == 'b_bishop') score += 80\\n if (grid[x][y] == 'b_queen') score += 250\\n if (grid[x][y] == 'b_king') score += 1000\\n\\n if (grid[x][y] == 'w_pawn') score -= 10\\n if (grid[x][y] == 'w_rook') score -= 100\\n if (grid[x][y] == 'w_knight') score -= 50\\n if (grid[x][y] == 'w_bishop') score -= 80\\n if (grid[x][y] == 'w_queen') score -= 250\\n if (grid[x][y] == 'w_king') score -= 1000\\n }\\n }\\n return score\\n}\\n\\n\\nconst chess = new Chess()\\n\\nnew Vue({\\n el: '#game',\\n data: {\\n chess,\\n grid: chess.grid,\\n black: false,\\n depth: 4,\\n message: 'Player first. Press the button to exchange.',\\n focusOn: {},\\n board: { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {} },\\n logs: [],\\n },\\n methods: {\\n click(x, y) {\\n x = Number(x)\\n y = Number(y)\\n\\n if (this.focusOn.x === undefined) {\\n this.chess.getReachedBlock(x, y).forEach(pos =\u003e {\\n this.board[pos.x][pos.y] = true\\n })\\n this.focusOn = { x, y }\\n } else if (this.board[x][y]) {\\n this.chess.move(this.focusOn.x, this.focusOn.y, x, y)\\n this.runAI()\\n } else {\\n this.clear()\\n }\\n },\\n\\n color(x, y) {\\n x = Number(x)\\n y = Number(y)\\n let odd = (x + y) % 2 === 0\\n\\n if (x == this.focusOn.x \u0026\u0026 y == this.focusOn.y) return 'blue'\\n\\n return this.board[x][y] ? 'red' : odd ? '#512a2a' : '#7c4c3e'\\n },\\n\\n clear() {\\n this.focusOn = {}\\n this.board = { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {} }\\n },\\n\\n runAI() {\\n this.clear()\\n this.message = 'thinking...'\\n \\n let startTime = Date.now()\\n if (window.AI !== undefined) window.AI(this.chess.turn, this.depth)\\n let costTime = Date.now() - startTime\\n \\n this.message = 'Cost: ' + (costTime / 1000) + 'sec'\\n this.logs.push({ cost: costTime, depth: this.depth })\\n if (this.chess.status !== 'playing') this.message = this.chess.status\\n }\\n }\\n})\\n\\n\"}","created_at":"2021-09-17T18:53:59.913+08:00","updated_at":"2021-09-23T17:47:38.681+08:00","name":"西洋棋","language":"web","screenshot":{"url":null},"parent_id":3,"plugin":"","description":null,"note":null,"status":"public","like_student_ids":[],"is_featured":false,"views":170,"hashid":"6rps9krez","is_content_changed":false,"review_status":"unsubmitted","submitted_at":null,"reviewed_at":null,"advise":null,"is_deleted":false}
[{"id":6011409,"file_name":"b_rook.svg","project_id":298252,"asset_id":105392,"created_at":"2021-09-17T18:58:19.229+08:00","updated_at":"2021-09-17T18:58:19.229+08:00"},{"id":6011400,"file_name":"koding.png","project_id":298252,"asset_id":302342,"created_at":"2021-09-17T18:53:59.918+08:00","updated_at":"2021-09-17T18:53:59.918+08:00"},{"id":6011406,"file_name":"b_knight.svg","project_id":298252,"asset_id":105389,"created_at":"2021-09-17T18:58:17.462+08:00","updated_at":"2021-09-17T18:58:17.462+08:00"},{"id":6011407,"file_name":"b_pawn.svg","project_id":298252,"asset_id":105390,"created_at":"2021-09-17T18:58:17.464+08:00","updated_at":"2021-09-17T18:58:17.464+08:00"},{"id":6011410,"file_name":"w_bishop.svg","project_id":298252,"asset_id":105393,"created_at":"2021-09-17T18:58:21.635+08:00","updated_at":"2021-09-17T18:58:21.635+08:00"},{"id":6011411,"file_name":"w_king.svg","project_id":298252,"asset_id":105394,"created_at":"2021-09-17T18:58:21.637+08:00","updated_at":"2021-09-17T18:58:21.637+08:00"},{"id":6011408,"file_name":"b_queen.svg","project_id":298252,"asset_id":105391,"created_at":"2021-09-17T18:58:19.227+08:00","updated_at":"2021-09-17T18:58:19.227+08:00"},{"id":6011412,"file_name":"w_knight.svg","project_id":298252,"asset_id":105395,"created_at":"2021-09-17T18:58:22.972+08:00","updated_at":"2021-09-17T18:58:22.972+08:00"},{"id":6011413,"file_name":"w_pawn.svg","project_id":298252,"asset_id":105396,"created_at":"2021-09-17T18:58:22.973+08:00","updated_at":"2021-09-17T18:58:22.973+08:00"},{"id":6011414,"file_name":"w_queen.svg","project_id":298252,"asset_id":105397,"created_at":"2021-09-17T18:58:26.857+08:00","updated_at":"2021-09-17T18:58:26.857+08:00"},{"id":6011415,"file_name":"w_rook.svg","project_id":298252,"asset_id":105398,"created_at":"2021-09-17T18:58:26.859+08:00","updated_at":"2021-09-17T18:58:26.859+08:00"},{"id":6011404,"file_name":"b_bishop.svg","project_id":298252,"asset_id":105387,"created_at":"2021-09-17T18:58:16.567+08:00","updated_at":"2021-09-17T18:58:16.567+08:00"},{"id":6011405,"file_name":"b_king.svg","project_id":298252,"asset_id":105388,"created_at":"2021-09-17T18:58:16.571+08:00","updated_at":"2021-09-17T18:58:16.571+08:00"}]
橘蘋學習平台
橘蘋學習平台
我的作品
檢視專案頁
匯出
複製
匯入
刪除
下載 Android APP (APK)
截圖
前往網站頁面
1:1:1
1:1
full
用手機掃描下方 QRCode 進行安裝
或您也可以
下載 APK
到這台電腦
用手機掃描下方 QRCode 進行安裝
或您也可以
下載 APK
到這台電腦