本文实例为大家分享了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了.
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次获胜.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。