JS+Canvas实现五子棋游戏


Posted in Javascript onAugust 26, 2020

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

布局+样式部分代码 :

<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>
 
 <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>

js部分代码:

<script>
 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 = '计算机赢了,继续加油哦!';
   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 = '计算机赢了,继续加油哦!';
   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>

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

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

Javascript 相关文章推荐
JavaScript进阶教程(第四课第一部分)
Apr 05 Javascript
探讨javascript是不是面向对象的语言
Nov 21 Javascript
Ext4.2的Ext.grid.plugin.RowExpander无法触发事件解决办法
Aug 15 Javascript
用JavaScript实现页面重定向功能的教程
Jun 04 Javascript
JavaScript获取两个数组交集的方法
Jun 09 Javascript
angularjs学习笔记之双向数据绑定
Sep 26 Javascript
使用vue.js实现联动效果的示例代码
Jan 10 Javascript
ES6使用let命令更简单的实现块级作用域实例分析
Mar 31 Javascript
详解vue beforeRouteEnter 异步获取数据给实例问题
Aug 09 Javascript
Net微信网页开发 使用微信JS-SDK获取当前地理位置过程详解
Aug 26 Javascript
基于layui框架响应式布局的一些使用详解
Sep 16 Javascript
详解webpack的文件监听实现(热更新)
Sep 11 Javascript
Js Snowflake(雪花算法)生成随机ID的实现方法
Aug 26 #Javascript
uin-app+mockjs实现本地数据模拟
Aug 26 #Javascript
一篇文章带你搞懂Vue虚拟Dom与diff算法
Aug 25 #Javascript
微信小程序换肤功能实现代码(思路详解)
Aug 25 #Javascript
prettier自动格式化去换行的实现代码
Aug 25 #Javascript
Vue中 axios delete请求参数操作
Aug 25 #Javascript
React实现轮播效果
Aug 25 #Javascript
You might like
php中get_meta_tags()、CURL与user-agent用法分析
2014/12/16 PHP
查询绑定数据岛的表格中的文本并修改显示方式的js代码
2009/12/15 Javascript
Javascript 类型转换方法
2010/10/24 Javascript
Dom在ajax技术中的作用说明
2010/10/25 Javascript
JavaScript的Module模式编程深入分析
2013/08/13 Javascript
JS作为值的函数用法示例
2016/06/20 Javascript
AngularJS递归指令实现Tree View效果示例
2016/11/07 Javascript
Bootstrap table两种分页示例
2016/12/23 Javascript
基于vue实现分页/翻页组件paginator示例
2017/03/09 Javascript
JS 组件系列之Bootstrap Table的冻结列功能彻底解决高度问题
2017/06/30 Javascript
聊聊那些使用前端Javascript实现的机器学习类库
2017/09/18 Javascript
angular4 JavaScript内存溢出问题
2018/03/06 Javascript
Servlet3.0与纯javascript通过Ajax交互的实例详解
2018/03/18 Javascript
Vue结合Video.js播放m3u8视频流的方法示例
2018/05/04 Javascript
纯JS实现五子棋游戏
2020/05/28 Javascript
vue如何在用户要关闭当前网页时弹出提示的实现
2020/05/31 Javascript
如何将Node.js中的回调转换为Promise
2020/11/10 Javascript
[36:05]完美世界DOTA2联赛循环赛 Forest vs DM 第一场 11.06
2020/11/06 DOTA
使用python编写android截屏脚本双击运行即可
2014/07/21 Python
PyCharm使用教程之搭建Python开发环境
2016/06/07 Python
python的exec、eval使用分析
2017/12/11 Python
python读取Excel实例详解
2018/08/17 Python
Python 实现异步调用函数的示例讲解
2018/10/14 Python
Python 获取div标签中的文字实例
2018/12/20 Python
django中使用事务及接入支付宝支付功能
2019/09/15 Python
Python数据可视化:饼状图的实例讲解
2019/12/07 Python
Python3 main函数使用sys.argv传入多个参数的实现
2019/12/25 Python
Python编程快速上手——强口令检测算法案例分析
2020/02/29 Python
设计师珠宝:Ylang 23
2018/05/11 全球购物
程序集与命名空间有什么不同
2014/07/25 面试题
商务英语广告词大全
2014/03/18 职场文书
党支部承诺书范文
2014/03/28 职场文书
中学生秋季运动会广播稿
2014/09/21 职场文书
服务承诺书
2015/01/19 职场文书
劳动模范获奖感言
2015/07/31 职场文书
银行工作心得体会范文
2016/01/23 职场文书