文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

HarmonyOS - 方舟开发框架ArkUI基于JSAPI实现五子棋游戏

2024-12-02 05:21

关注

​想了解更多内容,请访问:​

​51CTO和华为官方合作共建的鸿蒙技术社区​

​https://ost.51cto.com​

前言

最近逛社区发现已经有童鞋实现了java版的五子棋了,作为前端开发人员,怎能没有js版的五子棋呢,所以赶紧撸起来。

效果展示

实现过程

一、 绘制棋盘

首先我们使用css绘制棋盘,绘制一个14*14的正方形格子棋盘,但是需要注意,因为我们落子是落在四个格子之间的交界点上的,而不是落在格子里的,所以怎办呢?我们可以先绘制一个15*15的辅助正方形格子,然后再在其中间绘制一个14*14,这样落棋在15*15的格子里,而在14*14的格子里就可以看到落棋是在交界点里。

首先绘制一个15*15的正方形格子。

2. 然后再在其中间绘制一个14*14的正方形格子,这样的话,棋子就绘制在15*15的格子里,而在14*14的棋盘里就显示是在格子交界点上了。

最后把15*15的边距去掉,就得到一个正常的14*14的棋盘了,怎样是不是很漂亮。

做过前端开发的同学知道其实不需要这么麻烦的,直接绘制一个14*14的格子就可以了,可以使用css的::before和::after选择器来绘制格子线条。一开始也想用这么这样处理的,但是发现在目前好像还没集成这两个选择器进来,这个后续估计会更新,敬请期待。

二、实现落棋功能

首先我们在data声明一个arr为15*15的空数组,也就是长度为225的空数组。数组值只能更新为:

在标签里定义两个class来绘制黑棋和白棋。

<div
class="li{{item == '1' ? 'black' : ''}} {{item == '-1' ? 'white': ''}}"
for="{{(index,item) in arr}}"
tid="item"
onclick="play(index)"
>div>

在点击play落棋时,传入当前落棋的位置。

play(e){
// 针对数组内的数据修改,请使用splice方法生效数据绑定变更
this.arr.splice(e,1,'1');
}

上面代码传入1,则点击显示黑棋,看看效果怎样。

当然到这里还不行,需要做交换走棋,黑棋走完,到白棋走,并且走过的位置不允许再走棋。

在data定义holder为当前持棋者:

play(e){
if(this.arr[e] == '1' || this.arr[e] == '-1'){
console.log('该处已经有棋了');
return false;
}
// 针对数组内的数据修改,请使用splice方法生效数据绑定变更
this.arr.splice(e,1,this.holder);
// 交换走棋
this.holder = this.holder == '1' ? '-1' : '1';
},


三、计算赢棋方式

我们都知道要赢棋就得同色5颗棋子连成一条线,包括横向,竖向,斜向,斜向左边和斜向右边四种方式。那么我们就要把这几种方式拆分出来一一计算统计。

通过上面的序号,我们不难发现几个规律。

1、横向赢棋方式

横向赢棋方式是五个棋子每两两相差一个数值,所以每相邻棋子就是一个+1和-1的过程。

2、竖向赢棋方式

竖向赢棋方式上下连成一排,我们知道一行只有15个格子,每个棋子都相差15数值,所以每相邻棋子之间都是+15和-15的过程。

3、左斜向赢棋

左斜方向通过观察不难发现每两两棋子之间相差+14和-14。

4、右斜向赢棋

右边斜方向也可以看出每相邻棋子之间相差+16和16。

四、实现赢棋计算

通过上面一比较,是不是瞬间就觉得其实没那么难了呢,我们只要计算好每次落棋的序号和之前落棋的序号进行一对比,只要满足条件的五个棋子,就赢棋了。

实现思路: 以黑棋、横向为例子,通过递归算法,通过计算+1 || -1是否都有黑棋的记录,有则记录累计一次,每次计算完成,则去判断当前累计次数是否等于5,如果不是,则还没有赢,如果为5次,则说明赢棋了。

实现代码如下:

//id: 当前棋子的序号 d: 计算方式,比如横向是 +1-1arr是累计下来的序号结果。 
compute(id,d,arr){
id = parseInt(id);
if(this.arr[id + d] && this.arr[id + d] == this.holder){
arr.push(id);
this.compute(id + d, d, arr);
} else{
arr.push(id);
}
},

判断是否赢棋的方法:

// 判断是否赢了
getResult(arr){
if(arr.length > 5){
console.log(this.holder + '赢棋'); //this.holder是定义的当前下棋的一方
// 累计清0
arr.length = 0;
} else {
// 累计清0
arr.length = 0;
}
},

我们在每次点击下棋的时候,都调用一次统计累计次数方法和计算赢棋的方法。

// 横向赢方法
this.compute(e, 1, this.arr1); //arr1是定义好的累计次数多数组
this.compute(e, -1, this.arr1);
this.getResult(this.arr1);

结合上面计算方式,我们其他的赢棋方式一样可以这样统计来计算。

// 点击下棋方法
play(e){
if(this.isEnd) return;
if(this.arr[e] == '1' || this.arr[e] == '-1'){
console.log('该处已经有棋了');
return false;
}
// 针对数组内的数据修改,请使用splice方法生效数据绑定变更
this.arr.splice(e,1,this.holder);
// 横向赢方法
this.compute(e, 1, this.arr1);
this.compute(e, -1, this.arr1);
this.getResult(this.arr1);
// 竖向赢方法
this.compute(e, 15, this.arr1);
this.compute(e, -15, this.arr1);
this.getResult(this.arr1);
//右斜赢方法
this.compute(e, 14, this.arr1);
this.compute(e, -14, this.arr1);
this.getResult(this.arr1);
// 左斜赢方法
this.compute(e, 16, this.arr1);
this.compute(e, -16, this.arr1);
this.getResult(this.arr1);
// 交换走棋
this.holder = this.holder == '1' ? '-1' : '1';

下面看看效果。

到这里结束了吗?不,还没结束,这里还存在一些bug问题,比如说我们横向的时候是通过计算两棋子之间是否存在+1和-1的关系,但是如果两个棋子是14,15呢?这时候是已经换行了,显然是不能成立的,但是计算结果这种方式是成立的。所以我们要解决掉这个问题,包括斜向。

五、优化计算方法

其实无非两种结果,一种就是换行了,+1的时候换行到第一列数值了,-1的时候换行到最后一列数值了,那么我们把第一列和最后一列单独拉出来,进行比较。

下面我们来用代码实现。

// id: 为原id+d, d: 为计算方式。
scree(id,d){
if((d == 1 && this.colOne.indexOf(id) > -1)
|| (d == -1 && this.colEnd.indexOf(id) > -1)
|| (d == 14 && this.colEnd.indexOf(id) > -1)
|| (d == -14 && this.colOne.indexOf(id) > -1)
|| (d == 16 && this.colOne.indexOf(id) > -1)
|| (d == -16 && this.colEnd.indexOf(id) > -1)){
return false;
}
return true;
},

最后,我们在计算判断的时候加上这个判断条件即可 this.scree(id+d,d)。

compute(id,d,arr){
id = parseInt(id);
if(this.arr[id + d] && this.arr[id + d] == this.holder && this.scree(id+d,d)){
arr.push(id);
this.compute(id + d, d, arr);
} else{
arr.push(id);
}
},

最终的效果

源码地址:

https://gitee.com/yango520/gobang

总结

该方法是使用div+css+js实现的双人对战游戏,在使用css的时候发现相比web端的属性,还是少了很多,比如绘制棋盘的时候想用::before和::after选择器来绘制,但是发现当前还没有这个属性,还有想绘制一个好看有弧度高光的棋子,想使用内阴影实现,但是目前也还并不支持内阴影。不过相信后续会更新,这样web前端开发上手HarmonyOS JSAPI就容易多了。

​想了解更多内容,请访问:​

​51CTO和华为官方合作共建的鸿蒙技术社区​

​https://ost.51cto.com​

来源:鸿蒙社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯