用原生js+canvas实现五子棋

  1 <!DOCTYPE html>
  2 <html>
  3     <head>
  4         <meta charset="utf-8" />
  5         <title>五子棋</title>
  6         <link rel="stylesheet" href="css/style.css" />
  7     </head>
  8     <body>
  9         <h3 id="result-wrap">--益智五子棋--</h3>
 10         <canvas id="chess" width="450px" height="450px"></canvas>
 11         <p class="btn-wrap">
 12             <p id=‘restart‘ class="restart">
 13                 <span>重新开始</span>
 14             </p>
 15             <p id=‘goback‘ class="goback unable">
 16                 <span>悔棋</span>
 17             </p>
 18             <p id=‘return‘ class="return unable">
 19                 <span>撤销悔棋</span>
 20             </p>
 21         </p>
 22         <script type="text/javascript" charset="utf-8">
 23             var over = false;
 24             var me = true; //我
 25             var _nowi = 0,
 26                 _nowj = 0; //记录自己下棋的坐标
 27             var _compi = 0,
 28                 _compj = 0; //记录计算机当前下棋的坐标
 29             var _myWin = [],
 30                 _compWin = []; //记录我,计算机赢的情况
 31             var backAble = false,
 32                 returnAble = false;
 33             var resultTxt = document.getElementById(‘result-wrap‘);
 34             var chressBord = []; //棋盘
 35
 36             for(var i = 0; i < 15; i++) {
 37                 chressBord[i] = [];
 38                     for(var j = 0; j < 15; j++) {
 39                         chressBord[i][j] = 0;
 40                 }
 41             }
 42
 43             //赢法的统计数组
 44             var myWin = [];
 45             var computerWin = [];
 46
 47             //赢法数组
 48             var wins = [];
 49             for(var i = 0; i < 15; i++) {
 50                 wins[i] = [];
 51                     for(var j = 0; j < 15; j++) {
 52                         wins[i][j] = [];
 53                 }
 54             }
 55             var count = 0; //赢法总数
 56
 57             //横线赢法
 58             for(var i = 0; i < 15; i++) {
 59                 for(var j = 0; j < 11; j++) {
 60                     for(var k = 0; k < 5; k++) {
 61                         wins[i][j + k][count] = true;
 62                     }
 63                     count++;
 64                 }
 65             }
 66
 67             //竖线赢法
 68             for(var i = 0; i < 15; i++) {
 69                 for(var j = 0; j < 11; j++) {
 70                     for(var k = 0; k < 5; k++) {
 71                         wins[j + k][i][count] = true;
 72                     }
 73                     count++;
 74                 }
 75             }
 76
 77             //正斜线赢法
 78             for(var i = 0; i < 11; i++) {
 79                 for(var j = 0; j < 11; j++) {
 80                     for(var k = 0; k < 5; k++) {
 81                         wins[i + k][j + k][count] = true;
 82                     }
 83                     count++;
 84                 }
 85             }
 86
 87             //反斜线赢法
 88             for(var i = 0; i < 11; i++) {
 89                 for(var j = 14; j > 3; j--) {
 90                     for(var k = 0; k < 5; k++) {
 91                         wins[i + k][j - k][count] = true;
 92                     }
 93                     count++;
 94                 }
 95             }
 96
 97             // debugger;
 98             for(var i = 0; i < count; i++) {
 99                 myWin[i] = 0;
100                 _myWin[i] = 0;
101                 computerWin[i] = 0;
102                 _compWin[i] = 0;
103             }
104             var chess = document.getElementById("chess");
105             var context = chess.getContext(‘2d‘);
106             context.strokeStyle = ‘#bfbfbf‘; //边框颜色
107             var backbtn = document.getElementById("goback");
108             var returnbtn = document.getElementById("return");
109             window.onload = function() {
110                 drawChessBoard(); // 画棋盘
111             }
112             document.getElementById("restart").onclick = function() {
113                 window.location.reload();
114             }
115
116             // 我,下棋
117             chess.onclick = function(e) {
118             if(over) {
119                 return;
120             }
121             if(!me) {
122                 return;
123             }
124             // 悔棋功能可用
125             backbtn.className = backbtn.className.replace(new RegExp("(\\s|^)unable(\\s|$)"), " ");
126                 var x = e.offsetX;
127                 var y = e.offsetY;
128                 var i = Math.floor(x / 30);
129                 var j = Math.floor(y / 30);
130                 _nowi = i;
131                 _nowj = j;
132                 if(chressBord[i][j] == 0) {
133                     oneStep(i, j, me);
134                     chressBord[i][j] = 1; //我,已占位置
135                     for(var k = 0; k < count; k++) { // 将可能赢的情况都加1
136                         if(wins[i][j][k]) {
137                             // debugger;
138                             myWin[k]++;
139                             _compWin[k] = computerWin[k];
140                             computerWin[k] = 6; //这个位置对方不可能赢了
141                             if(myWin[k] == 5) {
142                                 // window.alert(‘你赢了‘);
143                                 resultTxt.innerHTML = ‘恭喜,你赢了!‘;
144                                 over = true;
145                             }
146                         }
147                     }
148                     if(!over) {
149                         me = !me;
150                         computerAI();
151                     }
152                 }
153             }
154
155             // 悔棋
156             backbtn.onclick = function(e) {
157                 if(!backAble) {
158                     return;
159                 }
160                 over = false;
161                 me = true;
162                 // resultTxt.innerHTML = ‘o(╯□╰)o,悔棋中‘;
163                 // 撤销悔棋功能可用
164                 returnbtn.className = returnbtn.className.replace(new RegExp("(\\s|^)unable(\\s|$)"), " ");
165                 // 我,悔棋
166                 chressBord[_nowi][_nowj] = 0; //我,已占位置 还原
167                 minusStep(_nowi, _nowj); //销毁棋子
168                 for(var k = 0; k < count; k++) { // 将可能赢的情况都减1
169                     if(wins[_nowi][_nowj][k]) {
170                         myWin[k]--;
171                         computerWin[k] = _compWin[k]; //这个位置对方可能赢
172                     }
173                 }
174                 // 计算机相应的悔棋
175                 chressBord[_compi][_compj] = 0; //计算机,已占位置 还原
176                 minusStep(_compi, _compj); //销毁棋子
177                 for(var k = 0; k < count; k++) { // 将可能赢的情况都减1
178                     if(wins[_compi][_compj][k]) {
179                         computerWin[k]--;
180                         myWin[k] = _myWin[i]; //这个位置对方可能赢
181                     }
182                 }
183                 resultTxt.innerHTML = ‘--益智五子棋--‘;
184                 returnAble = true;
185                 backAble = false;
186             }
187
188             // 撤销悔棋
189             returnbtn.onclick = function(e) {
190                 if(!returnAble) {
191                     return;
192                 }
193                 // 我,撤销悔棋
194                 chressBord[_nowi][_nowj] = 1; //我,已占位置
195                 oneStep(_nowi, _nowj, me);
196                 for(var k = 0; k < count; k++) {
197                     if(wins[_nowi][_nowj][k]) {
198                         myWin[k]++;
199                         _compWin[k] = computerWin[k];
200                         computerWin[k] = 6; //这个位置对方不可能赢
201                     }
202                     if(myWin[k] == 5) {
203                         resultTxt.innerHTML = ‘恭喜,你赢了!‘;
204                         over = true;
205                     }
206                 }
207
208                 // 计算机撤销相应的悔棋
209                 chressBord[_compi][_compj] = 2; //计算机,已占位置
210                 oneStep(_compi, _compj, false);
211                 for(var k = 0; k < count; k++) { // 将可能赢的情况都减1
212                     if(wins[_compi][_compj][k]) {
213                         computerWin[k]++;
214                         _myWin[k] = myWin[k];
215                         myWin[k] = 6; //这个位置对方不可能赢
216                     }
217                     if(computerWin[k] == 5) {
218                         resultTxt.innerHTML = ‘o(╯□╰)o,计算机赢了,继续加油哦!‘;
219                         over = true;
220                     }
221                 }
222                 returnbtn.className += ‘ ‘ + ‘unable‘;
223                 returnAble = false;
224                 backAble = true;
225             }
226
227             // 计算机下棋
228             var computerAI = function() {
229                 var myScore = [];
230                 var computerScore = [];
231                 var max = 0;
232                 var u = 0,
233                     v = 0;
234                 for(var i = 0; i < 15; i++) {
235                     myScore[i] = [];
236                     computerScore[i] = [];
237                     for(var j = 0; j < 15; j++) {
238                         myScore[i][j] = 0;
239                         computerScore[i][j] = 0;
240                     }
241                 }
242
243                 for(var i = 0; i < 15; i++) {
244                     for(var j = 0; j < 15; j++) {
245                         if(chressBord[i][j] == 0) {
246                             for(var k = 0; k < count; k++) {
247                                 if(wins[i][j][k]) {
248                                     if(myWin[k] == 1) {
249                                         myScore[i][j] += 200;
250                                     } else if(myWin[k] == 2) {
251                                         myScore[i][j] += 400;
252                                     } else if(myWin[k] == 3) {
253                                         myScore[i][j] += 2000;
254                                     } else if(myWin[k] == 4) {
255                                         myScore[i][j] += 10000;
256                                     }
257                                     if(computerWin[k] == 1) {
258                                         computerScore[i][j] += 220;
259                                     } else if(computerWin[k] == 2) {
260                                         computerScore[i][j] += 420;
261                                     } else if(computerWin[k] == 3) {
262                                         computerScore[i][j] += 2100;
263                                     } else if(computerWin[k] == 4) {
264                                         computerScore[i][j] += 20000;
265                                     }
266                                 }
267                             }
268                             if(myScore[i][j] > max) {
269                                 max = myScore[i][j];
270                                 u = i;
271                                 v = j;
272                             } else if(myScore[i][j] == max) {
273                                 if(computerScore[i][j] > computerScore[u][v]) {
274                                     u = i;
275                                     v = j;
276                                 }
277                             }
278                             if(computerScore[i][j] > max) {
279                                 max = computerScore[i][j];
280                                 u = i;
281                                 v = j;
282                             } else if(computerScore[i][j] == max) {
283                                 if(myScore[i][j] > myScore[u][v]) {
284                                     u = i;
285                                     v = j;
286                                 }
287                             }
288                         }
289                     }
290                 }
291                 _compi = u;
292                 _compj = v;
293                 oneStep(u, v, false);
294                 chressBord[u][v] = 2; //计算机占据位置
295                 for(var k = 0; k < count; k++) {
296                     if(wins[u][v][k]) {
297                         computerWin[k]++;
298                         _myWin[k] = myWin[k];
299                         myWin[k] = 6; //这个位置对方不可能赢了
300                         if(computerWin[k] == 5) {
301                             resultTxt.innerHTML = ‘o(╯□╰)o,计算机赢了,继续加油哦!‘;
302                             over = true;
303                         }
304                     }
305                 }
306                 if(!over) {
307                     me = !me;
308                 }
309                 backAble = true;
310                 returnAble = false;
311                 var hasClass = new RegExp(‘unable‘).test(‘ ‘ + returnbtn.className + ‘ ‘);
312                 if(!hasClass) {
313                     returnbtn.className += ‘ ‘ + ‘unable‘;
314                 }
315             }
316
317             //绘画棋盘
318             var drawChessBoard = function() {
319                 for(var i = 0; i < 15; i++) {
320                     context.moveTo(15 + i * 30, 15);
321                     context.lineTo(15 + i * 30, 435);
322                     context.stroke();
323                     context.moveTo(15, 15 + i * 30);
324                     context.lineTo(435, 15 + i * 30);
325                     context.stroke();
326                 }
327             }
328
329             //画棋子
330             var oneStep = function(i, j, me) {
331                 context.beginPath();
332                 context.arc(15 + i * 30, 15 + j * 30, 13, 0, 2 * Math.PI); // 画圆
333                 context.closePath();
334                 //渐变
335                 var gradient = context.createRadialGradient(15 + i * 30 + 2, 15 + j * 30 - 2, 13, 15 + i * 30 + 2, 15 + j * 30 - 2, 0);
336                 if(me) {
337                     gradient.addColorStop(0, ‘#0a0a0a‘);
338                     gradient.addColorStop(1, ‘#636766‘);
339                 } else {
340                     gradient.addColorStop(0, ‘#d1d1d1‘);
341                     gradient.addColorStop(1, ‘#f9f9f9‘);
342                 }
343                 context.fillStyle = gradient;
344                 context.fill();
345             }
346
347             //销毁棋子
348             var minusStep = function(i, j) {
349                 //擦除该圆
350                 context.clearRect((i) * 30, (j) * 30, 30, 30);
351                 // 重画该圆周围的格子
352                 context.beginPath();
353                 context.moveTo(15 + i * 30, j * 30);
354                 context.lineTo(15 + i * 30, j * 30 + 30);
355                 context.moveTo(i * 30, j * 30 + 15);
356                 context.lineTo((i + 1) * 30, j * 30 + 15);
357                 context.stroke();
358             }
359         </script>
360     </body>
361 </html>

原文地址:https://www.cnblogs.com/sdadawa123-/p/10559461.html

时间: 2024-10-01 03:31:35

用原生js+canvas实现五子棋的相关文章

原生js canvas 碰撞游戏的开发笔记

-----------------------------------------------福利--------------------------------------------- -----------------------------------------------分割线--------------------------------------------- 今天 我们研究下碰撞游戏 什么是碰撞游戏? 当然是东西碰到在一起啦 用前端逻辑来说 就是2个物品互相碰撞产生的事件 问

原生js canvas 碰撞游戏的开发笔记2

随着碰撞游戏一的开发成功! 我们的ae小伙子也大胆尝试很多新方案h5.. 所以就诞生了下面个比较变态的游戏. 先体验下吧 类似坦克大战 开发的过程异常的艰辛 不过也很好玩 修正了很多一的错误 和改良了一些思路 1. 原先的canvas的_this存在的全局污染 改良后避免了99% 为了获取windowtouch属性 还是有1%的 希望在三修正 2. 所有的递归函数变缓动函数requestAnimationFrame 增强性能 使动画更流畅 3. 数据和图像分离的更彻底 结构更清晰 对象的创建 对

原生JS实现的h5小游戏-植物大战僵尸

代码地址如下:http://www.demodashi.com/demo/12755.html 项目介绍 本项目是利用原生js实现的h5小游戏-植物大战僵尸,主要结合了一下自己对于h5小游戏的理解,结合面向对象的编程思想进行开发,在实现时使用了部分es6语法,对于es6语法不太熟悉的小伙伴可以先查阅相关资料了解一下. 如有需要,可根据自己的需求修改源码样式.源码配置属性代码,实现个性化定制. 以下为文件目录结构示意图,核心代码在js文件夹下的四个common.js.main.js.game.js

原生js拼图,封装,组件化

利用原生js实现拼图游戏,实现封装,变为插件,组件化,传入参数调用, 使用立即执行函数,将变量私有化,不污染全局, 利用canvas展示效果,减少dom操作,不影响HTML结构: 1 var myPingTu = (function(){ 2 function init(row_i,dom){ 3 var myCanvas = dom; 4 var row = row_i || 3,// 行列数 5 arr = [], 6 num = row * row;// 块个数 7 if (!myCanv

原生js实现折线图

不借助Echarts等图形框架原生JS快速实现折线图效果 1. 折线图效果预览 例如下图所示的折线图效果实现就很简单: 调用下面这段JS代码中的方法就好了: 假设页面上需要连接的所有点元素集合是eleDots,则页面上执行下fnLineChart(eleDots)效果就出来了. 当然,这段JS只处理长度和角度这两个动态属性,其他固定的样式还需要CSS配合,例如,线条的粗细和线条颜色,例如下面这个粗细2像素的绿色折线,可以这样: 2. 斜线效果实现的原理 1)计算两点之间的直线长度 这个应该属于初

前端对base64编码的理解,原生js实现字符base64编码

目录 常见对base64的认知(不完全正确) 多问一个为什么,base64到底是个啥? 按照我们的思路实现一下 到这里基本就实现了,结果跟原生的方法打印的是一样的 下一次 @( 对于前端工程师来说base64图片编码到底是个什么玩意?) **** ---- 常见对base64的认知(不完全正确) 首先对base64常见的认知,也是须知的必须有以下几点* base64是一种图片编码方式,用一长串超长的字符串表示图片 在加载的时候会直接以字符串的形式加载出来,减少了图片加载的http请求 正常加载服

利用原生JS实现网页1920banner图滚动效果

内容描述:随着PC设备硬件性能的进步和分辨率的不断提高,现在主流网站逐渐开始采用1920banner图,为适应这一趋势,博主设计了1920banner图的滚动效果,代码利用了原生JS实现了1920banner图的切换效果,并针对低分辨率电脑设备进行了适配,实现了JS代码与HTML代码的完全分离,符合w3c的标准使用规范,希望能给各位开发者朋友以帮助和参考.如发现有缺陷和不足,欢迎大家予以指正,如有更好的意见或解决方法,可在评论区交流互动.一下为代码内容: <!DOCTYPE html> <

原生JS写的ajax函数

参照JQuery中的ajax功能,用原生JS写了一个ajax,功能相对JQuery要少很多,不过基本功能都有,包括JSONP. 调用的方式分为两种: 1. ajax(url, {}); 2. ajax({}); 调用的方法参照JQuery的ajax,只是 不需要写$.ajax ,只需要写 ajax 就可以了. 代码如下: !function () { var jsonp_idx = 1; return ajax = function (url, options) { if (typeof url

原生js自动触发事件

熟悉jquery的童鞋都知道在jq中有一个方法可以自动触发事件,那就是trigger(),那么通过原生js又怎么模拟触发呢? js中添加一个主动触发事件的方法有dispatch.该方法能模拟用户行为,如点击(click)操作等. 标准使用dispatchEvent方法,IE6/7/8则使用fireEvent方法. dispatchEvent() 方法给节点分派一个合成事件. 语法如下: dispatchEvent(eventObj) eventObj 参数是一个描述事件的 ActionScrip