废话不多说,说说代码吧!完整项目地址:GitHub项目地址classGobang{constructor(options){this.options=optionsthis.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={宽度:(this.gobang.clientWidth-this.gobangStyle.padding*2)/this.gobangStyle.count,高度:(this.gobang.clientHeight-this.gobangStyle.padding*2)/this.gobangStyle.count}//初始化this.resetAndInit()}//初始化resetAndInit(){const{options}=this//角色=>1黑旗2白旗this.role=options.role||这个角色||1//是否已经确定胜负this.win=false//棋局记录this.history=[]//当前步this.currentStep=0//清除棋子和事件this.chessmans.onclick=nullthis.chessmans.innerHTML=''//初始化this.drawChessboard()this.listenDownChessman()this.initChessboardMatrix()}//棋盘矩阵initChessboardMatrix(){constcheckerboard=[]for(letx=0;x``).join('')this.chessboard.className=`chessboardlattice-${gobangStyle.count}`this.chessboard.innerHTML=latticesthis.gobang.style.border=`${gobangStyle.padding}pxsolid#ddd`}//刻画棋子drawChessman(x,y,isBlack){const{gobangStyle,lattice,gobang}=thisconstnewChessman=document.createElement('div')newChessman.setAttribute('id',`x${x}-y${y}-r${isBlack?1:2}`)newChessman.className=isBlack?'黑棋子':'白棋子'newChessman.style.width=lattice.width*0.6newChessman.style.height=lattice.height*0.6newChessman.style.left=(x*lattice.width)-lattice.width*0.3newChessman.style.top=(y*lattice.height)-lattice.height*0.3this.chessmans.appendChild(newChessman)//输赢必须在每一步结束时判断setTimeout(()=>{this.checkReferee(x,y,isBlack?1:2)},0)}//下棋listenDownChessman(isBlack=false){this.chessmans.onclick=event=>{//中断if(event.target.className.includes('chessman')){returnfalse}let{offsetX:x,offsetY:y}=eventx=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这。drawChessman(x,y,Object.is(this.role,1))//走子完成后,可能会后悔走子。在这种情况下,应该重置历史记录。this.history.length=this.currentStepthis.history.push({x,y,role:this.role})//保存坐标、角色、快照this.currentStep++this.role=Object.is(this.role,1)?2:1}}}//判断输赢checkReferee(x,y,role){if((x==undefined)||(y==undefined)||(role==undefined))return//killstreakletcountContinuous=0//矩阵数据constXContinuous=this.checkerboard.map(x=>x[y])constYContinuous=this.checkerboard[x]constS1Continuous=[]constS2Continuous=[]this.checkerboard.forEach((_y,i)=>{//左斜杠constS1Item=_y[y-(x-i)]//alert(S1Item)if(S1Item!==undefined){S1Continuous.push(S1Item)}//右斜杠constS2Item=_y[y+(x-i)]if(S2Item!==undefined){S2Continuous.push(S2Item)}})//当前棋点所在的X轴/Y轴/交叉斜轴,如只要有能连上的5个角色为优胜者;[XContinuous,YContinuous,S1Continuous,S2Continuous].forEach(axis=>{if(axis.some((x,i)=>axis[i]!==0&&axis[i-2]===axis[i-1]&&轴[i-1]===轴[i]&&轴[i]===轴[i+1]&&轴[i+1]]===轴[i+2])){countContinuous++}})//如果你赢了,取消绑定事件if(countContinuous){this.chessmans.onclick=nullthis.win=truealert((role==1?'Black':'White')+'Winner')}}//RegretChess(){//找到最后一条记录,回滚UI,更新矩阵if(this.history.length&&!this.win){constprev=this.history[this.currentStep-1]if(prev){const{x,y,role}=prevconsttargetChessman=document.getElementById(`x${x}-y${y}-r${role}`)targetChessman.parentNode。removeChild(targetChessman)this.checkerboard[prev.x][prev.y]=0this.currentStep--this.role=Object.is(this.role,1)?2:1}}}//吊销弃棋revokedRegretChess(){constnext=this.history[this.currentStep]if(next){this.drawChessman(next.x,next.y,next.role===1)this.checkerboard[next.x][next.y]=next.rolethis.currentStep++this.role=Object.is(this.role,1)?2:1}}}//实例化游戏constgobangGame=newGobang({role:2,canvas:'game',gobangStyle:{padding:30,count:16}})console.log(gobangGame)