最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2022年06月22日 10:26:08   作者:逍丶  
五子棋游戲是一款大家耳熟能詳?shù)囊嬷穷愑螒?下面這篇文章主要給大家介紹了關(guān)于如何使用原生JS快速寫出一個(gè)五子棋小游戲的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

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ù)組的長(zhǎng)度,就能判斷勝負(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 {
          //否則得清空
          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 {
          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 {
          //否則得清空
          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 {
          //否則得清空
          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的基本語(yǔ)法,幾個(gè)數(shù)組的方法來回用,希望能給js初學(xué)者一些幫助。

到此這篇關(guān)于使用原生JS快速寫出一個(gè)五子棋小游戲的文章就介紹到這了,更多相關(guān)原生JS寫五子棋小游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Javascript前端UI框架Kit使用指南之kitjs的對(duì)話框組件

    Javascript前端UI框架Kit使用指南之kitjs的對(duì)話框組件

    本文以kitjs對(duì)話框組件為例,給我們?cè)敿?xì)介紹了kitjs的組件目錄、默認(rèn)代碼模板、構(gòu)造器及初始方法、以及Kitjs繼承。講解的非常細(xì)致,對(duì)我們熟練掌握kitjs組件很有幫助。
    2014-11-11
  • 微信小程序中post方法與get方法的封裝

    微信小程序中post方法與get方法的封裝

    這篇文章主要介紹了微信小程序中post方法與get方法的封裝的相關(guān)資料,希望通過本文能幫助到大家,讓大家掌握如何封裝,需要的朋友可以參考下
    2017-09-09
  • JavaScript中Set基本使用方法實(shí)例

    JavaScript中Set基本使用方法實(shí)例

    因?yàn)镾et中存放的數(shù)據(jù)都是不會(huì)重復(fù)的數(shù)據(jù),我們?cè)诰帉慗S代碼的時(shí)候,因此我們可以利用Set來幫助我們更便捷地完成許多的事,下面這篇文章主要給大家介紹了關(guān)于JavaScript中Set基本使用方法的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • ES6中l(wèi)et、const的區(qū)別及變量的解構(gòu)賦值操作方法實(shí)例分析

    ES6中l(wèi)et、const的區(qū)別及變量的解構(gòu)賦值操作方法實(shí)例分析

    這篇文章主要介紹了ES6中l(wèi)et、const的區(qū)別及變量的解構(gòu)賦值操作方法,結(jié)合實(shí)例形式分析了ES6中l(wèi)et、const的功能、原理、使用方法及數(shù)組、字符串、函數(shù)參數(shù)等解構(gòu)賦值相關(guān)操作技巧,需要的朋友可以參考下
    2019-10-10
  • 原生JS實(shí)現(xiàn)微信通訊錄

    原生JS實(shí)現(xiàn)微信通訊錄

    這篇文章主要為大家詳細(xì)介紹了原生JS實(shí)現(xiàn)微信通訊錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • weui上傳多圖片,壓縮,base64編碼的示例代碼

    weui上傳多圖片,壓縮,base64編碼的示例代碼

    這篇文章主要介紹了weui上傳多圖片,壓縮,base64編碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 解讀TypeScript與JavaScript的區(qū)別

    解讀TypeScript與JavaScript的區(qū)別

    這篇文章主要介紹了TypeScript與JavaScript的區(qū)別及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 原生JS實(shí)現(xiàn)數(shù)碼表特效

    原生JS實(shí)現(xiàn)數(shù)碼表特效

    這篇文章主要為大家詳細(xì)介紹了原生JS實(shí)現(xiàn)數(shù)碼表特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • layui頁(yè)面級(jí)彈出框的實(shí)現(xiàn)

    layui頁(yè)面級(jí)彈出框的實(shí)現(xiàn)

    本文主要介紹了layui頁(yè)面級(jí)彈出框的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • BootStrap表單時(shí)間選擇器詳解

    BootStrap表單時(shí)間選擇器詳解

    這篇文章主要為大家詳細(xì)介紹了BootStrap表單時(shí)間選擇器的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05

最新評(píng)論

涟源市| 思茅市| 阳谷县| 治多县| 清远市| 阜南县| 壶关县| 礼泉县| 河西区| 颍上县| 邵阳市| 昭觉县| 兴隆县| 赣州市| 肥东县| 五河县| 白沙| 新民市| 当涂县| 山西省| 泗洪县| 桓仁| 永福县| 合肥市| 河西区| 龙山县| 宾川县| 定襄县| 祁阳县| 鹿泉市| 福清市| 曲松县| 镇坪县| 嘉峪关市| 社旗县| 红河县| 鄂尔多斯市| 平乡县| 乐清市| 凉城县| 澳门|