{"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":337,"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"}]
Orange Apple Learning Platform
My Projects
View Project Page
Export
Remix
Import
Delete
Download Android APP (APK)
Screenshot
Open Web Site
繁中
简中
English
日本語
1:1:1
1:1
Full Width
Scan the QRCode below with your phone to install
Or you can
download APK
to this computer
Scan the QRCode below with your phone to install
Or you can
download APK
to this computer