写点什么

无 AI 的五子棋 Vue 项目

作者:空城机
  • 2021 年 11 月 12 日
  • 本文字数:2265 字

    阅读完需:约 7 分钟

无AI的五子棋Vue项目

五子棋

以前我曾经看视频跟着做过一个井字棋的人机对战,现在又在书栈上看到了一篇和五子棋 AI 有关的教程,所以准备动手练习一下。


当然,在写 AI 之前肯定先要把之前的准备工作都做完。要完成的基础功能如下:


  • 先把五子棋的棋盘界面搭建起来

  • 点击棋盘,可以对应生成棋子,黑白棋子的生成交叉进行

  • 棋子的位置需要生成在网格线交叉的中间位置,并且不能重复在同一位置

  • 无论黑棋或白棋哪一方有五个字相连了,就判断游戏结束,并宣布胜利者


本文中只展示部分重点代码与方法,具体代码可参考 Gitee 仓库: https://gitee.com/wzckongchengji/node_study/blob/master/pianoDemo/TS/Gobang.ts


项目搭建

项目的搭建比较简单,使用了 Vue 框架,现在页面上创建好对应 Vue 实例需要挂载的元素


<div id="Gobang" ref="Gobang" class="Gobang" v-cloak></div>
复制代码


使用Ts编写,先在 Vue 中设置好需要的data对象,说明如下:

// 棋子属性type chessInfo = {    index: number,  // 第几步    isWhite: boolean,  // 是否是白色    position: pos // 棋子位置}type pos = {    left: number, top: number}let chessInfos:chessInfo[] = [];let vm:Vue = new Vue({    el:'#Gobang',    data: {        ifGenWhite: true,  // 是否生成白色棋子        chessInfos: chessInfos,  // 棋子信息集合        curIndex: 1,  // 当前步数        maxChessNum: 0,  // 最大连续棋子数         curColor: true,  // 当前棋子颜色        isFlag: false,  //是否找到成功的棋子        successChess: chessInfos,  // 成功的棋子集合    },    mounted(){     },    methods:{    }})
复制代码



棋盘界面

棋盘的界面本来我准备使用画线的方式来构成,但是后来一想,之后棋子落点都是要按鼠标点击位置进行判断,那干脆直接拿图当背景吧


棋盘:


在元素中,棋盘元素大小我设置为了 535*535,并且背景图也是相同大小。


这样能方便之后进行计算,目前棋盘最作上角落点位置为(22,22),右下角落点位置为(512,512),每个空格的间隔为 35 像素



点击棋盘和生成棋子

创建一个点击棋盘方法,使用@click绑定在棋盘元素上面。


// 棋盘点击checkerBoardClick(event: any) {    let e = event;    // 判断点击是否在棋盘    if (e.target.getAttribute('class') != 'Gobang') return;    // 点击位置确定    let curPos:pos|boolean = this.positionSure({left: e.offsetX - 13, top: e.offsetY - 13})    if (!curPos) return ;    // 生成棋子    this.generateChess(curPos as pos);},
复制代码


在此方法中,首先判断鼠标按下的点击的元素是否是棋盘元素,然后使用positionSure方法进行点击位置判断与计算,返回出当前应该生成的棋子位置,如果没有可生成的棋子位置或者当前位置已经存在棋子,则返回false阻止下面的操作。(这里棋子位置计算代码可以去仓库中查看,这里就不作罗列了)


当前位置可以下棋,根据当前返回的棋子位置,调用generateChess方法生成棋子,将该棋子添加到棋子数组当中,并且改变ifGenWhite属性,让下一次生成的棋子颜色进行改变,增加curIndex当前步数的属性值。

// 生成棋子generateChess(position:pos) {    let chess:chessInfo = {        index: this.curIndex,        isWhite: this.ifGenWhite,        position: position    }     this.curIndex ++;  // 步数增加    this.ifGenWhite = !this.ifGenWhite; // 棋子颜色改变    this.chessInfos.push(chess);
this.sortChessInfo(); // 根据棋子左上远近重新将棋子集合排序 this.ergodicChess(); // 遍历所有棋子判断胜利方法},
复制代码


在棋子生成方法generateChess中,如果不考虑下面的棋子集合排序和胜利判断,已经可以做到简单的下棋步骤了。


棋盘上面的棋子生成是由chessInfos棋子集合在棋盘元素当中使用 v-for 遍历生成的,根据棋子元素中的属性来生成对应的位置颜色class

<!-- 棋子 --><div class="step" v-for="item of chessInfos" :class="item.isWhite?'white':'black'"    :style="{ 'left': item.position.left + 'px', 'top': item.position.top + 'px'}" >    {{ item.index }}</div>
复制代码


效果:



胜利判断

棋子的胜利判断咋一看没找到头绪,但是其实是有逻辑可循的,需要遍历所有棋子,这里棋子集合就需要进行重新排序了。


棋子排序规则:最左上角到最右下角,并且 left 距左边距离的优先级大于 top 距顶部距离优先级。


排序完成后,胜利的条件无非就是五个棋子连在一起。


所以选择一个棋子为基准后,从该棋子的右方、下方、右下、左下四个方向开始判断 是否有连续的棋子 4 个,并且颜色相同。如果存在则游戏结束,该颜色方胜利。


至于这四个方向相对烦的方向就不需要判断了,因为棋子经过排序之后是从最左上角开始进行遍历的,如果在该棋子前的都没有成功,那么该棋子左方、上方、左上这三是不会有成功的条件的(右上可能会存在)。棋子某一方向的连续棋子判断时我使用了递归,如果存在则继续往此方向进行判断直到棋子为 5 个。


棋子的胜利判断方法这里也不展示了。然后可以在棋盘界面中添加胜利遮罩,当某一方胜利时进行显示


具体效果


可以添加点击重开方法,此方法只需将之前修改过的一些 data 中对象重置即可,包括棋子集合置空。


// 重开游戏replay() {    this.chessInfos = [];    this.curColor = true;    this.successChess = [];    this.isFlag = false;    this.ifGenWhite = true;    this.curIndex = 1;}
复制代码




以上就是一款无 AI 的五子棋简单项目了,当然之后的重点肯定是添加智能的下棋对象。


就先到这里了,结束...

发布于: 1 小时前阅读数: 5
用户头像

空城机

关注

曾经沧海难为水,只是当时已惘然 2021.03.22 加入

业余作者,在线水文 主要干前端的活,业余会学学python 欢迎各位关注,互相学习,互相进步

评论

发布
暂无评论
无AI的五子棋Vue项目