和comate一起,用JavaScript实现一个简易版五子棋小游戏

前言

五子棋起源于中国,是全国智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏。双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连珠者获胜。
这次和Baidu Comate智能代码助手共同完成这个小游戏。

在这里插入图片描述
先看一下效果:

Baidu Comate

JavaScript实现

在vscode上打开comate,开始编写代码

定义canvas元素

用于绘制棋盘和棋子 ,并将元素的显示方式设置为块级元素:

<!-- 定义一个canvas元素用于绘制棋盘和棋子 --><canvas id="chess" width="450" height="450"></canvas>

#chess {display: block;margin: 50px auto;background-color: #f0e6d6;}

HTML部分编写完成,开始编写JavaScript代码。接下来需要获取chess元素,并定义相关变量。此时在需要编写代码的空白处回车即可触发comate智能续写功能,可以按照自己的需要选择Tab键接受或Esc键拒绝comate生成的注释或相关代码:

在这里插入图片描述
解释相关代码:

在这里插入图片描述

那么目前就已经将相应变量定义好了,并且都加上了相关注释:

在这里插入图片描述

棋盘初始化

接下来就是对棋盘初始化了,思路是将chessBoard定义为一个15*15的二维数组,并且便于后面监听棋子事件,将二维数组元素均设置为0.

在这里插入图片描述

看下效果:

在这里插入图片描述
目前是一个空白盘,我们用console.log(chessBoard)在控制台打印一下数组:
在这里插入图片描述

没有问题。

绘制棋盘

接下来需要绘制这个空白的棋盘,首先需要绘制棋盘的线条,需要绘制纵横水平线分别为15条

 // 绘制棋盘的线条function drawChessBoard() {for (let i = 0; i <= 15; i++) {context.moveTo(15+i*30, 15);context.lineTo(15+i*30, 435);context.stroke();context.moveTo(15, 15+i*30);context.lineTo(435, 15+i*30);context.stroke();}}drawChessBoard();

context.moveTo(15+i*30, 15);为例:
设置Canvas的当前路径的开始位置。每次迭代时,这个位置都会沿着x轴向右移动,每次移动30个像素。而y坐标始终为15。为了棋盘四周留有一定空隙,我们让i从0开始,因此在遍历的时候,横坐标是从15开始迭代的。

在这里插入图片描述

使用comate生成的示例代码并新建HTML文件看下效果:
在这里插入图片描述

棋盘绘制实现效果:
在这里插入图片描述

棋盘绘制完成,接下来需要绘制棋子。

绘制棋子

1:这里需要定义一个drawChess的函数,用于在五子棋游戏中绘制棋子。它接受三个参数:i表示行索引,j表示列索引,player表示当前玩家(true表示黑子,false表示白子)。可以通过修改传入的i和j的参数,去改变当前棋子的位置。
2:因为下棋是在对角线上下,因此可以采用圆弧的方法绘制一个圆形,圆心坐标为(15 + i * 30, 15 + j *> 30),半径为13,起始角度为0,结束角度为2π。

3:最后将绘制好的圆形用相应颜色填充即可;由于在前面已经定义了当前棋手player为true,这里就让当前棋手先为黑色填充,下一棋手为白色填充。

看一下效果:

在这里插入图片描述
在这里插入图片描述
将player改为false,当前棋子为白色:

在这里插入图片描述

这里棋子的填充颜色通过comate生成,效果为渐变色,让棋子更有光泽(属实没想到哈哈)

在这里插入图片描述
棋盘和棋子都绘制完成,接着开始处理玩家的下棋事件。

处理下棋事件

1:由于棋手在对角线下棋,因此要通过获取鼠标的点击,进而获得所点击位置的横纵坐标。这里获取的坐标是鼠标点击位置相对于目标元素(棋盘)左上角的偏移量。
2:我们设定的棋盘是每个格子的宽和高都是30像素;因此将横纵坐标分别除以三十向下取整,从而确定i和j(行和列)的整数索引,进而将棋子下在目标格子对角线上。

在这里插入图片描述

编写完成,我们通过控制台打印出坐标以及i、j的索引:

在这里插入图片描述

我们看到,箭头所指的地方是我点击的地方,向下取整后,棋子所在位置应该为箭头所指的交线,看来comate理解的不错。

接着,我们将通过判断当前获取的索引所在二维数组元素是否为空,来决定该位置是否能继续下棋子。

// 处理棋手的下棋事件function play(e){// 获取鼠标点击的位置const x = e.offsetX;const y = e.offsetY;// 获取鼠标点击的棋盘的位置const i = Math.floor(x / 30);const j = Math.floor(y / 30);// 判断当前位置是否为空if (chessBoard[i][j] === 0) {drawChess(i, j, player);// 将棋子添加到棋盘中chessBoard[i][j] = player ? 1 : -1;// 切换玩家player = !player;}}

调用drawChess函数在当前位置绘制棋子,传入行索引、列索引和当前玩家(true表示黑子,false表示白子)。 player = !player;:切换当前玩家,如果之前是黑子,则变为白子;如果之前是白子,则变为黑子。

让comate加上注释,并解释这一段代码

在这里插入图片描述

实现效果

在这里插入图片描述
基础的功能编写完毕,最后需要判断棋手胜负。

判断胜负

1:定义一个判断函数 judge()
2:声明当前棋手的棋子颜色和棋子的走向

在这里插入图片描述

3:要实现监测不同方位的相同颜色的连续棋子,需要用for循环进行遍历,外层for循环遍历方向,内层for循环遍历该方向上共有多少个连续的相同颜色的棋子(两个并列的for循环,一个往前找,一个往后找),并且需要定义一个计数器,来记录同一方向相同且连续的棋子数目。
这里要注意,计数器count的初始值是1,因为要准确的判断该方向上五子棋的连续性,要保证检查到第一个棋子时它已经被计入连续序列中;如果设置为0,程序会一直把检查到的一个棋子识别为一个新的序列,即使出现五子连珠也不会返回true。

// 判断棋手胜负function judge(i,j,player) {const color = player ? 1 : -1;const directions =[// 横向[0, -1], [0, 1],// 纵向[-1, 0], [1, 0],// 主对角线[-1, -1], [1, 1],// 副对角线[-1, 1], [1, -1]];// 遍历所有方向for (const [dx, dy] of directions) {// 设置计数器,初始值为1let count = 1;// 正方向遍历棋盘for (let step = 1; step < 5; step++) {// 计算当前位置const x = i +step * dx;const y = j +step * dy;// 判断是否越界if (x >=0 && x < 15 && y >= 0 && y < 15 && chessBoard[x][y] === color) {// 计数器加一count++;}else{break;}}// 反方向遍历棋盘for (let step = 1; step < 5; step++) {// 计算当前位置const x = i -step * dx;const y = j -step * dy;// 判断是否越界if (x >=0 && x < 15 && y >= 0 && y < 15 && chessBoard[x][y] === color){count++;}else{break;}}// 判断是否满足条件if (count >= 5) {return true;}}// 判断是否满足条件return false;}

4:通过调用judge()函数,提示获胜棋手:

 // 显示胜利棋手function play(e){const x = e.offsetX;const y = e.offsetY;const i = Math.floor(x / 30);const j = Math.floor(y / 30);// 判断当前位置是否为空if (chessBoard[i][j] === 0) {// 绘制棋子drawChess(i, j, player);// 添加棋子到棋盘中chessBoard[i][j] = player ? 1 : -1;// 切换玩家if (judge(i, j, player)) {// 判断是否满足条件alert(player ? '黑方胜利' : '白方胜利');return;}// 切换玩家player = !player;}}

在这里插入图片描述

至此,简易版的五子棋就完成了,当然这个还可以加入更多功能,比如给获胜方记录获胜数,询问玩家是否重开一局等功能,或者是实现人机对战的功能等。

Comate还提供了多种功能,在这里就不一 一赘述了,大家可以去体验一下:

在这里插入图片描述

在这里插入图片描述

最后

总体上说comate的智能代码续写的能力还是比较令人惊喜的,对上下问的代码和注释感知力较强。的确可以在很大程度上减少对重复代码和注释的编写。当然没有一款智能代码编写工具是万能的,不可能连个框架都没有就能利用智能插件去完成一个功能健全的满意程序。在使用时需要给它一定的引导,比如可以通过注释去提示插件你下一步需要编写什么(这种方式还是很方便的)。这样可以让我们更注重架构以及程序的功能完善。
另外对于初学者来说,安装comate插件也会对一些语法有更为针对性的认识,学习效率上肯定会有较大的提升;而且相对于人为的去给一些变量、函数命名,大模型的命名能力要强得多,能够帮助开发者有更好的命名规范意识,让代码更具可读性。
感兴趣的朋友可以点击链接去官网免费体验,利用好智能工具,更高效的编写代码!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/8057.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS NEXT应用开发之多模态页面转场动效实现案例

介绍 本示例介绍多模态页面转场动效实现&#xff1a;通过半模态转场实现半模态登录界面&#xff0c; 与全屏模态和组件转场结合实现多模态组合登录场景&#xff0c;其中手机验证码登录与账号密码登录都为组件&#xff0c; 通过TransitionEffect.move()实现组件间转场达到近似页…

在Python中获取当前线程的名字

多线程编程是一种常见的编程范式&#xff0c;它允许程序同时执行多个任务。在Python中&#xff0c;​​threading​​模块提供了对多线程编程的支持。了解和管理当前运行的线程是多线程编程中的一个重要方面。本技术博客将介绍如何在Python中获取当前线程的名字&#xff0c;并提…

Linux入门攻坚——22、通信安全基础知识及openssl、CA证书

Linux系统常用的加解密工具&#xff1a;OpenSSL&#xff0c;gpg&#xff08;是pgp的实现&#xff09; 加密算法和协议&#xff1a; 对称加密&#xff1a;加解密使用同一个秘钥&#xff1b; DES&#xff1a;Data Encryption Standard&#xff0c;数据加密标准&…

meshlab: pymeshlab保存物体的横截面(compute planar section)

一、关于环境 请参考&#xff1a;pymeshlab遍历文件夹中模型、缩放并导出指定格式-CSDN博客 二、关于代码 本文所给出代码仅为参考&#xff0c;禁止转载和引用&#xff0c;仅供个人学习。 # pymeshlab需要导入&#xff0c;其一般被命名为ml import pymeshlab as ml# 本案例所…

05.添加自定义触发器

添加自定义触发器 在系统中找到一个用户登录数量的监控项&#xff0c;用该监控项作为参考实例 测试监控项取值&#xff0c;2代表为登录系统终端数量 创建触发器 表达式设置条件&#xff0c;选择对应的监控项&#xff0c;根据对应的功能函数&#xff0c;在选择触发的结果 添…

简洁大气APP下载单页源码

源码介绍 简洁大气APP下载单页源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 效果截图 源码下载 简洁大气APP下载单页源码

Jenkins +配置邮件 centos8.5 安装部署 运维系列一

1 jenkins的war包下载地址: Download and deploy 2 xftp 等方式上传到服务器 #安装jdk tar zxvf jdk-11.0.8_linux-x64_bin.tar.gz mv jdk-11.0.8/ /usr/local/jdk vim /etc/profile export JAVA_HOME/usr/local/jdk export PATH$JAVA_HOME/bin:$PATH CLASSPATH.:$JAVA_…

中国居民消费新特征:中枢回落,即时满足,去地产化

随着收入预期和财富效应的转变&#xff0c;居民更倾向于通过短期集中式的消费来获得即时满足的快乐&#xff0c;服务消费表现出了更强的韧性。服务消费强于商品消费、消费去地产化、汽车挑大梁的特征延续。 特征一&#xff1a;消费倾向高于2020-22年&#xff0c;低于2017-19年…

传递给组件

React 组件使用 props 相互通信。每个父组件都可以通过为其子组件提供道具来将一些信息传递给子组件。Props 可能会让您想起 HTML 属性&#xff0c;但您可以通过它们传递任何 JavaScript 值&#xff0c;包括对象、数组和函数。 Props 是传递给 JSX 标签的信息。例如&#xff0…

libcity笔记:详细流程(以DeepMove为例)

1 主调用 python run_model.py --task traj_loc_pred --model DeepMove --dataset gowalla --batch_size5有task、dataset、model三个必须命令行参数batch_size一个可选命令行参数没有confg_file 1.1 libcity/utils/argument_list.py/str2bool 将字符串表示的布尔值转换为 Pyt…

结合kimi chat的爬虫实战思路

背景 想钻研一下项目组件&#xff0c;找找之后的学习方向。不能自以为是&#xff0c;所以借着网开源项目网站上公布的项目内容看一下&#xff0c;那些是我可以努力去学习的&#xff08;入门的&#xff09;。首先需要获取相关内容&#xff0c;于是爬取整理。 任务1&#xff1a…

操作系统实战(二)(linux+C语言)

实验内容 通过Linux 系统中管道通信机制&#xff0c;加深对于进程通信概念的理解&#xff0c;观察和体验并发进程间的通信和协作的效果 &#xff0c;练习利用无名管道进行进程通信的编程和调试技术。 管道pipe是进程间通信最基本的一种机制,两个进程可以通过管道一个在管道一…

[Linux] git工具的安装和使用

目录 前言 安装 1.构建仓库 2.将仓库克隆到本地 使用 1.三板斧 1.git add 新增 2.git commit 提交 3.git push 推送 2.常用指令 前言 git 是一个代码托管平台&#xff0c;它的创始人是大名鼎鼎的 Linux 之父&#xff1a; 林纳斯托瓦兹&#xff0c;git的诞生可以使我们对…

pear + pecl 安装php扩展

pear https://pear.php.net/manual/en/installation.getting.php https://pear.php.net/go-pear.phar 让 CMD 支持 utf8 > chcp 65001 卸载 > php go-pear.phar uninstall 安装 > php go-pear.phar system 12 修改 12. Name of configuration file …

解释 RESTful API 以及如何使用它构建 web 应用程序

RESTful API&#xff08;Representational State Transfer&#xff09;是一种设计风格&#xff0c;用于创建网络应用程序的 API。它基于HTTP协议&#xff0c;通过使用标准的HTTP方法&#xff08;如GET、POST、PUT和DELETE&#xff09;来实现对资源的操作。 RESTful API的设计原…

python turtle

名字动画 #SquareSpiral1.py import turtle t turtle.Pen() turtle.bgcolor("black")my_nameturtle.textinput("输入你的姓名","你的名字&#xff1f;") colors["red","yellow","purple","blue"] for…

如何在Python中实现简单的OCR(光学字符识别)?

要在Python中实现简单的OCR&#xff08;光学字符识别&#xff09;&#xff0c;可以使用开源库Tesseract。Tesseract是一个免费的OCR引擎&#xff0c;支持多种语言和平台。 以下是使用Python和Tesseract进行简单OCR的步骤&#xff1a; 安装Tesseract和Python的tesseract包&…

金融业开源软件应用 管理指南

金融业开源软件应用 管理指南 1 范围 本文件提供了金融机构在应用开源软件时的全流程管理指南&#xff0c;对开源软件的使用和管理提供了配套 组织架构、配套管理规章制度、生命周期流程管理、风险管理、存量管理、工具化管理等方面的指导。 本文件适用于金融机构规范自身对开…

ModelID

* dev_display_shape_matching_results (ModelID, red, Row5, Column5, Angle, 1, 1, 0) *利用模板进行模板匹配&#xff0c;输出坐标角度匹配分数等参数 vector_angle_to_rigid (0, 0, 0, Row5, Column5, Angle, HomMat2D) *从模板匹配函数的结果…

环信设置头像昵称(安卓android)版

在此真的要吐槽吐槽环信&#xff0c;那么大的公司&#xff0c;文档那么乱。。。真的像一坨屎一样&#xff0c;翻个demo东翻西翻&#xff0c;官网论坛看的眼瞎。。。几乎要放弃了&#xff0c;还好百度到别人的看了看弄出来了 1、首先&#xff0c;要确认自己用的是哪个环信的UI库…