现场编写与AI一起玩五子棋呀!

发布时间 2023-05-25 19:34:44作者: 2小只
  

 

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