当前位置:首页 > 开发教程 > js/jQuery教程 >

Vue实现五子棋小游戏

时间:2022-05-09 14:31 来源:未知 作者:Believe yourself 收藏

这篇文章主要为大家详细介绍了Vue实现五子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Vue实现五子棋小游戏的具体代码,供大家参考,具体内容如下

<!DOCTYPE html>
<html>

<head>
 <meta charset="utf-8">
 <title>五子棋</title>
 <script src="./configJS/vue.js"></script>
 <script src="./configJS/jQuery 1.10.2.js"></script>
 <style>
  .fiveInRow {
   position: absolute;
   width: 100%;
  }

  .fiveStar {
   position: absolute;
   display: flex;
   width: 542px;
   height: 720px;
   margin: -24px 65px;
   justify-content: space-around;
   align-items: center;
  }

  .starGroup {
   height: 100%;
   display: flex;
   flex-direction: column;
   justify-content: space-around;
  }

  .star {
   width: 10px;
   height: 10px;
   border-radius: 50%;
   background: black;
  }

  .boxRow {
   position: absolute;
   display: flex;
   margin: 20px;
   border: 1px solid black;
   box-sizing: border-box;
  }

  .box {
   width: 45px;
   height: 45px;
   border: 1px solid black;
   box-sizing: border-box;
  }

  .chessBlock {
   position: absolute;
   margin: 20px;
  }

  .chessBox {
   position: absolute;
   z-index: 9;
   width: 42px;
   height: 42px;
   display: flex;
   justify-content: center;
   align-items: center;
  }

  .chess {
   width: 40px;
   height: 40px;
   border-radius: 50%;
   border: 1px solid black;
   box-sizing: border-box;
  }

  .overCover {
   position: absolute;
   display: flex;
   flex-direction: column;
   justify-content: center;
   align-items: center;
   width: 632px;
   height: 632px;
   color: red;
   z-index: 11;
  }

  .btnGroup {
   position: absolute;
   top: 700px;
   left: 235px;
   display: flex;
  }

  .btnGroup button {
   margin: 0 10px;
  }
 </style>
</head>

<body>
 <div class="fiveInRow">
  <!-- 棋盘五星层 -->
  <div class="fiveStar">
   <div class="starGroup">
    <div class="star"></div>
    <div class="star"></div>
   </div>
   <div class="star"></div>
   <div class="starGroup">
    <div class="star"></div>
    <div class="star"></div>
   </div>
  </div>
  <!-- 落子层 -->
  <div class="chessBlock"></div>
  <!-- 棋盘网格层 -->
  <div class="boxRow" @click="downChess($event)"></div>
  <!-- 功能BTN -->
  <div class="btnGroup">
   <button @click="giveUp()">认输</button>
   <button @click="regret()">悔棋</button>
   <button @click="openNew()">重开</button>
  </div>
 </div>
</body>

<script>
 new Vue({
  el: ".fiveInRow",
  data: {
   boxSize: 15, //棋盘大小
   chessType: "black", //棋子类型,默认为黑
   blackList: [], //黑子列表
   whiteList: [], //白子列表
   totleNum: 0, //落子总数
   isOver: 0 //游戏是否结束
  },
  created() {
   this.createBox()
  },
  watch: {
   totleNum(val) {
    // 监听棋盘落子数
    let boxRow = $(".boxRow")[0];
    let overCover = `<div class="overCover">
     <h1 style="color:red;">棋盘满了,下一把吧!!!</h1>
    </div>`;
    if (val === this.boxSize * this.boxSize) {
     boxRow.innerHTML += overCover;
     this.isOver = 1;
    }
   }
  },
  methods: {
   createBox() {
    // 创建棋盘网格
    let box = `<div class="box"></div>`;
    let boxRow = $(".boxRow")[0];
    for (let i = 1; i < this.boxSize; i++) {
     let boxCloum = `<div class="boxCloum">`;
     for (let j = 1; j < this.boxSize; j++) {
      boxCloum += box;
     }
     boxRow.innerHTML += boxCloum + `</div>`;
    }
   },
   downChess(ev) {
    // 判断落子
    if (!this.isOver) {
     this.down(ev);
    } else {
     let overCover = $(".overCover")[0];
     let newSpan = `<h2>游戏已经结束了,请重新开始!</h2>`;
     if (overCover.children.length <= 3) overCover.innerHTML += newSpan;
    }
   },
   down(ev) {
    // 落子
    let chessBlock = $(".chessBlock")[0];
    let layerX = this.getLayer(ev.layerX);
    let layerY = this.getLayer(ev.layerY);
    if (layerX >= 0 && layerY >= 0) {
     let chessTemp = `<div
      class="chessBox" style="left:${layerX-21}px;top:${layerY-21}px;"
     ><span class="chess" style="background:${this.chessType};"></span></div>`;
     chessBlock.innerHTML += chessTemp;
     this.totleNum++;
     if (this.chessType === "black") {
      this.blackList.push([layerX, layerY]);
      this.isFive(this.blackList);
      this.chessType = "white";
     } else {
      this.whiteList.push([layerX, layerY]);
      this.isFive(this.whiteList);
      this.chessType = "black";
     }
    } else {
     console.log("瞅哪呢看准点下!");
    }
   },
   getLayer(val) {
    // 获取落点相对位置
    if (val % 45 <= 20) {
     return val - val % 45;
    } else if (val % 45 >= 25) {
     return val - val % 45 + 45;
    } else {
     return -1;
    }
   },
   isFive(list) {
    // 判断是否落成五子
    this.isFiveInStraight(list, 0, 1);
    this.isFiveInStraight(list, 1, 0);
    this.isFiveInSlope(list, -1);
    this.isFiveInSlope(list, 1);
   },
   isFiveInStraight(list, a, b) {
    // 判断五子是否在水平线或垂直线
    let listSGT = {};
    for (let i = 0; i < list.length; i++) {
     if (!listSGT[list[i][b]]) {
      listSGT[list[i][b]] = [list[i][a]];
     } else {
      listSGT[list[i][b]].push(list[i][a]);
      this.isFiveNearby(listSGT[list[i][b]]);
     }
    }
   },
   isFiveInSlope(list, slope) {
    // 判断五子是否在正斜线或反斜线
    let listSLP = {};
    for (let i = 0; i < list.length; i++) {
     let b = list[i][1] - slope * list[i][0];
     if (!listSLP[b]) {
      listSLP[b] = [list[i][0]];
     } else {
      listSLP[b].push(list[i][0]);
      this.isFiveNearby(listSLP[b]);
     }
    }
   },
   isFiveNearby(arr) {
    // 判断五子是否相邻,连成一线
    let idx = 0;
    let player = this.chessType === "black"  "Black(黑)" : "White(白)";
    if (arr.length >= 5) {
     arr.sort((a, b) => a - b)
     for (let i = 1; i < arr.length; i++) {
      idx = arr[i] - arr[i - 1] === 45  idx + 1 : 0;
      if (idx === 4) this.gameOver(player);
     }
    }
   },
   gameOver(player) {
    // 游戏结束
    console.log(player + " Win!!!");
    let boxRow = $(".boxRow")[0];
    let overCover = `<div class="overCover"><h1>${player} Win!!!</h1></div>`;
    boxRow.innerHTML += overCover;
    this.isOver = 1;
   },
   giveUp() {
    // 认输投降
    let player = this.chessType === "black"  "White(白)" : "Black(黑)";
    if (!this.isOver) this.gameOver(player);
   },
   regret() {
    // 悔棋
    if (this.totleNum > 0 && !this.isOver) {
     let chessBlock = $(".chessBlock")[0];
     chessBlock.removeChild(chessBlock.children[--this.totleNum]);
     if (this.chessType === "black") {
      this.whiteList.pop();
      this.chessType = "white";
     } else {
      this.blackList.pop();
      this.chessType = "black";
     }
    } else {
     console.log("一个子都没有,悔个鸡儿悔!");
    }
   },
   openNew() {
    // 重新开始
    let chessBlock = $(".chessBlock")[0];
    let boxRow = $(".boxRow")[0];
    for (let i = this.totleNum - 1; i >= 0; i--) {
     chessBlock.removeChild(chessBlock.children[i]);
    }
    if (boxRow.children[14]) boxRow.removeChild(boxRow.children[14]);
    this.chessType = "black";
    this.blackList = [];
    this.whiteList = [];
    this.totleNum = this.isOver = 0;
   }
  }
 })
</script>

</html>

主要思路

1.画棋盘

小雨采用了最直接, 最暴力的方式, 就是把一堆小方块堆起来, 加上边框, 棋盘有了…什么 你问我那五个点怎么画上去的 页面上试出来的.

2.落子

落子是比较讲究的. 首先获取鼠标点击事件中的layerX, layerY, 这是鼠标点击的相对位置, 在本例中是比较好用的. 然后通过 getLayer() 函数获取点击点最近的网格点, 如下图, 鼠标点击在红框内则落子. 最后在相比网格点半个棋子位的地方落子就OK了.

Vue实现五子棋小游戏

3.判断获胜条件

isFive(list) {
    // 判断是否落成五子
    this.isFiveInStraight(list, 0, 1);
    this.isFiveInStraight(list, 1, 0);
    this.isFiveInSlope(list, -1);
    this.isFiveInSlope(list, 1);
   },
   isFiveInStraight(list, a, b) {
    // 判断五子是否在水平线或垂直线
    let listSGT = {};
    for (let i = 0; i < list.length; i++) {
     if (!listSGT[list[i][b]]) {
      listSGT[list[i][b]] = [list[i][a]];
     } else {
      listSGT[list[i][b]].push(list[i][a]);
      this.isFiveNearby(listSGT[list[i][b]]);
     }
    }
   },
   isFiveInSlope(list, slope) {
    // 判断五子是否在正斜线或反斜线
    let listSLP = {};
    for (let i = 0; i < list.length; i++) {
     let b = list[i][1] - slope * list[i][0];
     if (!listSLP[b]) {
      listSLP[b] = [list[i][0]];
     } else {
      listSLP[b].push(list[i][0]);
      this.isFiveNearby(listSLP[b]);
     }
    }
   },
   isFiveNearby(arr) {
    // 判断五子是否相邻,连成一线
    let idx = 0;
    let player = this.chessType === "black"  "Black(黑)" : "White(白)";
    if (arr.length >= 5) {
     arr.sort((a, b) => a - b)
     for (let i = 1; i < arr.length; i++) {
      idx = arr[i] - arr[i - 1] === 45  idx + 1 : 0;
      if (idx === 4) this.gameOver(player);
     }
    }
   },

这里主要有4个函数: isFive(), isFiveInStraight(), isFiveInSlope() 和 isFiveNearby().

isFive(): 这个只是调用后续函数的函数, 它将获胜条件分成了4类: 横线获胜, 竖线获胜, 斜率为1的斜线获胜 和 斜率为-1的斜线获胜.

isFiveInStraight(): 判断 横线获胜 竖线获胜 的功能函数. 这里的主要难点就是listSGT 对象的创建, 能否想到要用对象来实现落子的分类, 是这个函数的关键. 在 横线获胜 中, 将落子的layerY 坐标作为对象的属性, 将有相同layerY 坐标的棋子的layerX 组成一个数组作为属性的值. 竖线获胜 同理.

isFiveInSlope(): 判断 斜率为1的斜线获胜 斜率为-1的斜线获胜 的功能函数. 与 isFiveInStraight() 不同的是, 在创建listSLP 对象时, 以直线函数 y = k x + b y = kx+by=kx+b 中截距(b) 作为对象的属性, 以落子的layerX 坐标组成的数组作为属性的值, 其实用落子的layerY坐标也是一样的.

isFiveNearby(): 判断五子是否相邻的功能函数. 此函数直接获取上两个函数中所创建对象的值, 也就是落子坐标组成的数组. 首先判断数组长度是否大于5, 毕竟能少走一步是一步嘛. 之后将数组从小到大排序, 计算相邻两位的差, 并记录. 连续记录4次获胜.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持源码搜藏网。


下一篇:没有了

js/jQuery教程阅读排行

最新文章