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


Posted in Javascript onMay 28, 2020

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

<!DOCTYPE html> 
<html> 
 <head> 
 <meta charset="utf-8" /> 
 <title>五子棋</title> 
 <style type='text/css'> 
 canvas { 
 display: block; 
 margin: 50px auto; 
 box-shadow: -2px -2px 2px #efefef, 5px 5px 5px #b9b9b9; 
 cursor: pointer; 
 } 
 .btn-wrap { 
 display: flex; 
 flex-direction: row; 
 justify-content:center; 
 } 
 .btn-wrap div { 
 margin: 0 10px; 
 } 
 div>span { 
 display: inline-block; 
 padding: 10px 20px; 
 color: #fff; 
 background-color: #EE82EE; 
 border-radius: 5px; 
 cursor: pointer; 
 } 
 div.unable span { 
 background: #D6D6D4; 
 color: #adacaa; 
 } 
 #result-wrap {text-align: center;} 
 </style> 
 </head> 
 <body> 
 <h3 id="result-wrap">--益智五子棋--</h3> 
 <canvas id="chess" width="450px" height="450px"></canvas> 
 <div class="btn-wrap"> 
 <div id='restart' class="restart"> 
 <span>重新开始</span> 
 </div> 
 <div id='goback' class="goback unable"> 
 <span>悔棋</span> 
 </div> 
 <div id='return' class="return unable"> 
 <span>撤销悔棋</span> 
 </div> 
 </div> 
 <script type="text/javascript" charset="utf-8"> 
 var over = false; 
 var me = true; //我 
 var _nowi = 0, _nowj = 0; //记录自己下棋的坐标 
 var _compi = 0, _compj = 0; //记录计算机当前下棋的坐标 
 var _myWin = [], _compWin = []; //记录我,计算机赢的情况 
 var backAble = false, returnAble = false; 
 var resultTxt = document.getElementById('result-wrap'); 
 var chressBord = [];//棋盘 
 for(var i = 0; i < 15; i++){ 
 chressBord[i] = []; 
 for(var j = 0; j < 15; j++){ 
  chressBord[i][j] = 0; 
 } 
 } 
 //赢法的统计数组 
 var myWin = []; 
 var computerWin = []; 
 //赢法数组 
 var wins = []; 
 for(var i = 0; i < 15; i++){ 
 wins[i] = []; 
 for(var j = 0; j < 15; j++){ 
  wins[i][j] = []; 
 } 
 } 
 var count = 0; //赢法总数 
 //横线赢法 
 for(var i = 0; i < 15; i++){ 
 for(var j = 0; j < 11; j++){ 
  for(var k = 0; k < 5; k++){ 
  wins[i][j+k][count] = true; 
  } 
  count++; 
 } 
 } 
 //竖线赢法 
 for(var i = 0; i < 15; i++){ 
 for(var j = 0; j < 11; j++){ 
  for(var k = 0; k < 5; k++){ 
  wins[j+k][i][count] = true; 
  } 
  count++; 
 } 
 } 
 //正斜线赢法 
 for(var i = 0; i < 11; i++){ 
 for(var j = 0; j < 11; j++){ 
  for(var k = 0; k < 5; k++){ 
  wins[i+k][j+k][count] = true; 
  } 
  count++; 
 } 
 } 
 //反斜线赢法 
 for(var i = 0; i < 11; i++){ 
 for(var j = 14; j > 3; j--){ 
  for(var k = 0; k < 5; k++){ 
  wins[i+k][j-k][count] = true; 
  } 
  count++; 
 } 
 } 
 // debugger; 
 for(var i = 0; i < count; i++){ 
 myWin[i] = 0; 
 _myWin[i] = 0; 
 computerWin[i] = 0; 
 _compWin[i] = 0; 
 } 
 var chess = document.getElementById("chess"); 
 var context = chess.getContext('2d'); 
 context.strokeStyle = '#bfbfbf'; //边框颜色 
 var backbtn = document.getElementById("goback"); 
 var returnbtn = document.getElementById("return"); 
 window.onload = function(){ 
 drawChessBoard(); // 画棋盘 
 } 
 document.getElementById("restart").onclick = function(){ 
 window.location.reload(); 
 } 
 // 我,下棋 
 chess.onclick = function(e){ 
 if(over){ 
  return; 
 } 
 if(!me){ 
  return; 
 } 
 // 悔棋功能可用 
 backbtn.className = backbtn.className.replace( new RegExp( "(\\s|^)unable(\\s|$)" )," " ); 
 var x = e.offsetX; 
 var y = e.offsetY; 
 var i = Math.floor(x / 30); 
 var j = Math.floor(y / 30); 
 _nowi = i; 
 _nowj = j; 
 if(chressBord[i][j] == 0){ 
  oneStep(i,j,me); 
  chressBord[i][j] = 1; //我,已占位置 
   
  for(var k = 0; k < count; k++){ // 将可能赢的情况都加1 
  if(wins[i][j][k]){ 
  // debugger; 
  myWin[k]++; 
  _compWin[k] = computerWin[k]; 
  computerWin[k] = 6;//这个位置对方不可能赢了 
  if(myWin[k] == 5){ 
  // window.alert('你赢了'); 
  resultTxt.innerHTML = '恭喜,你赢了!'; 
  over = true; 
  } 
  } 
  } 
  if(!over){ 
  me = !me; 
  computerAI(); 
  } 
 } 
 } 
 // 悔棋 
 backbtn.onclick = function(e){ 
 if(!backAble) { return;} 
 over = false; 
 me = true; 
 // resultTxt.innerHTML = 'o(?□?)o,悔棋中'; 
 // 撤销悔棋功能可用 
 returnbtn.className = returnbtn.className.replace( new RegExp( "(\\s|^)unable(\\s|$)" )," " ); 
 // 我,悔棋 
 chressBord[_nowi][_nowj] = 0; //我,已占位置 还原 
 minusStep(_nowi, _nowj); //销毁棋子   
 for(var k = 0; k < count; k++){ // 将可能赢的情况都减1 
  if(wins[_nowi][_nowj][k]){ 
  myWin[k]--; 
  computerWin[k] = _compWin[k];//这个位置对方可能赢 
  } 
 } 
 // 计算机相应的悔棋 
 chressBord[_compi][_compj] = 0; //计算机,已占位置 还原 
 minusStep(_compi, _compj); //销毁棋子   
 for(var k = 0; k < count; k++){ // 将可能赢的情况都减1 
  if(wins[_compi][_compj][k]){ 
  computerWin[k]--; 
  myWin[k] = _myWin[i];//这个位置对方可能赢 
  } 
 } 
 resultTxt.innerHTML = '--益智五子棋--'; 
 returnAble = true; 
 backAble = false; 
 } 
 // 撤销悔棋 
 returnbtn.onclick = function(e){ 
 if(!returnAble) { return; } 
  // 我,撤销悔棋 
 chressBord[_nowi][_nowj] = 1; //我,已占位置 
 oneStep(_nowi,_nowj,me);  
 for(var k = 0; k < count; 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(var k = 0; k < count; k++){ // 将可能赢的情况都减1 
  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; 
 } 
 // 计算机下棋 
 var computerAI = function (){ 
 var myScore = []; 
 var computerScore = []; 
 var max = 0; 
 var u = 0, v = 0; 
 for(var i = 0; i < 15; i++){ 
  myScore[i] = []; 
  computerScore[i] = []; 
  for(var j = 0; j < 15; j++){ 
  myScore[i][j] = 0; 
  computerScore[i][j] = 0; 
  } 
 } 
 for(var i = 0; i < 15; i++){ 
  for(var j = 0; j < 15; j++){ 
  if(chressBord[i][j] == 0){ 
  for(var k = 0; k < count; k++){ 
  if(wins[i][j][k]){ 
   if(myWin[k] == 1){ 
   myScore[i][j] += 200; 
   }else if(myWin[k] == 2){ 
   myScore[i][j] += 400; 
   }else if(myWin[k] == 3){ 
   myScore[i][j] += 2000; 
   }else if(myWin[k] == 4){ 
   myScore[i][j] += 10000; 
   } 
   
   if(computerWin[k] == 1){ 
   computerScore[i][j] += 220; 
   }else if(computerWin[k] == 2){ 
   computerScore[i][j] += 420; 
   }else if(computerWin[k] == 3){ 
   computerScore[i][j] += 2100; 
   }else if(computerWin[k] == 4){ 
   computerScore[i][j] += 20000; 
   }  
  } 
  } 
  
  if(myScore[i][j] > max){ 
  max = myScore[i][j]; 
  u = i; 
  v = j; 
  }else if(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; 
  }else if(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(var k = 0; k < count; 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; 
 } 
 backAble = true; 
 returnAble = false; 
 var hasClass = new RegExp('unable').test(' ' + returnbtn.className + ' '); 
 if(!hasClass) { 
  returnbtn.className += ' ' + 'unable'; 
 } 
 } 
 //绘画棋盘 
 var drawChessBoard = function() { 
 for(var 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(); 
 } 
 } 
 //画棋子 
 var oneStep = function(i,j,me) { 
 context.beginPath(); 
 context.arc(15 + i * 30, 15 + j * 30, 13, 0, 2 * Math.PI);// 画圆 
 context.closePath(); 
 //渐变 
 var gradient = 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(); 
 } 
 //销毁棋子 
 var minusStep = 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(); 
 } 
 </script> 
 </body> 
</html>

更多有趣的经典小游戏实现专题,分享给大家:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Jquery插件之多图片异步上传
Oct 20 Javascript
JavaScript列表框listbox全选和反选的实现方法
Mar 18 Javascript
js改变Iframe中Src的方法
May 05 Javascript
通过Jquery.cookie.js实现展示浏览网页的历史记录超管用
Oct 23 Javascript
JavaScript中的Reflect对象详解(ES6新特性)
Jul 22 Javascript
Vue数据驱动模拟实现1
Jan 11 Javascript
JavaScript判断输入是否为数字类型的方法总结
Sep 28 Javascript
React Form组件的实现封装杂谈
May 07 Javascript
解决vue 按钮多次点击重复提交数据问题
May 10 Javascript
element-ui tree结构实现增删改自定义功能代码
Aug 31 Javascript
关于javascript中的promise的用法和注意事项(推荐)
Jan 15 Javascript
Vue实现图书管理案例
Jan 20 Vue.js
React-router v4 路由配置方法小结
Aug 08 #Javascript
用Vue.extend构建消息提示组件的方法实例
Aug 08 #Javascript
基于Vue实现页面切换左右滑动效果
Jun 29 #Javascript
VUE实现表单元素双向绑定(总结)
Aug 08 #Javascript
ES6模块化的import和export用法方法总结
Aug 08 #Javascript
Vue项目中quill-editor带样式编辑器的使用方法
Aug 08 #Javascript
webpack 2.x配置reactjs基本开发环境详解
Aug 08 #Javascript
You might like
PHP设计模式之命令模式的深入解析
2013/06/13 PHP
php获取mysql字段名称和其它信息的例子
2014/04/14 PHP
WampServer下安装多个版本的PHP、mysql、apache图文教程
2015/01/07 PHP
PHP获取一年有几周以及每周开始日期和结束日期
2015/08/06 PHP
php制作圆形用户头像的实例_自定义封装类源代码
2017/09/18 PHP
PHP让数组中有相同值的组成新的数组实例
2017/12/31 PHP
在网页中控制wmplayer播放器
2006/07/01 Javascript
jQuery参数列表集合
2011/04/06 Javascript
JavaScript中使用构造器创建对象无需new的情况说明
2012/03/01 Javascript
jquery插件开发注意事项小结
2013/06/04 Javascript
jQuery实现下拉框左右选择的简单实例
2014/02/22 Javascript
js实现两点之间画线的方法
2015/05/12 Javascript
jQuery实现只允许输入数字和小数点的方法
2016/03/02 Javascript
详解vue嵌套路由-query传递参数
2017/05/23 Javascript
PHP 实现一种多文件上传的方法
2017/09/20 Javascript
Vue+Flask实现简单的登录验证跳转的示例代码
2018/01/13 Javascript
关于微信小程序bug记录与解决方法
2018/08/15 Javascript
JS实现提示效果弹出及延迟隐藏的功能
2019/08/26 Javascript
Vue实现页面添加水印功能
2019/11/09 Javascript
javascript使用Blob对象实现的下载文件操作示例
2020/04/18 Javascript
Python continue语句用法实例
2014/03/11 Python
python opencv之分水岭算法示例
2018/02/24 Python
详解小白之KMP算法及python实现
2019/04/04 Python
使用Python和Prometheus跟踪天气的使用方法
2019/05/06 Python
Pytorch提取模型特征向量保存至csv的例子
2020/01/03 Python
Python读取yaml文件的详细教程
2020/07/21 Python
BIBLOO波兰:捷克的一家在线服装店
2018/03/09 全球购物
英国创新设计文具、卡片和礼品包装网站:Paperchase
2018/07/14 全球购物
奥利奥广告词
2014/03/20 职场文书
伦敦奥运会口号
2014/06/13 职场文书
个人工作表现评价材料
2014/09/21 职场文书
2014最新实习证明模板
2014/10/02 职场文书
2014年质检工作总结
2014/11/26 职场文书
统计员岗位职责
2015/02/11 职场文书
2016自主招生校长推荐信范文
2015/03/23 职场文书
python 中[0]*2与0*2的区别说明
2021/05/10 Python