自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何使用原生 JS,快速寫出一個(gè)五子棋小游戲

開發(fā) 前端
下棋的邏輯很簡(jiǎn)單,就是點(diǎn)擊棋盤的時(shí)候,給點(diǎn)擊的td對(duì)應(yīng)的那個(gè)對(duì)象添加一個(gè)num屬性,黑棋就是1,白棋就是2,然后渲染出來就可以了。下棋順序可以通過一個(gè)全局變量flag來控制,同時(shí)聲明兩個(gè)全局?jǐn)?shù)組,用來存放所有的黑棋和白棋。后面判斷勝負(fù)時(shí),要對(duì)這兩個(gè)數(shù)組先進(jìn)行遍歷。

1. 棋盤和棋子的繪制。

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標(biāo)簽設(shè)置自定義屬性,用來作為坐標(biāo)使用      td.dataset.y = index      td.dataset.x = index2      tr.appendChild(td)      //給數(shù)組里面的對(duì)象做條件判斷,這樣就能渲染出顏色      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)建一個(gè)15 * 15的二維數(shù)組,通過對(duì)數(shù)組的兩層遍歷,創(chuàng)建出一個(gè) 15 * 15 的表格,這樣棋盤就有了。用數(shù)組來繪制棋盤的好處是便于查找和篩選。每一個(gè)td都對(duì)應(yīng)著一個(gè)空對(duì)象,下棋的時(shí)候通過給這個(gè)對(duì)象添加一個(gè) num 的屬性,num 為 1 時(shí),就渲染成黑色,2 就渲染成白色,再稍微調(diào)整一下 css 樣式,這樣棋盤和棋子就繪制好了。每一個(gè) td 都有自己的自定義屬性 x 和 y,類似于坐標(biāo),這樣就可以很方便的把 td 標(biāo)簽和數(shù)組里對(duì)應(yīng)的值聯(lián)系起來。下面是 css 代碼

<style>  * {    margin: 0;    padding: 0;    box-sizing: border-box;    list-style: none;  }  table {    position: relative;    width: 730px;    height: 730px;    margin: 0 auto;    border: 5px solid black;    background: url(./src=http___pic45.nipic.com_20140804_2372131_155038114014_2.jpg&refer=http___pic45.nipic.webp) no-repeat;    background-size: 100%;    background-position: center;    padding: 24px 12px;  }  td {    width: 35px;    height: 35px;    border-radius: 50%;    margin-right: 13px;    margin-bottom: 11px;    cursor: pointer;  }  .bgc1 {    background-color: black;  }  .bgc2 {    background-color: white;  }  button {    position: absolute;    width: 200px;    height: 100px;    bottom: 100px;    right: 200px;    text-align: center;    line-height: 100px;    font-size: 25px;  }</style>
<table></table><button>悔棋</button>

圖片

2. 輪流下棋的點(diǎn)擊事件

下棋的邏輯很簡(jiǎn)單,就是點(diǎn)擊棋盤的時(shí)候,給點(diǎn)擊的td對(duì)應(yīng)的那個(gè)對(duì)象添加一個(gè)num屬性,黑棋就是1,白棋就是2,然后渲染出來就可以了。下棋順序可以通過一個(gè)全局變量flag來控制,同時(shí)聲明兩個(gè)全局?jǐn)?shù)組,用來存放所有的黑棋和白棋。后面判斷勝負(fù)時(shí),要對(duì)這兩個(gè)數(shù)組先進(jìn)行遍歷。

//判斷下棋順序的全局變量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) {      //判斷點(diǎn)擊的地方是否已經(jīng)有棋子了,避免棋子覆蓋      if (!arr[td.dataset.y][td.dataset.x].num) {        flag = !flag        arr[td.dataset.y][td.dataset.x].num = 1        //每走一步,就將其添加至對(duì)應(yīng)的數(shù)組當(dāng)中        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)用判斷勝負(fù)的函數(shù)    XWin(td)    YWin(td)    X_YWin(td)    Y_XWin(td)  }  render()})

圖片

3.獲勝條件判斷

接下來就是寫獲勝條件了。我分成了 4 種情況,橫軸,數(shù)軸,正斜軸和反斜軸。這 4 種情況邏輯和方法大致都是相同的,就是里面的數(shù)據(jù)有些細(xì)微差別。

3.1 橫軸獲勝

以橫軸為例,如何判斷獲勝,先判斷是黑棋還是白棋,然后遍歷對(duì)應(yīng)的數(shù)組。已黑棋為例,遍歷之后把y值相同的黑棋篩選出來都放入一個(gè)數(shù)組中,也就是同一行的黑棋。接著比較這一行的這些黑棋的x值,如果有5個(gè)連續(xù)的x值,則說明橫軸上有5個(gè)連續(xù)的黑棋,就可以判斷獲勝了。怎么比較這些x值呢,我的做法是先將他們用sort()方法排序,接著從小到大依次比較。建一個(gè)新數(shù)組,第二個(gè)值等于第一個(gè)值加1,就把他們?nèi)拥竭@個(gè)新數(shù)組中,如果出現(xiàn)某個(gè)值不連續(xù)了,就將這個(gè)數(shù)組清空,這樣通過判斷這個(gè)數(shù)組的長度,就能判斷勝負(fù)了。

//橫軸獲勝邏輯function XWin(td) {  //當(dāng)前X軸的所有棋子集合  let xAllArr = []  //判斷橫軸勝負(fù)邏輯的X軸棋子  let xWinArr = []  //判斷下的是黑棋還是白棋  if (!flag) {    blackArr.map(item => {      if (item[0] == td.dataset.y) {        //將當(dāng)前排的所有棋子加入對(duì)應(yīng)數(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)) {      //如果相鄰的兩個(gè)棋子數(shù)量相差1,就將其添加至勝負(fù)邏輯數(shù)組      xWinArr.push(xAllArr[i])    } else {      //如果數(shù)組長度大于4,就跳出循環(huán)      if (xWinArr.length >= 4) break      //否則得清空      xWinArr = []    }  }  //獲勝條件  if (xWinArr.length >= 4) {    //這里要用定時(shí)器將彈框變成異步任務(wù),否則第五顆棋子渲染不出來就提示獲勝了    if (!flag) {      setTimeout(function () {        alert('黑棋獲勝!')        location.reload()      }, 100)    } else {      setTimeout(function () {        alert('白棋獲勝!')        location.reload()      }, 100)    }  }}

圖片

3.2 數(shù)軸獲勝

?豎軸和橫軸代碼基本上也相同

只是換了個(gè)條件,把 if (item[0] == td.dataset.y) ?換成了 if (item[1] == td.dataset.x),意思就是選出這一列所有的棋子。后面的邏輯和代碼就和橫軸一樣了。?

//豎軸獲勝邏輯function YWin(td) {  //當(dāng)前Y軸的所有棋子集合  let yAllArr = []  //判斷豎軸勝負(fù)邏輯的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 正斜軸獲勝

斜軸困難一點(diǎn)的地方就是,怎么篩選出這一條斜線上的所有棋子。

只要能把這條斜線上的棋子給找出來,后面的邏輯判斷就都一樣了。所有的斜線都是 45 度角,也就是說斜線上的任意兩個(gè)棋子,他們的x值之差于y值之差是相等的。這樣的話,判斷起來就簡(jiǎn)單了。??if ((item[0] - td.dataset.y) == (item[1] - td.dataset.x))?? 這樣就可以了。斜線上的棋子找出來后,后面的步驟就都一樣了,復(fù)制粘貼即可。

//正斜軸獲勝邏輯function X_YWin(td) {  //當(dāng)前X軸的所有棋子集合  let x_yAllArr = []  //判斷橫軸勝負(fù)邏輯的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)) {      //如果相鄰的兩個(gè)棋子數(shù)量相差1,就將其添加至勝負(fù)邏輯數(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)),其余的復(fù)制粘貼。

//反斜軸獲勝邏輯function Y_XWin(td) {  //當(dāng)前X軸的所有棋子集合  let y_xAllArr = []  //判斷橫軸勝負(fù)邏輯的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)) {      //如果相鄰的兩個(gè)棋子數(shù)量相差1,就將其添加至勝負(fù)邏輯數(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)用,整個(gè)功能就完成了。

4. 悔棋功能

最后寫一下悔棋功能,點(diǎn)擊悔棋,把對(duì)應(yīng)數(shù)組里面的數(shù)據(jù)刪除,然后重新渲染棋盤就完事了。

//悔棋document.querySelector('button').addEventListener('click', function () {  //判斷前面一步是黑棋還是白棋  if (!flag) {    //黑棋    //獲取對(duì)應(yīng)棋子總數(shù)組的最后一個(gè)數(shù)據(jù)的值    const y = blackArr[blackArr.length - 1][0]    const x = blackArr[blackArr.length - 1][1]    //將對(duì)應(yīng)的對(duì)象里的num值刪除,這樣渲染出來對(duì)應(yīng)棋子就消失了    delete arr[y][x].num    //刪除總數(shù)組里的最后一個(gè)數(shù)據(jù),否則勝負(fù)邏輯會(huì)有問題    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()})

總結(jié)

整個(gè)代碼寫下來,都是些 js 的基本語法,幾個(gè)數(shù)組的方法來回用,希望能給 js 初學(xué)者一些幫助。

圖片

責(zé)任編輯:武曉燕 來源: 前端YUE
相關(guān)推薦

2022-11-07 11:27:00

JS游戲開發(fā)

2022-03-17 15:28:18

五子棋HarmonyOSJSAPI

2010-03-18 17:07:32

2015-01-19 13:42:08

Android游戲源碼藍(lán)牙對(duì)戰(zhàn)五子棋

2015-06-16 14:24:41

開發(fā)五子棋網(wǎng)游

2023-10-07 11:58:52

PythonPygame

2015-01-14 14:22:30

Android源碼游戲

2021-04-13 06:35:13

Elixir語言編程語言軟件開發(fā)

2022-08-22 17:28:34

ArkUI鴻蒙

2022-11-01 15:17:48

JS鴻蒙小游戲

2011-06-21 15:01:55

2022-10-31 15:22:37

JS鴻蒙小游戲

2022-03-24 07:57:58

Python水果忍者游戲

2020-11-30 06:20:13

javascript

2023-02-13 14:47:32

人工智能機(jī)器學(xué)習(xí)ChatGPT

2024-01-15 07:47:09

井字棋游戲編程練習(xí)Python

2021-03-30 05:58:01

JavascriptCss3轉(zhuǎn)盤小游戲

2022-02-11 14:39:11

游戲JS鴻蒙

2023-11-29 08:10:36

javascriptH5游戲

2020-10-29 16:00:03

Node.jsweb前端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)