用原生js+canvas实现五子棋
Posted 孤单成瘾
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用原生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>
以上是关于用原生js+canvas实现五子棋的主要内容,如果未能解决你的问题,请参考以下文章