原标题:原生 JS + Canvas 实现五子棋游戏

||

一、功能模块

先看下现在做完的效果:

线上体验:

https://wj704.github.io/five_game.html

主要功能模块为:

人机对战功能

悔棋功能

撤销悔棋功能二、代码详解 2.1 人机对战功能实现

从效果图可以看到,棋盘的横竖可以放的位置为15*15,通过canvas画棋盘:

//绘画棋盘

vardrawChessBoard=function(){

for(vari=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();

}

}

知道格子数后,我们先看五子棋有多少种赢法:

//赢法数组

varwins=[];

for(vari=0;i<15;i++){

wins[i]=[];

for(varj=0;j<15;j++){

wins[i][j]=[];

}

}

varcount=0;//赢法总数

//横线赢法

for(vari=0;i<15;i++){

for(varj=0;j<11;j++){

for(vark=0;k<5;k++){

wins[i][j+k][count]=true;

}

count++;

}

}

//竖线赢法

for(vari=0;i<15;i++){

for(varj=0;j<11;j++){

for(vark=0;k<5;k++){

wins[j+k][i][count]=true;

}

count++;

}

}

//正斜线赢法

for(vari=0;i<11;i++){

for(varj=0;j<11;j++){

for(vark=0;k<5;k++){

wins[i+k][j+k][count]=true;

}

count++;

}

}

//反斜线赢法

for(vari=0;i<11;i++){

for(varj=14;j>3;j--){

for(vark=0;k<5;k++){

wins[i+k][j-k][count]=true;

}

count++;

}

}

根据赢法总数定义分别保存计算机和人赢法的数组:

for(vari=0;i

myWin[i]=0;

_myWin[i]=0;

computerWin[i]=0;

_compWin[i]=0;

}

然后就是人开始下棋:

// 我,下棋

chess.οnclick=function(e){

if(over){// 游戏结束

return;

}

if(!me){

return;

}

varx=e.offsetX;

vary=e.offsetY;

vari=Math.floor(x/30);

varj=Math.floor(y/30);

_nowi=i;

_nowj=j;

if(chressBord[i][j]==0){

oneStep(i,j,me);

chressBord[i][j]=1;//我,已占位置

for(vark=0;k

if(wins[i][j][k]){

myWin[k]++;

_compWin[k]=computerWin[k];// 为悔棋做准备

computerWin[k]=6;//这个位置对方不可能赢了

if(myWin[k]==5){

resultTxt.innerHTML='恭喜,你赢了!';

over=true;

}

}

}

if(!over){

me=!me;

computerAI();

}

}

// 悔棋功能可用

backbtn.className=backbtn.className.replace(newRegExp("(s|^)unable(s|$)")," ");

}

oneStep() 方法为落子,要在棋盘上画一个棋子:

//画棋子

varoneStep=function(i,j,me){

// debugger;

context.beginPath();

context.arc(15+i*30,15+j*30,13,0,2*Math.PI);//画圆

context.closePath();

//渐变

vargradient=context.createRadialGradient(15+i*30+2,15+j*30-2,13,15+i*30+2,15+j*30-2,0);

if(me){

gradient.addColorStop(0,'#0a0a0a');

gradient.addColorStop(1,'#636766');

}else{

gradient.addColorStop(0,'#d1d1d1');

gradient.addColorStop(1,'#f9f9f9');

}

context.fillStyle=gradient;

context.fill();

}

接着看计算机怎么下棋,具体看computerAI()方法:

// 计算机下棋

varcomputerAI=function(){

varmyScore=[];

varcomputerScore=[];

varmax=0;

varu=0,v=0;

for(vari=0;i<15;i++){

myScore[i]=[];

computerScore[i]=[];

for(varj=0;j<15;j++){

myScore[i][j]=0;

computerScore[i][j]=0;

}

}

for(vari=0;i<15;i++){

for(varj=0;j<15;j++){

if(chressBord[i][j]==0){

for(vark=0;k

if(wins[i][j][k]){

if(myWin[k]==1){

myScore[i][j]+=200;

}elseif(myWin[k]==2){

myScore[i][j]+=400;

}elseif(myWin[k]==3){

myScore[i][j]+=2000;

}elseif(myWin[k]==4){

myScore[i][j]+=10000;

}

if(computerWin[k]==1){

computerScore[i][j]+=220;

}elseif(computerWin[k]==2){

computerScore[i][j]+=420;

}elseif(computerWin[k]==3){

computerScore[i][j]+=2100;

}elseif(computerWin[k]==4){

computerScore[i][j]+=20000;

}

}

}

if(myScore[i][j]>max){

max=myScore[i][j];

u=i;

v=j;

}elseif(myScore[i][j]==max){

if(computerScore[i][j]>computerScore[u][v]){

u=i;

v=j;

}

}

if(computerScore[i][j]>max){

max=computerScore[i][j];

u=i;

v=j;

}elseif(computerScore[i][j]==max){

if(myScore[i][j]>myScore[u][v]){

u=i;

v=j;

}

}

}

}

}

_compi=u;

_compj=v;

oneStep(u,v,false);

chressBord[u][v]=2;//计算机占据位置

for(vark=0;k

if(wins[u][v][k]){

computerWin[k]++;

_myWin[k]=myWin[k];

myWin[k]=6;//这个位置对方不可能赢了

if(computerWin[k]==5){

resultTxt.innerHTML='o(╯□╰)o,计算机赢了,继续加油哦!';

over=true;

}

}

}

if(!over){

me=!me;

}

}

根据相应的权重,计算出计算机应该落子的位置。

2.2 悔棋功能

要提的是,这里暂时只能悔一步棋。悔棋功能主要关键点是:1、销毁刚刚下的棋子;2、将之前不可能赢的状态还原;看下具体的代码:

// 悔棋

backbtn.οnclick=function(e){

if(!backAble){return;}

over=false;

me=true;

// 我,悔棋

chressBord[_nowi][_nowj]=0;//我,已占位置 还原

minusStep(_nowi,_nowj);//销毁棋子

for(vark=0;k

if(wins[_nowi][_nowj][k]){

myWin[k]--;

computerWin[k]=_compWin[k];//这个位置对方可能赢

}

}

// 计算机相应的悔棋

chressBord[_compi][_compj]=0;//计算机,已占位置 还原

minusStep(_compi,_compj);//销毁棋子

for(vark=0;k

if(wins[_compi][_compj][k]){

computerWin[k]--;

myWin[k]=_myWin[i];//这个位置对方可能赢

}

}

resultTxt.innerHTML='--益智五子棋--';

returnAble=true;

backAble=false;

// 撤销悔棋功能可用

returnbtn.className=returnbtn.className.replace(newRegExp("(s|^)unable(s|$)")," ");

}

minusStep()为销毁棋子的方法,我们看下是怎么销毁的。

//销毁棋子

varminusStep=function(i,j){

//擦除该圆

context.clearRect((i)*30,(j)*30,30,30);

// 重画该圆周围的格子

context.beginPath();

context.moveTo(15+i*30,j*30);

context.lineTo(15+i*30,j*30+30);

context.moveTo(i*30,j*30+15);

context.lineTo((i+1)*30,j*30+15);

context.stroke();

}

首先通过clearRect()擦掉该圆,然后再重新画该圆周围的格子,注意相应的位置,这里花了些时间折腾。

2.3 撤销悔棋功能

悔棋过后,再撤销,相当于还原悔棋之前的状态。代码比较简单:

// 撤销悔棋

returnbtn.οnclick=function(e){

if(!returnAble){return;}

// 我,撤销悔棋

chressBord[_nowi][_nowj]=1;//我,已占位置

oneStep(_nowi,_nowj,me);

for(vark=0;k

if(wins[_nowi][_nowj][k]){

myWin[k]++;

_compWin[k]=computerWin[k];

computerWin[k]=6;//这个位置对方不可能赢

}

if(myWin[k]==5){

resultTxt.innerHTML='恭喜,你赢了!';

over=true;

}

}

// 计算机撤销相应的悔棋

chressBord[_compi][_compj]=2;//计算机,已占位置

oneStep(_compi,_compj,false);

for(vark=0;k

if(wins[_compi][_compj][k]){

computerWin[k]++;

_myWin[k]=myWin[k];

myWin[k]=6;//这个位置对方不可能赢

}

if(computerWin[k]==5){

resultTxt.innerHTML='o(╯□╰)o,计算机赢了,继续加油哦!';

over=true;

}

}

returnbtn.className+='unable';

returnAble=false;

backAble=true;

}

至此,比较简单的完成了这三个功能。

三、总结

五子棋游戏的核心关键点是:

1、弄清楚有多少种赢法;

2、怎么判断是否已经赢了;

3、计算机下棋算法。这里巧妙地运用数组存储赢法,判断是否赢了,通过权重比较,计算出计算机该下棋的位置。 过程中用到canvas,之前有学习过,虽然很久没用,查了些资料,复习了怎么画线,画圆,学会了怎么如何清除一个圆等。 然后要注意的是,用原生Js怎么为元素添加、删除class。

作者:eraser123

源自:https://segmentfault.com/a/1190000009826648

声明:文章著作权归作者所有,如有侵权,请联系小编删除。返回搜狐,查看更多

责任编辑:

html五子棋悔棋,原生 JS + Canvas 实现五子棋游戏相关推荐

  1. 五子棋人机对战_原生JS+Canvas实现五子棋游戏

    原生JS+Canvas实现五子棋游戏 效果图 主要功能模块为: 1.人机对战功能 2.悔棋功能 3.撤销悔棋功能 二.代码详解 2.1 人机对战功能实现 从效果图可以看到,棋盘的横竖可以放的位置为15 ...

  2. html五子棋游戏制作原理,原生JS+Canvas实现五子棋游戏

    功能模块 先看下现在做完的效果: 代码详解 人机对战功能实现 从效果图可以看到,棋盘的横竖可以放的位置为15*15,通过canvas画棋盘: //绘画棋盘 var drawChessBoard = f ...

  3. 图片五子棋PHP接口,原生JS+Canvas实现五子棋游戏实例

    一.功能模块 先看下现在做完的效果: 主要功能模块为: 1.人机对战功能 2.悔棋功能 3.撤销悔棋功能 二.代码详解 2.1 人机对战功能实现 从效果图可以看到,棋盘的横竖可以放的位置为15*15, ...

  4. 使用原生JS+Canvas实现五子棋游戏

    布局+样式部分代码 : <style type='text/css'>canvas {display: block;margin: 50px auto;box-shadow: -2px - ...

  5. php 设计五子棋游戏,基于js+canvas实现五子棋小游戏

    本文实例为大家分享了js+canvas实现五子棋小游戏的具体代码,供大家参考,具体内容如下 效果展示: 源码展示: 五子棋 * { margin: 0; padding: 0; } body { ma ...

  6. PHP绘制99的棋盘,JS canvas绘制五子棋的棋盘

    本文为大家分享了JS canvas绘制五子棋棋盘的具体代码,供大家参考,具体内容如下 box-shadow:给元素块周边添加阴影效果. 语法:box-shadow: h-shadow v-shadow ...

  7. matlab 模拟心电图,使用原生js+canvas实现模拟心电图的实例

    从2015年2月转行进入IT行业,到现在也有将近两年的时间了,从最开始的java到现在的前端,前进的路上一直靠自己摸索,一路走到现在,前端大神是绝对谈不上的,最多算一只刚入门的菜鸟. 从最开始的懵懵懂 ...

  8. java心电图_使用原生js+canvas实现模拟心电图

    从2016年2月转行进入IT行业,到现在也有将近两年的时间了,从最开始的java到现在的前端,前进的路上一直靠自己摸索,一路走到现在,前端大神是绝对谈不上的,最多算一只刚入门的菜鸟. 从最开始的懵懵懂 ...

  9. 【学习随记】原生js canvas 画海报

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

最新文章

  1. 如何保证MySQL和Redis的数据一致性?
  2. Ajax结合json在web中的应用
  3. 有进度条圆周率Π计算
  4. UnityShader例子:边缘检测
  5. PHP7.1安装memcaehd扩展
  6. 【转】requests、BeautifulSoup使用总结
  7. tdscdma的matlab仿真,基于MATLAB的TDSCDMA调制解调仿真
  8. Spring事务管理A方法内部调用B方法的回滚问题(springboot事务管理)
  9. 计算机基础知识 图文,关于电脑基础知识学习【图文详解】
  10. 如何获得复权后的股票数据
  11. Cohort Analysis组群分析(1)
  12. python中set option_python的set_option选择
  13. 最短路计数(入门最短路)
  14. 机器学习笔记 --- 数学符号以及读法
  15. 自动提取网页文章或者文章的免费软件
  16. 清华才子王垠​加入华为职级22,前阿里P10赵海平加入字节跳动,职级或为4+
  17. 卸载macOSX版本的亚信安全防毒墙
  18. 常用电子元器件的一些特性(1)
  19. 10月11日关于煤炭的期货交易
  20. Angular 4入门教程系列:8:Tour Of Heroes之前后端服务

热门文章

  1. 数据网络卡顿怎么处理_最近移动怎么回事,4g网络很卡
  2. 小熊派bearpi-HM-nano(hi3861鸿蒙LiteOS)点亮WS2812灯板(spi方式)
  3. 移动APP功能测试要点总结
  4. 为啥离不了 linux
  5. 教育部文科计算机大赛,重磅!教育部官方发布2019受认可的全部竞赛名单
  6. Docker(13)-- Docker 网络
  7. [转] 网络术语大全
  8. tushare获取破新高的股票
  9. 智能优化算法:天鹰优化算法-附代码
  10. 委托与事件-观察者设计模式_老鹰捉小鸡