新聞中心
1. 棋盤和棋子的繪制。

創(chuàng)新互聯(lián)建站是一家專注于成都網(wǎng)站設計、成都網(wǎng)站制作與策劃設計,平原網(wǎng)站建設哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專注于網(wǎng)站建設10年,網(wǎng)設計領域的專業(yè)建站公司;建站業(yè)務涵蓋:平原等地區(qū)。平原做網(wǎng)站價格咨詢:18980820575
let arr = [ [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},], [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},],]//封裝渲染函數(shù)const render = () => { document.querySelector('table').innerHTML = '' arr.forEach((item, index) => { let tr = document.createElement('tr') item.forEach((item2, index2) => { let td = document.createElement('td')//遍歷數(shù)組,繪制棋盤 //給td標簽設置自定義屬性,用來作為坐標使用 td.dataset.y = index td.dataset.x = index2 tr.appendChild(td) //給數(shù)組里面的對象做條件判斷,這樣就能渲染出顏色 if (item2.num === 1) { td.classList.add('bgc1') } else if (item2.num === 2) { td.classList.add('bgc2') } }) document.querySelector('table').appendChild(tr) })}render()先創(chuàng)建一個15 * 15的二維數(shù)組,通過對數(shù)組的兩層遍歷,創(chuàng)建出一個 15 * 15 的表格,這樣棋盤就有了。用數(shù)組來繪制棋盤的好處是便于查找和篩選。每一個td都對應著一個空對象,下棋的時候通過給這個對象添加一個 num 的屬性,num 為 1 時,就渲染成黑色,2 就渲染成白色,再稍微調(diào)整一下 css 樣式,這樣棋盤和棋子就繪制好了。每一個 td 都有自己的自定義屬性 x 和 y,類似于坐標,這樣就可以很方便的把 td 標簽和數(shù)組里對應的值聯(lián)系起來。下面是 css 代碼
2. 輪流下棋的點擊事件
下棋的邏輯很簡單,就是點擊棋盤的時候,給點擊的td對應的那個對象添加一個num屬性,黑棋就是1,白棋就是2,然后渲染出來就可以了。下棋順序可以通過一個全局變量flag來控制,同時聲明兩個全局數(shù)組,用來存放所有的黑棋和白棋。后面判斷勝負時,要對這兩個數(shù)組先進行遍歷。
//判斷下棋順序的全局變量let flag = true//所有黑棋數(shù)組let blackArr = []//所有白棋數(shù)組let whiteArr = []//輪流下棋邏輯document.querySelector('table').addEventListener('click', function (e) { if (e.target.dataset.x) { let td = e.target //判斷黑白棋子的順序 if (flag) { //判斷點擊的地方是否已經(jīng)有棋子了,避免棋子覆蓋 if (!arr[td.dataset.y][td.dataset.x].num) { flag = !flag arr[td.dataset.y][td.dataset.x].num = 1 //每走一步,就將其添加至對應的數(shù)組當中 blackArr.push([td.dataset.y, td.dataset.x]) } } else { if (!arr[td.dataset.y][td.dataset.x].num) { flag = !flag arr[td.dataset.y][td.dataset.x].num = 2 whiteArr.push([td.dataset.y, td.dataset.x]) } } //調(diào)用判斷勝負的函數(shù) XWin(td) YWin(td) X_YWin(td) Y_XWin(td) } render()})3.獲勝條件判斷
接下來就是寫獲勝條件了。我分成了 4 種情況,橫軸,數(shù)軸,正斜軸和反斜軸。這 4 種情況邏輯和方法大致都是相同的,就是里面的數(shù)據(jù)有些細微差別。
3.1 橫軸獲勝
以橫軸為例,如何判斷獲勝,先判斷是黑棋還是白棋,然后遍歷對應的數(shù)組。已黑棋為例,遍歷之后把y值相同的黑棋篩選出來都放入一個數(shù)組中,也就是同一行的黑棋。接著比較這一行的這些黑棋的x值,如果有5個連續(xù)的x值,則說明橫軸上有5個連續(xù)的黑棋,就可以判斷獲勝了。怎么比較這些x值呢,我的做法是先將他們用sort()方法排序,接著從小到大依次比較。建一個新數(shù)組,第二個值等于第一個值加1,就把他們?nèi)拥竭@個新數(shù)組中,如果出現(xiàn)某個值不連續(xù)了,就將這個數(shù)組清空,這樣通過判斷這個數(shù)組的長度,就能判斷勝負了。
//橫軸獲勝邏輯function XWin(td) { //當前X軸的所有棋子集合 let xAllArr = [] //判斷橫軸勝負邏輯的X軸棋子 let xWinArr = [] //判斷下的是黑棋還是白棋 if (!flag) { blackArr.map(item => { if (item[0] == td.dataset.y) { //將當前排的所有棋子加入對應數(shù)組 xAllArr.push(item[1]) } }) } else { whiteArr.map(item => { if (item[0] == td.dataset.y) { xAllArr.push(item[1]) } }) } //把橫排總數(shù)組排序,方便比較 xAllArr.sort((a, b) => a - b) for (let i = 1; i < xAllArr.length; i++) { // console.log(xAllArr[i]); if (xAllArr[i] == (+xAllArr[i - 1] + 1)) { //如果相鄰的兩個棋子數(shù)量相差1,就將其添加至勝負邏輯數(shù)組 xWinArr.push(xAllArr[i]) } else { //如果數(shù)組長度大于4,就跳出循環(huán) if (xWinArr.length >= 4) break //否則得清空 xWinArr = [] } } //獲勝條件 if (xWinArr.length >= 4) { //這里要用定時器將彈框變成異步任務,否則第五顆棋子渲染不出來就提示獲勝了 if (!flag) { setTimeout(function () { alert('黑棋獲勝!') location.reload() }, 100) } else { setTimeout(function () { alert('白棋獲勝!') location.reload() }, 100) } }}3.2 數(shù)軸獲勝
?豎軸和橫軸代碼基本上也相同
只是換了個條件,把 if (item[0] == td.dataset.y) ?換成了 if (item[1] == td.dataset.x),意思就是選出這一列所有的棋子。后面的邏輯和代碼就和橫軸一樣了。?
//豎軸獲勝邏輯function YWin(td) { //當前Y軸的所有棋子集合 let yAllArr = [] //判斷豎軸勝負邏輯的X軸棋子 let yWinArr = [] if (!flag) { blackArr.map(item => { if (item[1] == td.dataset.x) { yAllArr.push(item[0]) } }) } else { whiteArr.map(item => { if (item[1] == td.dataset.x) { yAllArr.push(item[0]) } }) } //豎排總數(shù)組排序 yAllArr.sort((a, b) => a - b) for (let i = 1; i < yAllArr.length; i++) { // console.log(xAllArr[i]); if (yAllArr[i] == (+yAllArr[i - 1] + 1)) { yWinArr.push(yAllArr[i]) } else { //如果數(shù)組長度大于4,就跳出循環(huán) if (yWinArr.length >= 4) break yWinArr = [] } } if (yWinArr.length >= 4) { if (!flag) { setTimeout(function () { alert('黑棋獲勝!') location.reload() }, 100) } else { setTimeout(function () { alert('白棋獲勝!') location.reload() }, 100) } }}3.3 正斜軸獲勝
斜軸困難一點的地方就是,怎么篩選出這一條斜線上的所有棋子。
只要能把這條斜線上的棋子給找出來,后面的邏輯判斷就都一樣了。所有的斜線都是 45 度角,也就是說斜線上的任意兩個棋子,他們的x值之差于y值之差是相等的。這樣的話,判斷起來就簡單了。??if ((item[0] - td.dataset.y) == (item[1] - td.dataset.x))?? 這樣就可以了。斜線上的棋子找出來后,后面的步驟就都一樣了,復制粘貼即可。
//正斜軸獲勝邏輯function X_YWin(td) { //當前X軸的所有棋子集合 let x_yAllArr = [] //判斷橫軸勝負邏輯的X軸棋子 let x_yWinArr = [] if (!flag) { blackArr.map(item => { //判斷斜軸棋子,斜軸棋子的x和y之差都是相同的 if ((item[0] - td.dataset.y) == (item[1] - td.dataset.x)) { x_yAllArr.push(item[1]) } }) } else { whiteArr.map(item => { if ((item[0] - td.dataset.y) == (item[1] - td.dataset.x)) { x_yAllArr.push(item[1]) } }) } x_yAllArr.sort((a, b) => a - b) for (let i = 1; i < x_yAllArr.length; i++) { if (x_yAllArr[i] == (+x_yAllArr[i - 1] + 1)) { //如果相鄰的兩個棋子數(shù)量相差1,就將其添加至勝負邏輯數(shù)組 x_yWinArr.push(x_yAllArr[i]) } else { //如果數(shù)組長度大于4,就跳出循環(huán) if (x_yWinArr.length >= 4) break //否則得清空 x_yWinArr = [] } } //獲勝條件 if (x_yWinArr.length >= 4) { if (!flag) { setTimeout(function () { alert('黑棋獲勝!') location.reload() }, 100) } else { setTimeout(function () { alert('白棋獲勝!') location.reload() }, 100) } }}3.4 反斜軸獲勝
反斜軸同理,條件改成 if (0 - (item[0] - td.dataset.y) == (item[1] - td.dataset.x)),其余的復制粘貼。
//反斜軸獲勝邏輯function Y_XWin(td) { //當前X軸的所有棋子集合 let y_xAllArr = [] //判斷橫軸勝負邏輯的X軸棋子 let y_xWinArr = [] if (!flag) { blackArr.map(item => { //判斷斜軸棋子 if (0 - (item[0] - td.dataset.y) == (item[1] - td.dataset.x)) { y_xAllArr.push(item[1]) } }) } else { whiteArr.map(item => { if (0 - (item[0] - td.dataset.y) == (item[1] - td.dataset.x)) { y_xAllArr.push(item[1]) } }) } y_xAllArr.sort((a, b) => a - b) for (let i = 1; i < y_xAllArr.length; i++) { if (y_xAllArr[i] == (+y_xAllArr[i - 1] + 1)) { //如果相鄰的兩個棋子數(shù)量相差1,就將其添加至勝負邏輯數(shù)組 y_xWinArr.push(y_xAllArr[i]) } else { //如果數(shù)組長度大于4,就跳出循環(huán) if (y_xWinArr.length >= 4) break //否則得清空 y_xWinArr = [] } } //獲勝條件 if (y_xWinArr.length >= 4) { if (!flag) { setTimeout(function () { alert('黑棋獲勝!') location.reload() }, 100) } else { setTimeout(function () { alert('白棋獲勝!') location.reload() }, 100) } }}把這些函數(shù)放到下棋事件里面調(diào)用,整個功能就完成了。
4. 悔棋功能
最后寫一下悔棋功能,點擊悔棋,把對應數(shù)組里面的數(shù)據(jù)刪除,然后重新渲染棋盤就完事了。
//悔棋document.querySelector('button').addEventListener('click', function () { //判斷前面一步是黑棋還是白棋 if (!flag) { //黑棋 //獲取對應棋子總數(shù)組的最后一個數(shù)據(jù)的值 const y = blackArr[blackArr.length - 1][0] const x = blackArr[blackArr.length - 1][1] //將對應的對象里的num值刪除,這樣渲染出來對應棋子就消失了 delete arr[y][x].num //刪除總數(shù)組里的最后一個數(shù)據(jù),否則勝負邏輯會有問題 blackArr.splice(blackArr.length - 1, 1) //重置下棋順序 flag = !flag } else { //白棋 const y = whiteArr[whiteArr.length - 1][0] const x = whiteArr[whiteArr.length - 1][1] delete arr[y][x].num whiteArr.splice(whiteArr.length - 1, 1) flag = !flag } render()})總結
整個代碼寫下來,都是些 js 的基本語法,幾個數(shù)組的方法來回用,希望能給 js 初學者一些幫助。
分享題目:如何使用原生 JS,快速寫出一個五子棋小游戲
轉載注明:http://www.dlmjj.cn/article/djshppj.html


咨詢
建站咨詢
