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

 更新时间:2020年05月28日 10:38:13   作者:老于  
这篇文章主要为大家详细介绍了原生JS+Canvas实现五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了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>

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

C++经典小游戏汇总

python经典小游戏汇总

python俄罗斯方块游戏集合

JavaScript经典游戏 玩不停

javascript经典小游戏汇总

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

相关文章

  • javascript弹出带文字信息的提示框效果

    javascript弹出带文字信息的提示框效果

    这篇文章主要介绍了javascript弹出带文字信息的提示框效果,涉及javascript简单弹出窗口定义与样式相关操作技巧,需要的朋友可以参考下
    2016-07-07
  • JS实现的仿淘宝交易倒计时效果

    JS实现的仿淘宝交易倒计时效果

    这篇文章主要介绍了JS实现的仿淘宝交易倒计时效果,涉及JavaScript针对时间与日期的动态操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • js数组Array sort方法使用深入分析

    js数组Array sort方法使用深入分析

    js中Array.sort()方法是用来对数组项进行排序的,默认是升序排列sort() 方法可以接受一个 方法为参数,这个方法有两个参数,接下来本例将对sort方法进行深入探讨,感兴趣的朋友可以参考下
    2013-02-02
  • nodejs win7下安装方法

    nodejs win7下安装方法

    什么是Node.js?还服务器端javascript?对于这个概念我在这篇文章不做解释,可以自己去搜索了解下,服务器端js不是新技术,只是最近的node.js的火爆让他爆发了,我会在以后的文章里解释什么是node.js
    2012-05-05
  • Sort()函数的多种用法

    Sort()函数的多种用法

    sort() 方法用于对数组的元素进行排序。接下来通过本文给大家介绍Sort()函数的多种用法,对sort函数的用法相关知识感兴趣的朋友一起学习
    2016-03-03
  • 解决JS使用fill()进行数组填充遇到的问题

    解决JS使用fill()进行数组填充遇到的问题

    最近在做算法题时,遇到需要创建二维数组并进行初始化的情况,刚开始我使用的是 new Array(n).fill(new Array(n).fill('.')) 进行二维数组的初始化,但无论怎样我都通不过测试用例,所以本文就给大家详细的介绍了如何解决这类问题以及将js中的fill(方法重学一下
    2023-09-09
  • 解决浏览器会自动填充密码的问题

    解决浏览器会自动填充密码的问题

    本篇文章主要介绍了解决浏览器会自动填充密码问题的方法。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-04-04
  • js简单的点击返回顶部效果实现方法

    js简单的点击返回顶部效果实现方法

    这篇文章主要介绍了js简单的点击返回顶部效果实现方法,实例分析了实现返回顶部效果的相关要点与实现技巧,需要的朋友可以参考下
    2015-04-04
  • 微信小程序支付PHP代码

    微信小程序支付PHP代码

    这篇文章主要为大家详细介绍了微信小程序支付的PHP实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • JS实现鼠标点击展开或隐藏表格行的方法

    JS实现鼠标点击展开或隐藏表格行的方法

    这篇文章主要介绍了JS实现鼠标点击展开或隐藏表格行的方法,实例分析了javascript操作table表格与css样式的技巧,需要的朋友可以参考下
    2015-03-03

最新评论