摘要:廢話不多說(shuō)上代碼完整項(xiàng)目地址項(xiàng)目地址棋盤樣式棋盤元素初始化初始化角色黑旗子白旗是否已分出勝負(fù)走棋記錄當(dāng)前步清空棋子和事件初始化棋盤矩陣刻畫棋盤棋盤網(wǎng)格刻畫棋子每次落子結(jié)束都要判斷輸贏落子如果點(diǎn)擊的是棋子則中斷空的棋位才可落子落
廢話不多說(shuō)上代碼!
完整項(xiàng)目地址:GitHub項(xiàng)目地址
class Gobang { constructor(options) { this.options = options this.gobang = document.getElementById(options.canvas || "gobang") this.chessboard = this.gobang.children[0] this.chessmans = this.gobang.children[1] // 棋盤樣式 this.gobangStyle = Object.assign({ padding: 30, count: 15 }, options.gobangStyle || {}) // 棋盤元素 this.lattice = { width: (this.gobang.clientWidth - this.gobangStyle.padding * 2) / this.gobangStyle.count, height: (this.gobang.clientHeight - this.gobangStyle.padding * 2) / this.gobangStyle.count } // 初始化 this.resetAndInit() } // 初始化 resetAndInit() { const {options} = this // 角色 => 1黑旗子 2白旗 this.role = options.role || this.role || 1 // 是否已分出勝負(fù) this.win = false // 走棋記錄 this.history = [] // 當(dāng)前步 this.currentStep = 0 // 清空棋子和事件 this.chessmans.onclick = null this.chessmans.innerHTML = "" // 初始化 this.drawChessboard() this.listenDownChessman() this.initChessboardMatrix() } // 棋盤矩陣 initChessboardMatrix() { const checkerboard = [] for(let x = 0; x < this.gobangStyle.count + 1; x++) { checkerboard[x] = [] for(let y = 0; y < this.gobangStyle.count + 1; y++) { checkerboard[x][y] = 0 } } this.checkerboard = checkerboard } // 刻畫棋盤 drawChessboard() { const { gobangStyle, gobang } = this // 棋盤網(wǎng)格 const lattices = Array.from({ length: gobangStyle.count * gobangStyle.count }, () => ``).join("") this.chessboard.className = `chessboard lattice-${gobangStyle.count}` this.chessboard.innerHTML = lattices this.gobang.style.border = `${gobangStyle.padding}px solid #ffffd` } // 刻畫棋子 drawChessman(x, y, isBlack) { const { gobangStyle, lattice, gobang } = this const newChessman = document.createElement("div") newChessman.setAttribute("id", `x${x}-y${y}-r${isBlack ? 1 : 2}`) newChessman.className = isBlack ? "chessman black" : "chessman white" newChessman.style.width = lattice.width * 0.6 newChessman.style.height = lattice.height * 0.6 newChessman.style.left = (x * lattice.width) - lattice.width * 0.3 newChessman.style.top = (y * lattice.height) - lattice.height * 0.3 this.chessmans.appendChild(newChessman) // 每次落子結(jié)束都要判斷輸贏 setTimeout(() => { this.checkReferee(x, y, isBlack ? 1 : 2) }, 0) } // 落子 listenDownChessman(isBlack = false) { this.chessmans.onclick = event => { // 如果點(diǎn)擊的是棋子則中斷 if(event.target.className.includes("chessman ")) { return false } let { offsetX: x, offsetY: y } = event x = Math.round(x / this.lattice.width) y = Math.round(y / this.lattice.height) // 空的棋位才可落子 if(this.checkerboard[x][y] !== undefined && Object.is(this.checkerboard[x][y], 0)) { // 落子后,更新矩陣,切換角色,并記錄 this.checkerboard[x][y] = this.role this.drawChessman(x, y, Object.is(this.role, 1)) // 落子完畢后,有可能是悔棋之后落子的,這種情況下就該重置歷史記錄 this.history.length = this.currentStep this.history.push({ x, y, role: this.role }) // 保存坐標(biāo),角色,快照 this.currentStep++ this.role = Object.is(this.role, 1) ? 2 : 1 } } } // 判斷輸贏 checkReferee(x, y, role) { if((x == undefined) || (y == undefined) || (role == undefined)) return // 連殺分?jǐn)?shù) let countContinuous = 0 // 所在矩陣數(shù)據(jù) const XContinuous = this.checkerboard.map(x => x[y]) const YContinuous = this.checkerboard[x] const S1Continuous = [] const S2Continuous = [] this.checkerboard.forEach((_y, i) => { // 左斜線 const S1Item = _y[y - (x - i)] // alert(S1Item) if(S1Item !== undefined) { S1Continuous.push(S1Item) } // 右斜線 const S2Item = _y[y + (x - i)] if(S2Item !== undefined) { S2Continuous.push(S2Item) } }) // 當(dāng)前落棋點(diǎn)所在的X軸/Y軸/交叉斜軸,只要有能連起來(lái)的5個(gè)子的角色即有勝者 ; [XContinuous, YContinuous, S1Continuous, S2Continuous].forEach(axis => { if(axis.some((x, i) => axis[i] !== 0 && axis[i - 2] === axis[i - 1] && axis[i - 1] === axis[i] && axis[i] === axis[i + 1] && axis[i + 1] === axis[i + 2])) { countContinuous++ } }) // 如果贏了,則解綁事件 if(countContinuous) { this.chessmans.onclick = null this.win = true alert((role == 1 ? "黑" : "白") + "子勝") } } // 悔棋 regretChess() { // 找到最后一次的記錄,回滾UI,更新矩陣 if(this.history.length && !this.win) { const prev = this.history[this.currentStep - 1] if(prev) { const { x, y, role } = prev const targetChessman = document.getElementById(`x${x}-y${y}-r${role}`) targetChessman.parentNode.removeChild(targetChessman) this.checkerboard[prev.x][prev.y] = 0 this.currentStep-- this.role = Object.is(this.role, 1) ? 2 : 1 } } } // 撤銷悔棋 revokedRegretChess() { const next = this.history[this.currentStep] if(next) { this.drawChessman(next.x, next.y, next.role === 1) this.checkerboard[next.x][next.y] = next.role this.currentStep++ this.role = Object.is(this.role, 1) ? 2 : 1 } } } // 實(shí)例化游戲 const gobangGame = new Gobang({ role: 2, canvas: "game", gobangStyle: { padding: 30, count: 16 } }) console.log(gobangGame)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/88325.html
摘要:這是我在一次面試中,被面試官所提問(wèn)的一道題在這次面試題中相等指的是對(duì)象的屬性個(gè)數(shù)值相等有這樣兩個(gè)李德華張德華我能想到的一種方案解答過(guò)程的思考由于沒(méi)有,我只能通過(guò)轉(zhuǎn)化成數(shù)組進(jìn)入第二步,對(duì)象中的屬性在另一個(gè)中是否存在。 這是我在一次面試中,被面試官所提問(wèn)的一道題 在這次面試題中 相等:指的是對(duì)象的屬性個(gè)數(shù)值相等 有這樣兩個(gè)obj let obj1 = { name:李德華, ...
摘要:前端日?qǐng)?bào)精選專題之跟著學(xué)節(jié)流冴羽的博客全家桶仿微信項(xiàng)目,支持多人在線聊天和機(jī)器人聊天騰訊前端團(tuán)隊(duì)社區(qū)編碼的奧秘模塊實(shí)現(xiàn)入門淺析知乎專欄前端每周清單發(fā)布新版本提升應(yīng)用性能的方法中文寇可往吾亦可往用實(shí)現(xiàn)對(duì)決支付寶的微信企業(yè)付款到零 2017-06-20 前端日?qǐng)?bào) 精選 JavaScript專題之跟著 underscore 學(xué)節(jié)流 - 冴羽的JavaScript博客 - SegmentFau...
摘要:前言很認(rèn)真的說(shuō)吧,在和騰訊面試官的面試的過(guò)程。騰訊二面自我介紹二面的面試官和一面不是同一個(gè)面試官,所以在這個(gè)時(shí)候,我的基本介紹還是和一面一樣,介紹自己的基本信息,以及怎么想到學(xué)習(xí)前端和怎么學(xué)習(xí)前端。 前言 很認(rèn)真的說(shuō)吧,在和騰訊面試官的面試的過(guò)程。有點(diǎn)感覺(jué)是在聊天一樣,他們是面試官,但是感覺(jué)更像是引路人,不管結(jié)果的好壞,在騰訊面試的過(guò)程,只要你認(rèn)真去聽(tīng)去問(wèn),就可以學(xué)到很多東西吧。 如果...
摘要:擁有兩個(gè)版本,無(wú)依賴的獨(dú)立版和版本。除了對(duì)象,也可監(jiān)聽(tīng)內(nèi)元素的手勢(shì)需要引擎內(nèi)置對(duì)象支持綁定相關(guān)事件。據(jù)不完全統(tǒng)計(jì),目前服務(wù)于興趣部落群動(dòng)漫騰訊學(xué)院騰訊等多個(gè)部門團(tuán)隊(duì)和項(xiàng)目。也可以在事件回調(diào)里根據(jù)攜帶的信息使用去操作。 簡(jiǎn)介 針對(duì)多點(diǎn)觸控設(shè)備編程的Web手勢(shì)組件,快速幫助你的web程序增加手勢(shì)支持,也不用再擔(dān)心click 300ms的延遲了。擁有兩個(gè)版本,無(wú)依賴的獨(dú)立版和react版本。...
閱讀 3138·2021-11-24 10:24
閱讀 2930·2021-11-11 16:54
閱讀 3067·2021-09-22 15:55
閱讀 2027·2019-08-30 15:44
閱讀 1901·2019-08-29 18:41
閱讀 2761·2019-08-29 13:43
閱讀 3053·2019-08-29 12:51
閱讀 1172·2019-08-26 12:19