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 相关文章推荐
网页广告中JS代码的信息监听示例
Apr 02 Javascript
JavaScript设置表单上传时文件个数的方法
Aug 11 Javascript
创建自己的jquery表格插件
Nov 25 Javascript
浅谈JavaScript中小数和大整数的精度丢失
May 31 Javascript
详解js中的apply与call的用法
Jul 30 Javascript
JavaScript实现经典排序算法之选择排序
Dec 28 Javascript
jQuery实现的省市联动菜单功能示例【测试可用】
Jan 13 Javascript
微信小程序实现美团菜单
Jun 06 Javascript
jQuery实现的隔行变色功能【案例】
Feb 18 jQuery
Vue多环境代理配置方法思路详解
Jun 21 Javascript
js神秘的电报密码 哈弗曼编码实现
Sep 10 Javascript
一篇文章弄清楚Ajax请求的五个步骤
Mar 17 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将HTML转换成文本的实现代码
2015/01/21 PHP
php实现的RSS生成类实例
2015/04/23 PHP
PHP中快速生成随机密码的几种方式
2017/04/17 PHP
解决laravel5中auth用户登录其他页面获取不到登录信息的问题
2019/10/08 PHP
HTML页面如何象ASP一样接受参数
2007/02/07 Javascript
javascript 获取浏览器版本
2015/01/21 Javascript
jQuery定义背景动态切换效果的方法
2015/03/23 Javascript
jQuery中extend函数详解
2015/07/13 Javascript
简单谈谈javascript中的变量、作用域和内存问题
2015/08/30 Javascript
Jquery左右滑动插件之实现超级炫酷动画效果附源码下载
2015/12/02 Javascript
jQuery实现点击表格单元格就可以编辑内容的方法【测试可用】
2016/08/01 Javascript
JavaScript算法系列之快速排序(Quicksort)算法实例详解
2016/09/04 Javascript
jQuery Mobile和HTML5开发App推广注册页
2016/11/07 Javascript
JavaScript数据结构之广义表的定义与表示方法详解
2017/04/12 Javascript
jQuery插件FusionCharts绘制的2D双柱状图效果示例【附demo源码】
2017/05/13 jQuery
Angularjs 1.3 中的$parse实例代码
2017/09/14 Javascript
Vue如何从1.0迁移到2.0
2017/10/19 Javascript
JS实现的文字间歇循环滚动效果完整示例
2018/02/13 Javascript
vue中锚点的三种方法
2018/07/06 Javascript
详解Vue.js自定义tipOnce指令用法实例
2018/12/19 Javascript
小程序绑定用户方案优化小结
2019/05/15 Javascript
[02:40]DOTA2超级联赛专访430 从小就爱玩对抗性游戏
2013/06/18 DOTA
python创建和删除目录的方法
2015/04/29 Python
linux查找当前python解释器的位置方法
2019/02/20 Python
解决pycharm不能自动补全第三方库的函数和属性问题
2020/03/12 Python
golang/python实现归并排序实例代码
2020/08/30 Python
Huda Beauty官方商店:化妆和美容产品
2020/09/05 全球购物
毕业生自我推荐
2013/11/04 职场文书
社区中秋节活动方案
2014/01/29 职场文书
双创工作实施方案
2014/03/26 职场文书
乡镇三项教育实施方案
2014/03/30 职场文书
个人贷款授权委托书样本
2014/10/07 职场文书
教师见习报告范文
2014/11/03 职场文书
反邪教观后感
2015/06/11 职场文书
浅谈Redis的事件驱动模型
2022/05/30 Redis
CSS中calc(100%-100px)不加空格不生效
2023/05/07 HTML / CSS