{"id":298356,"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 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 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\\\" class=\\\"container text-center p-5\\\"\u003e\\n \u003cdiv class=\\\"grid\\\"\u003e\\n \u003ctemplate v-for=\\\"(row, y) in grid\\\"\u003e\\n \u003cdiv v-for=\\\"(col, x) in row\\\" @click=\\\"click(x, y)\\\" class=\\\"cell\\\" :class=\\\"cellClass(x, y)\\\"\u003e\\n \u003cimg src=\\\"b_advisor.svg\\\" v-if=\\\"col === 'b_advisor'\\\"\u003e\\n \u003cimg src=\\\"b_cannon.svg\\\" v-if=\\\"col === 'b_cannon'\\\"\u003e\\n \u003cimg src=\\\"b_chariot.svg\\\" v-if=\\\"col === 'b_chariot'\\\"\u003e\\n \u003cimg src=\\\"b_elephant.svg\\\" v-if=\\\"col === 'b_elephant'\\\"\u003e\\n \u003cimg src=\\\"b_general.svg\\\" v-if=\\\"col === 'b_general'\\\"\u003e\\n \u003cimg src=\\\"b_horse.svg\\\" v-if=\\\"col === 'b_horse'\\\"\u003e\\n \u003cimg src=\\\"b_pawn.svg\\\" v-if=\\\"col === 'b_pawn'\\\"\u003e\\n \u003cimg src=\\\"r_advisor.svg\\\" v-if=\\\"col === 'r_advisor'\\\"\u003e\\n \u003cimg src=\\\"r_cannon.svg\\\" v-if=\\\"col === 'r_cannon'\\\"\u003e\\n \u003cimg src=\\\"r_chariot.svg\\\" v-if=\\\"col === 'r_chariot'\\\"\u003e\\n \u003cimg src=\\\"r_elephant.svg\\\" v-if=\\\"col === 'r_elephant'\\\"\u003e\\n \u003cimg src=\\\"r_general.svg\\\" v-if=\\\"col === 'r_general'\\\"\u003e\\n \u003cimg src=\\\"r_horse.svg\\\" v-if=\\\"col === 'r_horse'\\\"\u003e\\n \u003cimg src=\\\"r_pawn.svg\\\" v-if=\\\"col === 'r_pawn'\\\"\u003e\\n \u003c/div\u003e\\n \u003c/template\u003e\\n \u003cimg src=\\\"./board.png\\\" class=\\\"board\\\" alt=\\\"\\\"\u003e\\n \u003c/div\u003e\\n \u003cp class=\\\"font-weight-bold\\\"\u003e{{message}}\u003c/p\u003e\\n \u003cp class=\\\"font-weight-bold\\\"\u003eturn {{chess.turn}} status {{chess.status}}\u003c/p\u003e\\n \u003cbutton class=\\\"mb-3\\\" @click=\\\"runAI\\\"\u003e{{chess.turn === 'w' ? 'White' : 'Black'}} AI\u003c/button\u003e\\n \u003cbutton class=\\\"mb-3\\\" @click=\\\"undo\\\"\u003eundo\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\u003c/body\u003e\\n\\n\u003c/html\u003e\",\"css\":\":root {\\n --size: 60px;\\n}\\n\\n.grid {\\n position: relative;\\n margin: auto;\\n width: calc(var(--size) * 9);\\n height: calc(var(--size) * 10);\\n display: grid;\\n grid-template-columns: repeat(9, 1fr);\\n border: 2px solid black;\\n transition: transform 1.5s;\\n}\\n\\n.grid \u003e div {\\n position: relative;\\n}\\n\\n.grid \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 z-index: 1;\\n}\\n\\n.cell.blue::after {\\n content: '';\\n display: block;\\n width: 100%;\\n height: 100%;\\n z-index: inherit;\\n border-radius: 50%;\\n background-color: blue;\\n}\\n\\n.cell.red::after {\\n content: '';\\n display: block;\\n width: 100%;\\n height: 100%;\\n z-index: inherit;\\n border-radius: 50%;\\n background-color: red;\\n}\\n\\n.board {\\n position: absolute;\\n top: 0;\\n left: 0;\\n right: 0;\\n bottom: 0;\\n width: 100%;\\n height: 100%;\\n z-index: -1;\\n}\",\"js\":\"class Chess {\\n\\n constructor() {\\n\\n this.status = 'playing' // 'playing', 'white win', 'black win'\\n this.turn = 'r' // 'b', 'r'\\n this.logs = []\\n this.grid = {\\n 0: { 0: 'b_chariot', 1: 'b_horse', 2: 'b_elephant', 3: 'b_advisor', 4: 'b_general', 5: 'b_advisor', 6: 'b_elephant', 7: 'b_horse', 8: 'b_chariot' },\\n 1: { 0: '', 1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '' },\\n 2: { 0: '', 1: 'b_cannon', 2: '', 3: '', 4: '', 5: '', 6: '', 7: 'b_cannon', 8: '' },\\n 3: { 0: 'b_pawn', 1: '', 2: 'b_pawn', 3: '', 4: 'b_pawn', 5: '', 6: 'b_pawn', 7: '', 8: 'b_pawn' },\\n 4: { 0: '', 1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '' },\\n 5: { 0: '', 1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '' },\\n 6: { 0: 'r_pawn', 1: '', 2: 'r_pawn', 3: '', 4: 'r_pawn', 5: '', 6: 'r_pawn', 7: '', 8: 'r_pawn' },\\n 7: { 0: '', 1: 'r_cannon', 2: '', 3: '', 4: '', 5: '', 6: '', 7: 'r_cannon', 8: '' },\\n 8: { 0: '', 1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '' },\\n 9: { 0: 'r_chariot', 1: 'r_horse', 2: 'r_elephant', 3: 'r_advisor', 4: 'r_general', 5: 'r_advisor', 6: 'r_elephant', 7: 'r_horse', 8: 'r_chariot' },\\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[fromY][fromX][0] !== this.turn) return\\n\\n if (this.grid[toY][toX] == 'b_general') this.status = 'red win'\\n if (this.grid[toY][toX] == 'r_general') this.status = 'black win'\\n\\n this._move(fromX, fromY, toX, toY)\\n this.switch()\\n\\n if (3 \u003c= fromX \u0026\u0026 fromX \u003c= 5 \u0026\u0026 this._isGeneralMetGeneral()) {\\n this.status = this.turn === 'b' ? 'black win' : 'red win'\\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.switch()\\n this.status = 'playing'\\n }\\n\\n switch() {\\n this.turn = this.turn === 'b' ? 'r' : 'b'\\n }\\n\\n getReachedBlock(fromX, fromY) {\\n let from = this.grid[fromY][fromX]\\n if (from === '' || from[0] !== this.turn || this.status !== 'playing') return []\\n\\n switch (from.split('_')[1]) {\\n case 'general': return this._general(fromX, fromY)\\n case 'advisor': return this._advisor(fromX, fromY)\\n case 'chariot': return this._chariot(fromX, fromY)\\n case 'elephant': return this._elephant(fromX, fromY)\\n case 'horse': return this._horse(fromX, fromY)\\n case 'cannon': return this._cannon(fromX, fromY)\\n case 'pawn': return this._pawn(fromX, fromY)\\n }\\n }\\n\\n _general(x, y) {\\n let steps = [\\n { x: x + 0, y: y - 1 },\\n { x: x - 1, y: y + 0 },\\n { x: x + 1, y: y + 0 },\\n { x: x + 0, y: y + 1 },\\n ]\\n return steps.filter(this._isInField).filter(this._isCover)\\n }\\n\\n _advisor(x, y) {\\n let steps = [\\n { x: x + 1, y: y + 1 },\\n { x: x + 1, y: y - 1 },\\n { x: x - 1, y: y - 1 },\\n { x: x - 1, y: y + 1 },\\n ]\\n return steps.filter(this._isInField).filter(this._isCover)\\n }\\n\\n _elephant(x, y) {\\n let steps = [\\n { x: x + 2, y: y + 2 },\\n { x: x + 2, y: y - 2 },\\n { x: x - 2, y: y - 2 },\\n { x: x - 2, y: y + 2 },\\n ]\\n return steps\\n .filter(this._isInRange)\\n .filter(this._isInSite)\\n .filter(this._isCover)\\n }\\n\\n _chariot(fromX, fromY) {\\n return this._line(fromX, fromY, 0, 1, true)\\n .concat(this._line(fromX, fromY, 1, 0, true))\\n .concat(this._line(fromX, fromY, 0, -1, true))\\n .concat(this._line(fromX, fromY, -1, 0, true))\\n }\\n\\n _horse(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)\\n }\\n\\n _cannon = (fromX, fromY) =\u003e {\\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 .concat(this._jump(fromX, fromY, 0, 1))\\n .concat(this._jump(fromX, fromY, 1, 0))\\n .concat(this._jump(fromX, fromY, 0, -1))\\n .concat(this._jump(fromX, fromY, -1, 0))\\n }\\n\\n _pawn = (x, y) =\u003e {\\n let isCrossRiver = this.turn === 'b' ? y \u003e 4 : y \u003c 5\\n let steps = [{ x, y: y + (this.turn === 'b' ? 1 : -1) }]\\n if (isCrossRiver) {\\n steps.push({ x: x + 1, y })\\n steps.push({ x: x - 1, y })\\n }\\n return steps.filter(this._isInRange)\\n }\\n\\n _move(fromX, fromY, toX, toY) {\\n this.logs.push([\\n ['remove', fromY, fromX, this.grid[fromY][fromX]],\\n ['remove', toY, toX, this.grid[toY][toX]],\\n ['create', toY, toX, this.grid[fromY][fromX]],\\n ])\\n this.grid[toY][toX] = this.grid[fromY][fromX]\\n this.grid[fromY][fromX] = ''\\n }\\n\\n _isCover = (pos) =\u003e {\\n return this.grid[pos.y][pos.x] === '' || this.grid[pos.y][pos.x][0] !== this.turn\\n }\\n\\n _isInRange = (pos) =\u003e {\\n return pos.x \u003e= 0 \u0026\u0026 pos.x \u003c 9 \u0026\u0026 pos.y \u003e= 0 \u0026\u0026 pos.y \u003c 10\\n }\\n\\n _isInSite = (pos) =\u003e {\\n return this.turn === 'b' ? pos.y \u003c= 4 : pos.y \u003e= 5\\n }\\n\\n _isInField = (pos) =\u003e {\\n if (this.turn === 'b' \u0026\u0026 pos.y \u003e= 3) return\\n if (this.turn === 'r' \u0026\u0026 pos.y \u003c= 6) return\\n return pos.x \u003e= 3 \u0026\u0026 pos.x \u003c= 5 \u0026\u0026 this._isInRange(pos)\\n }\\n\\n _line = (fromX, fromY, offsetX, offsetY, isChariot) =\u003e {\\n const steps = []\\n for (let i = 1; i \u003c 10; i++) {\\n const x = fromX + offsetX * i\\n const y = fromY + offsetY * i\\n if (!this._isInRange({ x, y })) break\\n if (this.grid[y][x] === '') steps.push({ x, y })\\n if (isChariot \u0026\u0026 this.grid[y][x][0] !== this.turn) steps.push({ x, y })\\n if (this.grid[y][x] !== '') break\\n }\\n return steps\\n }\\n\\n _jump = (fromX, fromY, offsetX, offsetY) =\u003e {\\n let count = 0\\n let steps = []\\n for (let i = 1; i \u003c 10; i++) {\\n const x = fromX + offsetX * i\\n const y = fromY + offsetY * i\\n if (!this._isInRange({ x, y })) break\\n if (this.grid[y][x] !== '') count++\\n if (count === 2 \u0026\u0026 this.grid[y][x][0] !== this.turn) steps.push({ x, y })\\n if (count === 2) break\\n }\\n return steps\\n }\\n\\n _isGeneralMetGeneral = () =\u003e {\\n let startChecking = false\\n for (let x = 3; x \u003c= 5; x++) {\\n for (let y = 0; y \u003c 10; y++) {\\n let isGneral = this.grid[y][x] === 'b_general' || this.grid[y][x] === 'r_general'\\n if (startChecking === false \u0026\u0026 isGneral) {\\n startChecking = true\\n continue\\n }\\n if (startChecking === true) {\\n if (isGneral) return true\\n if (this.grid[y][x] || y === 9) return false\\n }\\n }\\n }\\n return false\\n }\\n}\\n\\nconst chess = new Chess\\n\\nnew Vue({\\n el: '#game',\\n\\n data() {\\n return {\\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: {}, 8: {}, 9: {} },\\n logs: [],\\n }\\n },\\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.clear()\\n this.runAI()\\n } else {\\n this.clear()\\n }\\n },\\n\\n undo () {\\n this.chess.undo()\\n },\\n\\n cellClass(x, y) {\\n if (x == this.focusOn.x \u0026\u0026 y == this.focusOn.y) return 'blue'\\n return this.board[x][y] ? 'red' : ''\\n },\\n\\n clear() {\\n this.focusOn = {}\\n this.board = { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {}, 8: {}, 9: {} }\\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})\"}","created_at":"2021-09-17T20:25:29.294+08:00","updated_at":"2021-09-23T17:47:51.861+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":345,"hashid":"wdks4eme8","is_content_changed":false,"review_status":"unsubmitted","submitted_at":null,"reviewed_at":null,"advise":null,"is_deleted":false}
[{"id":6014585,"file_name":"b_general.svg","project_id":298356,"asset_id":417701,"created_at":"2021-09-17T20:26:30.360+08:00","updated_at":"2021-09-17T20:26:30.360+08:00"},{"id":6014586,"file_name":"b_horse.svg","project_id":298356,"asset_id":417702,"created_at":"2021-09-17T20:26:30.361+08:00","updated_at":"2021-09-17T20:26:30.361+08:00"},{"id":6014587,"file_name":"b_pawn.svg","project_id":298356,"asset_id":417703,"created_at":"2021-09-17T20:26:32.669+08:00","updated_at":"2021-09-17T20:26:32.669+08:00"},{"id":6014588,"file_name":"board.png","project_id":298356,"asset_id":417704,"created_at":"2021-09-17T20:26:32.671+08:00","updated_at":"2021-09-17T20:26:32.671+08:00"},{"id":6014591,"file_name":"r_chariot.svg","project_id":298356,"asset_id":417707,"created_at":"2021-09-17T20:26:33.530+08:00","updated_at":"2021-09-17T20:26:33.530+08:00"},{"id":6014592,"file_name":"r_elephant.svg","project_id":298356,"asset_id":417708,"created_at":"2021-09-17T20:26:33.532+08:00","updated_at":"2021-09-17T20:26:33.532+08:00"},{"id":6014583,"file_name":"b_chariot.svg","project_id":298356,"asset_id":417699,"created_at":"2021-09-17T20:26:29.905+08:00","updated_at":"2021-09-17T20:26:29.905+08:00"},{"id":6014584,"file_name":"b_elephant.svg","project_id":298356,"asset_id":417700,"created_at":"2021-09-17T20:26:29.907+08:00","updated_at":"2021-09-17T20:26:29.907+08:00"},{"id":6014593,"file_name":"r_general.svg","project_id":298356,"asset_id":417709,"created_at":"2021-09-17T20:26:34.303+08:00","updated_at":"2021-09-17T20:26:34.303+08:00"},{"id":6014594,"file_name":"r_horse.svg","project_id":298356,"asset_id":417710,"created_at":"2021-09-17T20:26:34.305+08:00","updated_at":"2021-09-17T20:26:34.305+08:00"},{"id":6014595,"file_name":"r_pawn.svg","project_id":298356,"asset_id":417711,"created_at":"2021-09-17T20:26:34.676+08:00","updated_at":"2021-09-17T20:26:34.676+08:00"},{"id":6014581,"file_name":"b_advisor.svg","project_id":298356,"asset_id":417697,"created_at":"2021-09-17T20:26:29.473+08:00","updated_at":"2021-09-17T20:26:29.473+08:00"},{"id":6014582,"file_name":"b_cannon.svg","project_id":298356,"asset_id":417698,"created_at":"2021-09-17T20:26:29.475+08:00","updated_at":"2021-09-17T20:26:29.475+08:00"},{"id":6014589,"file_name":"r_advisor.svg","project_id":298356,"asset_id":417705,"created_at":"2021-09-17T20:26:33.084+08:00","updated_at":"2021-09-17T20:26:33.084+08:00"},{"id":6014590,"file_name":"r_cannon.svg","project_id":298356,"asset_id":417706,"created_at":"2021-09-17T20:26:33.086+08:00","updated_at":"2021-09-17T20:26:33.086+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