井字棋游戏(HTML+CSS+JavaScript)

  🌏个人博客主页心.c

前言:这两天在写植物大战僵尸,写不动了,现在和大家分享一下之前我写的一个很简单的小游戏井字棋,这个没有AI,可以两个人一起玩,如果大家觉得我哪里写的有一些问题,还希望积极改正,欢迎大家留言

🔥🔥🔥专题文章JavaScript小游戏

😽感谢大家的点赞👍收藏⭐️评论✍您的一键三连是我更新的动力 💓 


目录

页面效果: 

 相关技能实现:

创建空数组:

 获得大盒子和小盒子对象:

 给大盒子添加事件监听:

 判断小格子是否被填满:

判断是否有一方成功:

 判断数组中存在的数的个数:

 更新页面:

源代码:

HTML

CSS

 JavaScript:


页面效果: 

关于应用就是不可重复添加,而且两次点击的表情是不一样的,每个表情代表一方,出现三连的那一方就赢了,每一个小方格是不可重复添加的,如果每个格子都填满了就平局成功或平局都会出现alert提示,然后页面清空,清空之后可以继续玩

 相关技能实现:

创建空数组:

空数组用来遍历(通过其值是1是2或是null)来放置我们的表情 

  const arr = Array(9).fill(null)
 获得大盒子和小盒子对象:
 let box = this.document.querySelector('.box')
 let small_boxes = this.document.querySelectorAll('.small')
 给大盒子添加事件监听:

给我们的大盒子添加点击事件,冒泡到子级,通过1和2的个数,来添加1或2,谁少添加谁,优先添加1,如果1和2的个数有一个大于3,可能出现一方胜利的情况,就添加winner方法进行判断,如果有一方胜利,就返回这一方,然后页面进行清空(通过返回的1还是2进行判断是谁胜利了)如果一直没有胜利,直到小方格都被填写完,算两方平局,页面就会被清空,就可以重新进行添加了

box.addEventListener('click', function (e) {
    if (e.target.tagName === 'DIV') {
      let id = +e.target.dataset.id
      if (getCount(arr, 1) <= getCount(arr, 2)) {
        if (arr[id - 1] === null) {
          arr[id - 1] = 1
          console.log(arr)
          render()
        } else {
          alert('请在空白处添加')
        }
      } else {
        if (arr[id - 1] === null) {
          arr[id - 1] = 2
          console.log(arr)
          render()
        } else {
          alert('请在空白处添加')
        }
      }
      //判断是否被填满
      if (allSet()) {
        let time0 = setTimeout(function () {
          alert('平局')
          arr.fill(null)
          small_boxes.forEach(function (small_box) {
            console.log(small_box)
            small_box.innerHTML = ''; // 清空每个文本框
          });
          clearTimeout(time0)
        }, 300)
      }

      //判断是否有一方赢
      if (getCount(arr, 1) >= 3 || getCount(arr, 2) >= 3) {
        let time = setTimeout(function () {

          let win = winner()
          if (win != -1) {
            if (win === 1) {
              alert('笑脸成功')
            } else if (win === 2) {
              alert('哭脸成功')
            }
            arr.fill(null)
            small_boxes.forEach(function (small_box) {
              console.log(small_box)
              small_box.innerHTML = ''; // 清空每个文本框
            });
            clearTimeout(time)
          }
        }, 400)
      }
    }
  })
 判断小格子是否被填满:

遍历数组arr的每个值,如果该值有一个为null,就返回false,如果都不为false,最后返回true 

function allSet() {
    for (let i of arr) {
      if (i == null) {
        return false
      }
    }
    return true
  }
判断是否有一方成功:

 这个游戏虽然是3×3方格,但是是用一维数组存储的,如果下面有一对(三个)下标的值相等,就返回其中一个下标的值

//判断是否成功
  function winner() {
    const winningCombinations = [
      [0, 1, 2], [3, 4, 5], [6, 7, 8],
      [0, 3, 6], [1, 4, 7], [2, 5, 8],
      [0, 4, 8], [2, 4, 6]
    ];

    for (let combo of winningCombinations) {
      if (arr[combo[0]] && arr[combo[0]] === arr[combo[1]] && arr[combo[1]] === arr[combo[2]]) {
        return arr[combo[0]];
      }
    }

    return -1;
  }
 判断数组中存在的数的个数:

这个方法就是为了判断1和2的个数 

//返回某个数存在的个数
  function getCount(arr, value) {
    return arr.filter(item => item === value).length;
  }
 更新页面:

遍历数组向每个小方格添加内容,如果为1,添加笑脸,如果为2,添加哭脸,如果为null,什么也不添加,数组和方格是一一对应的 

 function render() {
    small_boxes.forEach(function (small_box) {
      small_box.innerHTML = ''; // 清空每个文本框
    });
    for (let i = 0; i < 9; i++) {
      let smal = document.querySelector(`[data-id="${i + 1}"]`)
      if (arr[i] === 1) {
        smal.innerHTML = '&#xe68b;'
      }
      else if (arr[i] === 2) {
        smal.innerHTML = '&#xe68e;'
      } else {
        smal.innerHTML = ''
      }
    }
  }

源代码:

HTML:
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./iconfont/iconfont.css">
  <link rel="stylesheet" href="./game.css">
</head>

<body>
  <div class="box wrapper">
    <div class="small iconfont" data-id="1"></div>
    <div class="small iconfont" data-id="2"></div>
    <div class="small iconfont" data-id="3"></div>
    <div class="small iconfont" data-id="4"></div>
    <div class="small iconfont" data-id="5"></div>
    <div class="small iconfont" data-id="6"></div>
    <div class="small iconfont" data-id="7"></div>
    <div class="small iconfont" data-id="8"></div>
    <div class="small iconfont" data-id="9"></div>
  </div>
  <div class="text">
    <h1>----井字棋----</h1>
  </div>


  <script src="./game.js"></script>
</body>

</html>
CSS:
:root {
  --bgc: rgb(223, 225, 248);
}

.wrapper {
  margin: auto;
}

* {
  margin: 0;
  height: 0;
  box-sizing: border-box;
}

.body {
  user-select: none;
  background-color: #f6faff;
}

.box {
  user-select: none;
  margin-top: 20px;
  display: flex;
  flex-wrap: wrap;
  width: 570px;
  height: 570px;
  border: 12px solid var(--bgc);
  border-radius: 40px;
  background-color: #ffffff;
}

.small {
  font-size: 120px;
  color: rgb(183, 190, 227);
  line-height: 182px;
  text-align: center;
  user-select: none;
  width: 182px;
  height: 182px;
  cursor: pointer;
}

.small:nth-child(1),
.small:nth-child(2),
.small:nth-child(4),
.small:nth-child(5) {
  border-right: 12px solid var(--bgc);
  border-bottom: 12px solid var(--bgc);
}

.small:nth-child(3),
.small:nth-child(6) {
  border-bottom: 12px solid var(--bgc);
}

.small:nth-child(7),
.small:nth-child(8) {
  border-right: 12px solid var(--bgc);
}

.text {
  text-align: center;
  color: var(--bgc);
}
 JavaScript:
window.addEventListener('load', function () {
  const arr = Array(9).fill(null)

  let box = this.document.querySelector('.box')
  let small_boxes = this.document.querySelectorAll('.small')
  box.addEventListener('click', function (e) {
    if (e.target.tagName === 'DIV') {
      let id = +e.target.dataset.id
      if (getCount(arr, 1) <= getCount(arr, 2)) {
        if (arr[id - 1] === null) {
          arr[id - 1] = 1
          console.log(arr)
          render()
        } else {
          alert('请在空白处添加')
        }
      } else {
        if (arr[id - 1] === null) {
          arr[id - 1] = 2
          console.log(arr)
          render()
        } else {
          alert('请在空白处添加')
        }
      }
      //判断是否被填满
      if (allSet()) {
        let time0 = setTimeout(function () {
          alert('平局')
          arr.fill(null)
          small_boxes.forEach(function (small_box) {
            console.log(small_box)
            small_box.innerHTML = ''; // 清空每个文本框
          });
          clearTimeout(time0)
        }, 300)
      }

      //判断是否有一方赢
      if (getCount(arr, 1) >= 3 || getCount(arr, 2) >= 3) {
        let time = setTimeout(function () {

          let win = winner()
          if (win != -1) {
            if (win === 1) {
              alert('笑脸成功')
            } else if (win === 2) {
              alert('哭脸成功')
            }
            arr.fill(null)
            small_boxes.forEach(function (small_box) {
              console.log(small_box)
              small_box.innerHTML = ''; // 清空每个文本框
            });
            clearTimeout(time)
          }
        }, 400)
      }
    }
  })

  function allSet() {
    for (let i of arr) {
      if (i == null) {
        return false
      }
    }
    return true
  }

  function render() {
    small_boxes.forEach(function (small_box) {
      small_box.innerHTML = ''; // 清空每个文本框
    });
    for (let i = 0; i < 9; i++) {
      let smal = document.querySelector(`[data-id="${i + 1}"]`)
      if (arr[i] === 1) {
        smal.innerHTML = '&#xe68b;'
      }
      else if (arr[i] === 2) {
        smal.innerHTML = '&#xe68e;'
      } else {
        smal.innerHTML = ''
      }
    }
  }

  //判断是否成功
  function winner() {
    const winningCombinations = [
      [0, 1, 2], [3, 4, 5], [6, 7, 8],
      [0, 3, 6], [1, 4, 7], [2, 5, 8],
      [0, 4, 8], [2, 4, 6]
    ];

    for (let combo of winningCombinations) {
      if (arr[combo[0]] && arr[combo[0]] === arr[combo[1]] && arr[combo[1]] === arr[combo[2]]) {
        return arr[combo[0]];
      }
    }

    return -1;
  }


  //返回某个数存在的个数
  function getCount(arr, value) {
    return arr.filter(item => item === value).length;
  }

}
)

 到这里就讲完了,感谢大家的观看!!!

  • 88
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 62
    评论
评论 62
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值