five-chess.html 12 KB

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