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