经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Vue.js » 查看文章
Vue实现五子棋小游戏
来源:jb51  时间:2022/5/9 14:22:35  对本文有异议

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

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. ?? ?<meta charset="utf-8">
  6. ?? ?<title>五子棋</title>
  7. ?? ?<script src="./configJS/vue.js"></script>
  8. ?? ?<script src="./configJS/jQuery 1.10.2.js"></script>
  9. ?? ?<style>
  10. ?? ??? ?.fiveInRow {
  11. ?? ??? ??? ?position: absolute;
  12. ?? ??? ??? ?width: 100%;
  13. ?? ??? ?}
  14.  
  15. ?? ??? ?.fiveStar {
  16. ?? ??? ??? ?position: absolute;
  17. ?? ??? ??? ?display: flex;
  18. ?? ??? ??? ?width: 542px;
  19. ?? ??? ??? ?height: 720px;
  20. ?? ??? ??? ?margin: -24px 65px;
  21. ?? ??? ??? ?justify-content: space-around;
  22. ?? ??? ??? ?align-items: center;
  23. ?? ??? ?}
  24.  
  25. ?? ??? ?.starGroup {
  26. ?? ??? ??? ?height: 100%;
  27. ?? ??? ??? ?display: flex;
  28. ?? ??? ??? ?flex-direction: column;
  29. ?? ??? ??? ?justify-content: space-around;
  30. ?? ??? ?}
  31.  
  32. ?? ??? ?.star {
  33. ?? ??? ??? ?width: 10px;
  34. ?? ??? ??? ?height: 10px;
  35. ?? ??? ??? ?border-radius: 50%;
  36. ?? ??? ??? ?background: black;
  37. ?? ??? ?}
  38.  
  39. ?? ??? ?.boxRow {
  40. ?? ??? ??? ?position: absolute;
  41. ?? ??? ??? ?display: flex;
  42. ?? ??? ??? ?margin: 20px;
  43. ?? ??? ??? ?border: 1px solid black;
  44. ?? ??? ??? ?box-sizing: border-box;
  45. ?? ??? ?}
  46.  
  47. ?? ??? ?.box {
  48. ?? ??? ??? ?width: 45px;
  49. ?? ??? ??? ?height: 45px;
  50. ?? ??? ??? ?border: 1px solid black;
  51. ?? ??? ??? ?box-sizing: border-box;
  52. ?? ??? ?}
  53.  
  54. ?? ??? ?.chessBlock {
  55. ?? ??? ??? ?position: absolute;
  56. ?? ??? ??? ?margin: 20px;
  57. ?? ??? ?}
  58.  
  59. ?? ??? ?.chessBox {
  60. ?? ??? ??? ?position: absolute;
  61. ?? ??? ??? ?z-index: 9;
  62. ?? ??? ??? ?width: 42px;
  63. ?? ??? ??? ?height: 42px;
  64. ?? ??? ??? ?display: flex;
  65. ?? ??? ??? ?justify-content: center;
  66. ?? ??? ??? ?align-items: center;
  67. ?? ??? ?}
  68.  
  69. ?? ??? ?.chess {
  70. ?? ??? ??? ?width: 40px;
  71. ?? ??? ??? ?height: 40px;
  72. ?? ??? ??? ?border-radius: 50%;
  73. ?? ??? ??? ?border: 1px solid black;
  74. ?? ??? ??? ?box-sizing: border-box;
  75. ?? ??? ?}
  76.  
  77. ?? ??? ?.overCover {
  78. ?? ??? ??? ?position: absolute;
  79. ?? ??? ??? ?display: flex;
  80. ?? ??? ??? ?flex-direction: column;
  81. ?? ??? ??? ?justify-content: center;
  82. ?? ??? ??? ?align-items: center;
  83. ?? ??? ??? ?width: 632px;
  84. ?? ??? ??? ?height: 632px;
  85. ?? ??? ??? ?color: red;
  86. ?? ??? ??? ?z-index: 11;
  87. ?? ??? ?}
  88.  
  89. ?? ??? ?.btnGroup {
  90. ?? ??? ??? ?position: absolute;
  91. ?? ??? ??? ?top: 700px;
  92. ?? ??? ??? ?left: 235px;
  93. ?? ??? ??? ?display: flex;
  94. ?? ??? ?}
  95.  
  96. ?? ??? ?.btnGroup button {
  97. ?? ??? ??? ?margin: 0 10px;
  98. ?? ??? ?}
  99. ?? ?</style>
  100. </head>
  101.  
  102. <body>
  103. ?? ?<div class="fiveInRow">
  104. ?? ??? ?<!-- 棋盘五星层 -->
  105. ?? ??? ?<div class="fiveStar">
  106. ?? ??? ??? ?<div class="starGroup">
  107. ?? ??? ??? ??? ?<div class="star"></div>
  108. ?? ??? ??? ??? ?<div class="star"></div>
  109. ?? ??? ??? ?</div>
  110. ?? ??? ??? ?<div class="star"></div>
  111. ?? ??? ??? ?<div class="starGroup">
  112. ?? ??? ??? ??? ?<div class="star"></div>
  113. ?? ??? ??? ??? ?<div class="star"></div>
  114. ?? ??? ??? ?</div>
  115. ?? ??? ?</div>
  116. ?? ??? ?<!-- 落子层 -->
  117. ?? ??? ?<div class="chessBlock"></div>
  118. ?? ??? ?<!-- 棋盘网格层 -->
  119. ?? ??? ?<div class="boxRow" @click="downChess($event)"></div>
  120. ?? ??? ?<!-- 功能BTN -->
  121. ?? ??? ?<div class="btnGroup">
  122. ?? ??? ??? ?<button @click="giveUp()">认输</button>
  123. ?? ??? ??? ?<button @click="regret()">悔棋</button>
  124. ?? ??? ??? ?<button @click="openNew()">重开</button>
  125. ?? ??? ?</div>
  126. ?? ?</div>
  127. </body>
  128.  
  129. <script>
  130. ?? ?new Vue({
  131. ?? ??? ?el: ".fiveInRow",
  132. ?? ??? ?data: {
  133. ?? ??? ??? ?boxSize: 15, //棋盘大小
  134. ?? ??? ??? ?chessType: "black", //棋子类型,默认为黑
  135. ?? ??? ??? ?blackList: [], //黑子列表
  136. ?? ??? ??? ?whiteList: [], //白子列表
  137. ?? ??? ??? ?totleNum: 0, //落子总数
  138. ?? ??? ??? ?isOver: 0 //游戏是否结束
  139. ?? ??? ?},
  140. ?? ??? ?created() {
  141. ?? ??? ??? ?this.createBox()
  142. ?? ??? ?},
  143. ?? ??? ?watch: {
  144. ?? ??? ??? ?totleNum(val) {
  145. ?? ??? ??? ??? ?// 监听棋盘落子数
  146. ?? ??? ??? ??? ?let boxRow = $(".boxRow")[0];
  147. ?? ??? ??? ??? ?let overCover = `<div class="overCover">
  148. ?? ??? ??? ??? ??? ?<h1 style="color:red;">棋盘满了,下一把吧!!!</h1>
  149. ?? ??? ??? ??? ?</div>`;
  150. ?? ??? ??? ??? ?if (val === this.boxSize * this.boxSize) {
  151. ?? ??? ??? ??? ??? ?boxRow.innerHTML += overCover;
  152. ?? ??? ??? ??? ??? ?this.isOver = 1;
  153. ?? ??? ??? ??? ?}
  154. ?? ??? ??? ?}
  155. ?? ??? ?},
  156. ?? ??? ?methods: {
  157. ?? ??? ??? ?createBox() {
  158. ?? ??? ??? ??? ?// 创建棋盘网格
  159. ?? ??? ??? ??? ?let box = `<div class="box"></div>`;
  160. ?? ??? ??? ??? ?let boxRow = $(".boxRow")[0];
  161. ?? ??? ??? ??? ?for (let i = 1; i < this.boxSize; i++) {
  162. ?? ??? ??? ??? ??? ?let boxCloum = `<div class="boxCloum">`;
  163. ?? ??? ??? ??? ??? ?for (let j = 1; j < this.boxSize; j++) {
  164. ?? ??? ??? ??? ??? ??? ?boxCloum += box;
  165. ?? ??? ??? ??? ??? ?}
  166. ?? ??? ??? ??? ??? ?boxRow.innerHTML += boxCloum + `</div>`;
  167. ?? ??? ??? ??? ?}
  168. ?? ??? ??? ?},
  169. ?? ??? ??? ?downChess(ev) {
  170. ?? ??? ??? ??? ?// 判断落子
  171. ?? ??? ??? ??? ?if (!this.isOver) {
  172. ?? ??? ??? ??? ??? ?this.down(ev);
  173. ?? ??? ??? ??? ?} else {
  174. ?? ??? ??? ??? ??? ?let overCover = $(".overCover")[0];
  175. ?? ??? ??? ??? ??? ?let newSpan = `<h2>游戏已经结束了,请重新开始!</h2>`;
  176. ?? ??? ??? ??? ??? ?if (overCover.children.length <= 3) overCover.innerHTML += newSpan;
  177. ?? ??? ??? ??? ?}
  178. ?? ??? ??? ?},
  179. ?? ??? ??? ?down(ev) {
  180. ?? ??? ??? ??? ?// 落子
  181. ?? ??? ??? ??? ?let chessBlock = $(".chessBlock")[0];
  182. ?? ??? ??? ??? ?let layerX = this.getLayer(ev.layerX);
  183. ?? ??? ??? ??? ?let layerY = this.getLayer(ev.layerY);
  184. ?? ??? ??? ??? ?if (layerX >= 0 && layerY >= 0) {
  185. ?? ??? ??? ??? ??? ?let chessTemp = `<div?
  186. ?? ??? ??? ??? ??? ??? ?class="chessBox" style="left:${layerX-21}px;top:${layerY-21}px;"
  187. ?? ??? ??? ??? ??? ?><span class="chess" style="background:${this.chessType};"></span></div>`;
  188. ?? ??? ??? ??? ??? ?chessBlock.innerHTML += chessTemp;
  189. ?? ??? ??? ??? ??? ?this.totleNum++;
  190. ?? ??? ??? ??? ??? ?if (this.chessType === "black") {
  191. ?? ??? ??? ??? ??? ??? ?this.blackList.push([layerX, layerY]);
  192. ?? ??? ??? ??? ??? ??? ?this.isFive(this.blackList);
  193. ?? ??? ??? ??? ??? ??? ?this.chessType = "white";
  194. ?? ??? ??? ??? ??? ?} else {
  195. ?? ??? ??? ??? ??? ??? ?this.whiteList.push([layerX, layerY]);
  196. ?? ??? ??? ??? ??? ??? ?this.isFive(this.whiteList);
  197. ?? ??? ??? ??? ??? ??? ?this.chessType = "black";
  198. ?? ??? ??? ??? ??? ?}
  199. ?? ??? ??? ??? ?} else {
  200. ?? ??? ??? ??? ??? ?console.log("瞅哪呢?看准点下!");
  201. ?? ??? ??? ??? ?}
  202. ?? ??? ??? ?},
  203. ?? ??? ??? ?getLayer(val) {
  204. ?? ??? ??? ??? ?// 获取落点相对位置
  205. ?? ??? ??? ??? ?if (val % 45 <= 20) {
  206. ?? ??? ??? ??? ??? ?return val - val % 45;
  207. ?? ??? ??? ??? ?} else if (val % 45 >= 25) {
  208. ?? ??? ??? ??? ??? ?return val - val % 45 + 45;
  209. ?? ??? ??? ??? ?} else {
  210. ?? ??? ??? ??? ??? ?return -1;
  211. ?? ??? ??? ??? ?}
  212. ?? ??? ??? ?},
  213. ?? ??? ??? ?isFive(list) {
  214. ?? ??? ??? ??? ?// 判断是否落成五子
  215. ?? ??? ??? ??? ?this.isFiveInStraight(list, 0, 1);
  216. ?? ??? ??? ??? ?this.isFiveInStraight(list, 1, 0);
  217. ?? ??? ??? ??? ?this.isFiveInSlope(list, -1);
  218. ?? ??? ??? ??? ?this.isFiveInSlope(list, 1);
  219. ?? ??? ??? ?},
  220. ?? ??? ??? ?isFiveInStraight(list, a, b) {
  221. ?? ??? ??? ??? ?// 判断五子是否在水平线或垂直线
  222. ?? ??? ??? ??? ?let listSGT = {};
  223. ?? ??? ??? ??? ?for (let i = 0; i < list.length; i++) {
  224. ?? ??? ??? ??? ??? ?if (!listSGT[list[i][b]]) {
  225. ?? ??? ??? ??? ??? ??? ?listSGT[list[i][b]] = [list[i][a]];
  226. ?? ??? ??? ??? ??? ?} else {
  227. ?? ??? ??? ??? ??? ??? ?listSGT[list[i][b]].push(list[i][a]);
  228. ?? ??? ??? ??? ??? ??? ?this.isFiveNearby(listSGT[list[i][b]]);
  229. ?? ??? ??? ??? ??? ?}
  230. ?? ??? ??? ??? ?}
  231. ?? ??? ??? ?},
  232. ?? ??? ??? ?isFiveInSlope(list, slope) {
  233. ?? ??? ??? ??? ?// 判断五子是否在正斜线或反斜线
  234. ?? ??? ??? ??? ?let listSLP = {};
  235. ?? ??? ??? ??? ?for (let i = 0; i < list.length; i++) {
  236. ?? ??? ??? ??? ??? ?let b = list[i][1] - slope * list[i][0];
  237. ?? ??? ??? ??? ??? ?if (!listSLP[b]) {
  238. ?? ??? ??? ??? ??? ??? ?listSLP[b] = [list[i][0]];
  239. ?? ??? ??? ??? ??? ?} else {
  240. ?? ??? ??? ??? ??? ??? ?listSLP[b].push(list[i][0]);
  241. ?? ??? ??? ??? ??? ??? ?this.isFiveNearby(listSLP[b]);
  242. ?? ??? ??? ??? ??? ?}
  243. ?? ??? ??? ??? ?}
  244. ?? ??? ??? ?},
  245. ?? ??? ??? ?isFiveNearby(arr) {
  246. ?? ??? ??? ??? ?// 判断五子是否相邻,连成一线
  247. ?? ??? ??? ??? ?let idx = 0;
  248. ?? ??? ??? ??? ?let player = this.chessType === "black" ? "Black(黑)" : "White(白)";
  249. ?? ??? ??? ??? ?if (arr.length >= 5) {
  250. ?? ??? ??? ??? ??? ?arr.sort((a, b) => a - b)
  251. ?? ??? ??? ??? ??? ?for (let i = 1; i < arr.length; i++) {
  252. ?? ??? ??? ??? ??? ??? ?idx = arr[i] - arr[i - 1] === 45 ? idx + 1 : 0;
  253. ?? ??? ??? ??? ??? ??? ?if (idx === 4) this.gameOver(player);
  254. ?? ??? ??? ??? ??? ?}
  255. ?? ??? ??? ??? ?}
  256. ?? ??? ??? ?},
  257. ?? ??? ??? ?gameOver(player) {
  258. ?? ??? ??? ??? ?// 游戏结束
  259. ?? ??? ??? ??? ?console.log(player + " Win!!!");
  260. ?? ??? ??? ??? ?let boxRow = $(".boxRow")[0];
  261. ?? ??? ??? ??? ?let overCover = `<div class="overCover"><h1>${player} Win!!!</h1></div>`;
  262. ?? ??? ??? ??? ?boxRow.innerHTML += overCover;
  263. ?? ??? ??? ??? ?this.isOver = 1;
  264. ?? ??? ??? ?},
  265. ?? ??? ??? ?giveUp() {
  266. ?? ??? ??? ??? ?// 认输投降
  267. ?? ??? ??? ??? ?let player = this.chessType === "black" ? "White(白)" : "Black(黑)";
  268. ?? ??? ??? ??? ?if (!this.isOver) this.gameOver(player);
  269. ?? ??? ??? ?},
  270. ?? ??? ??? ?regret() {
  271. ?? ??? ??? ??? ?// 悔棋
  272. ?? ??? ??? ??? ?if (this.totleNum > 0 && !this.isOver) {
  273. ?? ??? ??? ??? ??? ?let chessBlock = $(".chessBlock")[0];
  274. ?? ??? ??? ??? ??? ?chessBlock.removeChild(chessBlock.children[--this.totleNum]);
  275. ?? ??? ??? ??? ??? ?if (this.chessType === "black") {
  276. ?? ??? ??? ??? ??? ??? ?this.whiteList.pop();
  277. ?? ??? ??? ??? ??? ??? ?this.chessType = "white";
  278. ?? ??? ??? ??? ??? ?} else {
  279. ?? ??? ??? ??? ??? ??? ?this.blackList.pop();
  280. ?? ??? ??? ??? ??? ??? ?this.chessType = "black";
  281. ?? ??? ??? ??? ??? ?}
  282. ?? ??? ??? ??? ?} else {
  283. ?? ??? ??? ??? ??? ?console.log("一个子都没有,悔个鸡儿悔!");
  284. ?? ??? ??? ??? ?}
  285. ?? ??? ??? ?},
  286. ?? ??? ??? ?openNew() {
  287. ?? ??? ??? ??? ?// 重新开始
  288. ?? ??? ??? ??? ?let chessBlock = $(".chessBlock")[0];
  289. ?? ??? ??? ??? ?let boxRow = $(".boxRow")[0];
  290. ?? ??? ??? ??? ?for (let i = this.totleNum - 1; i >= 0; i--) {
  291. ?? ??? ??? ??? ??? ?chessBlock.removeChild(chessBlock.children[i]);
  292. ?? ??? ??? ??? ?}
  293. ?? ??? ??? ??? ?if (boxRow.children[14]) boxRow.removeChild(boxRow.children[14]);
  294. ?? ??? ??? ??? ?this.chessType = "black";
  295. ?? ??? ??? ??? ?this.blackList = [];
  296. ?? ??? ??? ??? ?this.whiteList = [];
  297. ?? ??? ??? ??? ?this.totleNum = this.isOver = 0;
  298. ?? ??? ??? ?}
  299. ?? ??? ?}
  300. ?? ?})
  301. </script>
  302.  
  303. </html>

主要思路

1.画棋盘

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

2.落子

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

 

3.判断获胜条件

  1. isFive(list) {
  2. ?? ??? ??? ??? ?// 判断是否落成五子
  3. ?? ??? ??? ??? ?this.isFiveInStraight(list, 0, 1);
  4. ?? ??? ??? ??? ?this.isFiveInStraight(list, 1, 0);
  5. ?? ??? ??? ??? ?this.isFiveInSlope(list, -1);
  6. ?? ??? ??? ??? ?this.isFiveInSlope(list, 1);
  7. ?? ??? ??? ?},
  8. ?? ??? ??? ?isFiveInStraight(list, a, b) {
  9. ?? ??? ??? ??? ?// 判断五子是否在水平线或垂直线
  10. ?? ??? ??? ??? ?let listSGT = {};
  11. ?? ??? ??? ??? ?for (let i = 0; i < list.length; i++) {
  12. ?? ??? ??? ??? ??? ?if (!listSGT[list[i][b]]) {
  13. ?? ??? ??? ??? ??? ??? ?listSGT[list[i][b]] = [list[i][a]];
  14. ?? ??? ??? ??? ??? ?} else {
  15. ?? ??? ??? ??? ??? ??? ?listSGT[list[i][b]].push(list[i][a]);
  16. ?? ??? ??? ??? ??? ??? ?this.isFiveNearby(listSGT[list[i][b]]);
  17. ?? ??? ??? ??? ??? ?}
  18. ?? ??? ??? ??? ?}
  19. ?? ??? ??? ?},
  20. ?? ??? ??? ?isFiveInSlope(list, slope) {
  21. ?? ??? ??? ??? ?// 判断五子是否在正斜线或反斜线
  22. ?? ??? ??? ??? ?let listSLP = {};
  23. ?? ??? ??? ??? ?for (let i = 0; i < list.length; i++) {
  24. ?? ??? ??? ??? ??? ?let b = list[i][1] - slope * list[i][0];
  25. ?? ??? ??? ??? ??? ?if (!listSLP[b]) {
  26. ?? ??? ??? ??? ??? ??? ?listSLP[b] = [list[i][0]];
  27. ?? ??? ??? ??? ??? ?} else {
  28. ?? ??? ??? ??? ??? ??? ?listSLP[b].push(list[i][0]);
  29. ?? ??? ??? ??? ??? ??? ?this.isFiveNearby(listSLP[b]);
  30. ?? ??? ??? ??? ??? ?}
  31. ?? ??? ??? ??? ?}
  32. ?? ??? ??? ?},
  33. ?? ??? ??? ?isFiveNearby(arr) {
  34. ?? ??? ??? ??? ?// 判断五子是否相邻,连成一线
  35. ?? ??? ??? ??? ?let idx = 0;
  36. ?? ??? ??? ??? ?let player = this.chessType === "black" ? "Black(黑)" : "White(白)";
  37. ?? ??? ??? ??? ?if (arr.length >= 5) {
  38. ?? ??? ??? ??? ??? ?arr.sort((a, b) => a - b)
  39. ?? ??? ??? ??? ??? ?for (let i = 1; i < arr.length; i++) {
  40. ?? ??? ??? ??? ??? ??? ?idx = arr[i] - arr[i - 1] === 45 ? idx + 1 : 0;
  41. ?? ??? ??? ??? ??? ??? ?if (idx === 4) this.gameOver(player);
  42. ?? ??? ??? ??? ??? ?}
  43. ?? ??? ??? ??? ?}
  44. ?? ??? ??? ?},

这里主要有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。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号