欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2022年06月22日 10:26:08   作者:逍丶  
五子棋游戲是一款大家耳熟能詳?shù)囊嬷穷愑螒?下面這篇文章主要給大家介紹了關(guān)于如何使用原生JS快速寫出一個(gè)五子棋小游戲的相關(guān)資料,文中通過(guò)實(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è)置自定義屬性,用來(lái)作為坐標(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ù)組,通過(guò)對(duì)數(shù)組的兩層遍歷,創(chuàng)建出一個(gè)15*15的表格,這樣棋盤就有了。用數(shù)組來(lái)繪制棋盤的好處是便于查找和篩選。 每一個(gè)td都對(duì)應(yīng)著一個(gè)空對(duì)象,下棋的時(shí)候通過(guò)給這個(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)系起來(lái)。 下面是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,然后渲染出來(lái)就可以了。下棋順序可以通過(guò)一個(gè)全局變量flag來(lái)控制,同時(shí)聲明兩個(gè)全局?jǐn)?shù)組,用來(lái)存放所有的黑棋和白棋。后面判斷勝負(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.獲勝條件判斷

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

3.1橫軸獲勝

以橫軸為例,如何判斷獲勝,先判斷是黑棋還是白棋,然后遍歷對(duì)應(yīng)的數(shù)組。已黑棋為例,遍歷之后把y值相同的黑棋篩選出來(lái)都放入一個(gè)數(shù)組中,也就是同一行的黑棋。接著比較這一行的這些黑棋的x值,如果有5個(gè)連續(xù)的x值,則說(shuō)明橫軸上有5個(gè)連續(xù)的黑棋,就可以判斷獲勝了。怎么比較這些x值呢,我的做法是先將他們用sort()方法排序,接著從小到大依次比較。建一個(gè)新數(shù)組,第二個(gè)值等于第一個(gè)值加1,就把他們?nèi)拥竭@個(gè)新數(shù)組中,如果出現(xiàn)某個(gè)值不連續(xù)了,就將這個(gè)數(shù)組清空,這樣通過(guò)判斷這個(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ù),否則第五顆棋子渲染不出來(lái)就提示獲勝了
        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)的地方就是,怎么篩選出這一條斜線上的所有棋子。

只要能把這條斜線上的棋子給找出來(lái),后面的邏輯判斷就都一樣了。所有的斜線都是45度角,也就是說(shuō)斜線上的任意兩個(gè)棋子,他們的x值之差于y值之差是相等的。這樣的話,判斷起來(lái)就簡(jiǎn)單了。 if ((item[0] - td.dataset.y) == (item[1] - td.dataset.x))這樣就可以了。斜線上的棋子找出來(lái)后,后面的步驟就都一樣了,復(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值刪除,這樣渲染出來(lái)對(duì)應(yīng)棋子就消失了
        delete arr[y][x].num
        //刪除總數(shù)組里的最后一個(gè)數(shù)據(jù),否則勝負(fù)邏輯會(huì)有問(wèn)題
        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è)代碼寫下來(lái),都是些js的基本語(yǔ)法,幾個(gè)數(shù)組的方法來(lái)回用,希望能給js初學(xué)者一些幫助。

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

相關(guān)文章

  • 一文弄懂JavaScript的繼承方式

    一文弄懂JavaScript的繼承方式

    這篇文章主要介紹了一文弄懂JavaScript的繼承方式,在java面試過(guò)程中經(jīng)常被問(wèn)到j(luò)avascript中有幾種繼承方式,每種繼承方式是怎么實(shí)現(xiàn)的,文中給大家講解的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • 深入理解JavaScript中的call、apply、bind方法的區(qū)別

    深入理解JavaScript中的call、apply、bind方法的區(qū)別

    下面小編就為大家?guī)?lái)一篇深入理解JavaScript中的call、apply、bind方法的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-05-05
  • 利用JS將圖標(biāo)字體渲染為圖片的方法詳解

    利用JS將圖標(biāo)字體渲染為圖片的方法詳解

    在軟件開(kāi)發(fā)中肯定要用到圖標(biāo),比如下圖的?Groove?音樂(lè)中就用到了許多圖標(biāo)。一種獲取這些圖標(biāo)的方法是把?Groove?音樂(lè)截個(gè)圖,然后熟練地開(kāi)啟?Photoshop,開(kāi)始摳圖。這種方式很遜,效率也很低。本文將利用JS將圖標(biāo)字體渲染為圖片,需要的可以參考一下
    2022-05-05
  • 詳解js根據(jù)百度地圖提供經(jīng)緯度計(jì)算兩點(diǎn)距離

    詳解js根據(jù)百度地圖提供經(jīng)緯度計(jì)算兩點(diǎn)距離

    這篇文章主要介紹了js根據(jù)百度地圖提供經(jīng)緯度計(jì)算兩點(diǎn)距離,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)帶動(dòng)畫返回頂部的方法詳解

    JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)帶動(dòng)畫返回頂部的方法詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)帶動(dòng)畫返回頂部的效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-08-08
  • IE8利用自帶的setCapture和releaseCapture解決iframe的拖拽事件方法

    IE8利用自帶的setCapture和releaseCapture解決iframe的拖拽事件方法

    最近有個(gè)需求須要實(shí)現(xiàn)左右拖拽功能,頁(yè)面右邊是個(gè)iframe頁(yè)面,在chrome測(cè)試通過(guò)之后,發(fā)現(xiàn)在ie8上面效果不是很理想,查閱相關(guān)資料找到可以使用ie自帶的setCapture和releaseCapture來(lái)解決,需要的朋友可以參考下
    2016-10-10
  • 純JS單頁(yè)面賽車游戲制作代碼分享

    純JS單頁(yè)面賽車游戲制作代碼分享

    這篇文章主要為大家分享了純JS單頁(yè)面賽車游戲制作代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • JavaScript 判斷數(shù)據(jù)類型的4種方法

    JavaScript 判斷數(shù)據(jù)類型的4種方法

    這篇文章主要介紹了JavaScript 判斷數(shù)據(jù)類型的4種方法,幫助大家更好的理解和學(xué)習(xí)JavaScript,感興趣的朋友可以了解下
    2020-09-09
  • javascript時(shí)間差插件分享

    javascript時(shí)間差插件分享

    這篇文章主要為大家分享了javascript時(shí)間差插件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-07-07
  • setTimeout()遞歸調(diào)用不加引號(hào)出錯(cuò)的解決方法

    setTimeout()遞歸調(diào)用不加引號(hào)出錯(cuò)的解決方法

    用了setTimeout()想實(shí)現(xiàn)遞歸調(diào)用,如果第一個(gè)參數(shù)不加引號(hào)的話,就會(huì)出錯(cuò),下面與大家分享下該如何解決
    2014-09-09

最新評(píng)論