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>