zoukankan      html  css  js  c++  java
  • js实现五子棋人机对战源码

    indexhtml

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>五子棋</title>
     6     <meta name="viewport" content="width=device-width"> <!-- 适应移动屏幕 -->
     7     <link rel="stylesheet" type="text/css" href="style.css">
     8 </head>
     9 <body>
    10     <h1>五子棋人机对战版</h1>
    11     
    12     <canvas id="chess" width="450px" height="450px">
    13     </canvas>
    14     <div id="restart">
    15         <span>重新开始</span>
    16     </div>
    17     <!-- <script type="text/javascript" src="script.js"></script> --> <!-- 未封装版本 -->
    18     <script type="text/javascript" src="gobang.js"></script>  <!-- 封装版本 -->
    19 </body>
    20 </html>
    View Code

    style.css

     1 h1{
     2     text-align: center;
     3     margin-top: 5%;
     4 }
     5 #restart{
     6     display: block;
     7     margin: 20px auto;
     8     width: 100px;
     9     padding: 10px 10px;
    10     background-color: #8f7a66;
    11     text-align: center;
    12     font-size: 24px;
    13     color: white;
    14     border-radius: 10px;
    15     text-decoration: none;
    16 }
    17 #restart:hover {
    18     background-color: #9f8b77;
    19 }
    20 canvas {
    21   margin: 0 auto;
    22   display: block;
    23   -moz-box-shadow: -2px -2px 2px #EFEFEF, 5px 5px 5px #b9b9b9;
    24   -webkit-box-shadow: -2px -2px 2px #EFEFEF, 5px 5px 5px #b9b9b9;
    25   box-shadow: -2px -2px 2px #EFEFEF, 5px 5px 5px #b9b9b9;
    26 }
    View Code

    scrit.js (未封装版本)

      1 //全局变量
      2 var me = true; //黑棋先手 
      3 var over = false; //判断游戏是否结束
      4 //棋盘落子情况初始化为空
      5 var chessBoard = new Array();
      6 
      7 var init = function(){
      8     for (var i=0; i<15; i++) {
      9         chessBoard[i] = [];
     10         for(var j=0; j<15; j++){
     11             chessBoard[i][j] = 0;
     12         }
     13     }
     14 }
     15 
     16 //制作棋盘
     17 var chess = document.getElementById('chess');
     18 var ctx = chess.getContext('2d');
     19 ctx.strokeStyle = "#000000";
     20 
     21 //载入背景图片
     22 var logo = new Image();
     23 logo.src = "logo.jpg";
     24 logo.onload = function(){
     25     ctx.drawImage(logo,0,0,450,450);
     26     drawChessBoard();
     27     init();
     28 }
     29 
     30 var newgame = function(){
     31     location.reload();
     32 }
     33 
     34 //绘制棋盘线
     35 var drawChessBoard = function(){
     36     for(var i=0; i<15; i++){
     37         //画棋盘竖线
     38         ctx.moveTo(15+i*30, 15);
     39         ctx.lineTo(15+i*30, 435);
     40         ctx.stroke(); 
     41         //画棋盘横线
     42         ctx.moveTo(15, 15+i*30);
     43         ctx.lineTo(435, 15+i*30);
     44         ctx.stroke();  
     45     }    
     46 }
     47 
     48 //制作黑白棋子
     49 var oneStep = function(i, j, me){
     50     //画圆
     51     ctx.beginPath();
     52     ctx.arc(15 + i*30, 15 + j*30, 13, 0, 2 * Math.PI);
     53     ctx.closePath();
     54     //渐变
     55     var grd = ctx.createRadialGradient(15 + i*30 + 2, 15 + j*30 - 2, 13, 15 + i*30 + 2, 15 + j*30 - 2, 0); 
     56     if(me){ //黑棋
     57         grd.addColorStop(0, "#0A0A0A");
     58         grd.addColorStop(1, "#636766");
     59     }
     60     else{  //白棋
     61         grd.addColorStop(0, "#D1D1D1");
     62         grd.addColorStop(1, "#F9F9F9");
     63     }   
     64     ctx.fillStyle = grd;
     65     ctx.fill();
     66 }
     67 
     68 //点击棋盘落子
     69 chess.onclick = function(e){
     70     if(over){
     71         return ;
     72     }
     73     if(!me){
     74         return ;
     75     }
     76     var x = e.offsetX;
     77     var y = e.offsetY;
     78     var i = Math.floor(x / 30);
     79     var j = Math.floor(y / 30);
     80     if(chessBoard[i][j] == 0){
     81         oneStep(i, j, me);
     82         chessBoard[i][j] = 1;   //黑棋落子为1
     83      
     84         for(var k=0; k<count; k++){
     85             if(wins[i][j][k]){
     86                 myWin[k]++;
     87                 computerWin[k] = 6; //设置成比5大的数都不会加分
     88                 if(myWin[k] == 5){
     89                     window.alert("You Win !");
     90                     over = true;
     91                 }
     92             }
     93         }
     94         if(!over){
     95             me = !me;
     96             computerAI();
     97         }
     98     }
     99 }
    100 //计算机下棋
    101 var computerAI = function(){
    102     var myScore = [];
    103     var computerScore = [];
    104     var max = 0;
    105     var u = 0, v = 0;
    106     for(var i=0; i<15; i++){
    107         myScore[i] = [];
    108         computerScore[i] =[];
    109         for(var j=0; j<15; j++){
    110             myScore[i][j] = 0;
    111             computerScore[i][j] = 0;
    112         }
    113     }
    114     for(var i=0; i<15; i++){
    115         for(var j=0; j<15; j++){
    116             if(chessBoard[i][j] == 0){
    117                 for(var k=0; k<count; k++){
    118                     if(wins[i][j][k]){
    119                         if(myWin[k] == 1){
    120                             myScore[i][j] += 200;
    121                         }else if(myWin[k] == 2){
    122                             myScore[i][j] += 400;
    123                         }else if(myWin[k] == 3){
    124                             myScore[i][j] += 2000;
    125                         }else if(myWin[k] == 4){
    126                             myScore[i][j] += 10000;
    127                         }
    128 
    129                         if(computerWin[k] == 1){
    130                             computerScore[i][j] += 220;
    131                         }
    132                         else if(computerWin[k] == 2){
    133                             computerScore[i][j] += 420;
    134                         }
    135                         else if(computerWin[k] == 3){
    136                             computerScore[i][j] += 2100;
    137                         }
    138                         else if(computerWin[k] == 4){
    139                             computerScore[i][j] += 20000;
    140                         }
    141                     }
    142                 }
    143                 if(myScore[i][j] > max){
    144                     max = myScore[i][j];
    145                     u = i;
    146                     v = j;                  
    147                 }
    148                 else if(myScore[i][j] == max){
    149                     if(computerScore[i][j] > computerScore[u][v]){
    150                         u = i;
    151                         v = j;                      
    152                     }
    153                 }
    154 
    155                 if(computerScore[i][j] > max){
    156                     max = computerScore[i][j];
    157                     u = i;
    158                     v = j;                  
    159                 }
    160                 else if(computerScore[i][j] == max){
    161                     if(myScore[i][j] > myScore[u][v]){
    162                         u = i;
    163                         v = j;                      
    164                     }
    165                 }
    166             }
    167         }
    168     }
    169     oneStep(u, v, false);
    170     chessBoard[u][v] = 2;  
    171     
    172     for(var k = 0; k < count; k++){
    173         if(wins[u][v][k]){
    174             computerWin[k]++;
    175             myWin[k] = 6;
    176             if(computerWin[k] == 5){
    177                 window.alert("Computer Win !")
    178                 over = true;
    179             }
    180         }
    181     }
    182     if(!over){
    183         me = !me;
    184     }    
    185 }
    186 
    187 
    188 //更改鼠标指针样式
    189 chess.onmousemove = function(e){
    190     chess.style.cursor = "default";
    191     var x = e.offsetX;
    192     var y = e.offsetY;
    193     for(var i=0; i<15; i++){
    194         for(var j=0; j<15; j++){
    195             var a = x - (15+i*30);
    196             var b = y - (15+j*30);
    197             var distance = Math.hypot(a, b);
    198             var chessRange = Math.sqrt(25, 2);
    199             //在交叉处半径为5的范围内,鼠标变成手指样式
    200             if(distance < chessRange){
    201                 chess.style.cursor = "pointer";
    202             }
    203         }
    204     }
    205 }
    206 
    207 
    208 //赢法数组
    209 var wins = new Array();
    210 
    211 //定义赢法的三维数组
    212 for(var i=0; i<15; i++){
    213     wins[i] = [];
    214     for(var j=0; j<15; j++){
    215         wins[i][j] = [];
    216     }
    217 }
    218 var count = 0;
    219 
    220 //横线赢法
    221 for(var i=0; i<15; i++){
    222     for(var j=0; j<11; j++){
    223         for(var k=0; k<5; k++){
    224             wins[i][j+k][count] = true;  
    225         }
    226         count++;
    227     }
    228 }
    229 
    230 //竖线赢法
    231 for(var i=0; i<15; i++){
    232     for(var j=0; j<11; j++){
    233         for(var k=0; k<5; k++){
    234             wins[j+k][i][count] = true;  
    235         }
    236         count++;
    237     }
    238 }
    239 
    240 //斜线赢法
    241 for(var i=0; i<11; i++){
    242     for(var j=0; j<11; j++){
    243         for(var k=0; k<5; k++){
    244             wins[i+k][j+k][count] = true;  
    245         }
    246         count++;
    247     }
    248 }
    249 
    250 //反斜线赢法
    251 for(var i = 0; i < 11; i++){
    252     for(var j= 14; j > 3; j--){
    253         for(var k = 0; k < 5; k++){
    254             wins[i+k][j-k][count] = true;
    255         }
    256         count++;
    257     }
    258 }
    259 console.log(count);
    260 
    261 
    262 //赢法统计数组
    263 var myWin = [];
    264 var computerWin = [];
    265 
    266 //赢法统计数组初始化
    267 for(var i=0; i<count; i++){
    268     myWin[i] = 0;
    269     computerWin[i] = 0;
    270 }
    View Code

    gobang.js(函数封装版本)

      1 //gobang 封装实现
      2 (function(){
      3     //定义变量
      4     var chess = document.getElementById('chess');  //获取棋盘画布
      5     var ctx = chess.getContext('2d');  //设置画布渲染
      6     var logo = new Image(); //创建棋盘背景图像
      7     var chessBoard = new Array();  //棋盘落子统计,用于存储棋盘格上是否有落子
      8     var wins = [];  //赢法数组
      9     var count = 0;  //赢法统计数组
     10     var myWin = [];  //玩家赢法统计
     11     var computerWin = [];  //计算机赢法统计
     12     var me = true; //棋手标记 true为玩家下棋,false为电脑下棋 
     13     var over = false; //判断对局是否结束标记 true为结束,flase为未结束
     14 
     15     var goBang = {
     16         //入口
     17         init: function(){
     18             var _this = this;  //复制this对象
     19             return (function(){
     20                 //变量初始化
     21                 _this.initializa();
     22                 //图片加载点
     23                 logo.onload = function(){
     24                     //填充背景图片
     25                     ctx.drawImage(logo,0,0,450,450);
     26                     //绘制棋盘线
     27                     _this.drawChessBoard();  
     28                     // _this.oneStep(7,7,false); //测试oneStep函数                                   
     29                 };
     30 
     31                 //落子事件绑定
     32                 //点击棋盘落子
     33                 chess.onclick = function(e){
     34                     //判断对局是否结束或是否轮到玩家下棋,对局结束或者不是玩家下棋就会跳出循环
     35                     if(over || me == false){
     36                         return ;
     37                     }
     38                     //获取鼠标点击位置坐标,并转换为落点坐标
     39                     var x = e.offsetX,
     40                         y = e.offsetY;
     41                     var i = Math.floor(x / 30),
     42                         j = Math.floor(y / 30);
     43                     //判断当前落点是否已有棋子,如果没有则落子成功
     44                     if(chessBoard[i][j] == 0){
     45                         _this.oneStep(i, j, me);  //玩家落子
     46                         chessBoard[i][j] = 1;   //玩家黑棋落子为1
     47                         for(var k=0; k<count; k++){
     48                             if(wins[i][j][k]){
     49                                 myWin[k]++;
     50                                 computerWin[k] = 999; //设置成比5大的数都不会加分
     51                                 if(myWin[k] == 5){
     52                                     window.alert("You Win !");
     53                                     over = true;
     54                                 }
     55                             }
     56                         }
     57                         //判断对局是否未结束,如果未结束将换成计算机下子
     58                         if(over == false){
     59                             me = !me;
     60                             _this.computerAI(); //计算机落子
     61                         }
     62                     }
     63                 };
     64 
     65                 //更改鼠标指针样式
     66                 chess.onmousemove = function(e){
     67                     chess.style.cursor = "default";
     68                     var x = e.offsetX;
     69                     var y = e.offsetY;
     70                     for(var i=0; i<15; i++){
     71                         for(var j=0; j<15; j++){
     72                             var a = x - (15+i*30);
     73                             var b = y - (15+j*30);
     74                             var distance = Math.hypot(a, b);
     75                             var chessRange = Math.sqrt(25, 2);
     76                             //在交叉处半径为5的范围内,鼠标变成手指样式
     77                             if(distance < chessRange){
     78                                 chess.style.cursor = "pointer";
     79                             }
     80                         }
     81                     }
     82                 };
     83 
     84             })();
     85         },
     86 
     87         //变量&初始化&参数设置
     88         initializa: function(){
     89             return (function(){
     90                 //棋盘线条颜色
     91                 ctx.strokeStyle = "#000000"; //黑色
     92                 //载入背景图片
     93                 logo.src = "logo.jpg";
     94                 //棋盘棋盘落子统计初始化(无落子) chessBoard
     95                 for (var i=0; i<15; i++) {
     96                     chessBoard[i] = [];
     97                     for(var j=0; j<15; j++){
     98                         chessBoard[i][j] = 0;
     99                     }
    100                 } 
    101                 //定义赢法的三维数组 wins
    102                 for(var i=0; i<15; i++){
    103                     wins[i] = [];
    104                     for(var j=0; j<15; j++){
    105                         wins[i][j] = [];
    106                     }
    107                 } 
    108                 //赢法总类统计 共计572种
    109                 //横线赢法
    110                 for(var i=0; i<15; i++){
    111                     for(var j=0; j<11; j++){
    112                         for(var k=0; k<5; k++){
    113                             wins[i][j+k][count] = true;  
    114                         }
    115                         count++;
    116                     }
    117                 }
    118                 //竖线赢法
    119                 for(var i=0; i<15; i++){
    120                     for(var j=0; j<11; j++){
    121                         for(var k=0; k<5; k++){
    122                             wins[j+k][i][count] = true;  
    123                         }
    124                         count++;
    125                     }
    126                 }
    127                 //斜线赢法
    128                 for(var i=0; i<11; i++){
    129                     for(var j=0; j<11; j++){
    130                         for(var k=0; k<5; k++){
    131                             wins[i+k][j+k][count] = true;  
    132                         }
    133                         count++;
    134                     }
    135                 }
    136                 //反斜线赢法
    137                 for(var i = 0; i < 11; i++){
    138                     for(var j= 14; j > 3; j--){
    139                         for(var k = 0; k < 5; k++){
    140                             wins[i+k][j-k][count] = true;
    141                         }
    142                         count++;
    143                     }
    144                 }
    145                 console.log(count);  //赢法总类输出
    146                 //赢法统计数组初始化
    147                 for(var i=0; i<count; i++){
    148                     myWin[i] = 0;
    149                     computerWin[i] = 0;
    150                 }
    151             })();
    152         },
    153 
    154         //绘制棋盘
    155         drawChessBoard: function(){
    156             return (function(){
    157                 for(var i=0; i<15; i++){
    158                     //画棋盘竖线
    159                     ctx.moveTo(15+i*30, 15);
    160                     ctx.lineTo(15+i*30, 435);
    161                     ctx.stroke(); 
    162                     //画棋盘横线
    163                     ctx.moveTo(15, 15+i*30);
    164                     ctx.lineTo(435, 15+i*30);
    165                     ctx.stroke();  
    166                 }       
    167             })();
    168         },
    169 
    170         //绘制黑白棋子
    171         oneStep: function(i, j, me){
    172             return (function(){
    173                 //阴影
    174                 ctx.shadowOffsetX = 1.5;
    175                 ctx.shadowOffsetY = 2;
    176                 ctx.shadowBlur = 3;
    177                 ctx.shadowColor = '#333';
    178                 //画圆
    179                 ctx.beginPath();
    180                 ctx.arc(15 + i*30, 15 + j*30, 13, 0, 2 * Math.PI);
    181                 ctx.closePath();
    182                 //渐变
    183                 var grd = ctx.createRadialGradient(15 + i*30 + 2, 15 + j*30 - 2, 13, 15 + i*30 + 2, 15 + j*30 - 2, 0); 
    184                 if(me){ //黑棋
    185                     grd.addColorStop(0, "#0A0A0A");
    186                     grd.addColorStop(1, "#636766");
    187                 }
    188                 else{  //白棋
    189                     grd.addColorStop(0, "#D1D1D1");
    190                     grd.addColorStop(1, "#F9F9F9");
    191                 }   
    192                 ctx.fillStyle = grd;
    193                 ctx.fill();                
    194             })();
    195         },
    196 
    197         //计算机下棋
    198         computerAI: function(){
    199             var that = this; //复制this对象
    200             return (function(){
    201                 //定义变量,分数统计数组和坐标存储变量
    202                 var myScore = [],
    203                     computerScore = [];
    204                 var max = 0,
    205                     u = 0, v = 0;
    206                 //分数统计初始化
    207                 for(var i=0; i<15; i++){
    208                     myScore[i] = [];
    209                     computerScore[i] = [];
    210                     for(var j=0; j<15; j++){
    211                         myScore[i][j] = 0;
    212                         computerScore[i][j] = 0;
    213                     }
    214                 }
    215                 //分数(权重)统计&计算,获取坐标
    216                 for(var i=0; i<15; i++){
    217                     for(var j=0; j<15; j++){
    218                         //判断当前位置是否没有落子
    219                         if(chessBoard[i][j] == 0){
    220                             //根据赢法数组计算分数
    221                             for(var k=0; k<count; k++){
    222                                 //如果存在第K种赢法的可能性
    223                                 if(wins[i][j][k]){
    224                                     if(myWin[k] == 1){
    225                                         myScore[i][j] += 200;
    226                                     }else if(myWin[k] == 2){
    227                                         myScore[i][j] += 400;
    228                                     }else if(myWin[k] == 3){
    229                                         myScore[i][j] += 2000;
    230                                     }else if(myWin[k] == 4){
    231                                         myScore[i][j] += 10000;
    232                                     }
    233 
    234                                     if(computerWin[k] == 1){
    235                                         computerScore[i][j] += 220;
    236                                     }
    237                                     else if(computerWin[k] == 2){
    238                                         computerScore[i][j] += 420;
    239                                     }
    240                                     else if(computerWin[k] == 3){
    241                                         computerScore[i][j] += 2100;
    242                                     }
    243                                     else if(computerWin[k] == 4){
    244                                         computerScore[i][j] += 20000;
    245                                     }
    246                                 }
    247                             }
    248                             //通过判断获取最优的落子点
    249                             if(myScore[i][j] > max){
    250                                 max = myScore[i][j];
    251                                 u = i;
    252                                 v = j;                  
    253                             }else if(myScore[i][j] == max){
    254                                 if(computerScore[i][j] > computerScore[u][v]){
    255                                     u = i;
    256                                     v = j;                      
    257                                 }
    258                             }
    259 
    260                             if(computerScore[i][j] > max){
    261                                 max = computerScore[i][j];
    262                                 u = i;
    263                                 v = j;                  
    264                             }else if(computerScore[i][j] == max){
    265                                 if(myScore[i][j] > myScore[u][v]){
    266                                     u = i;
    267                                     v = j;                      
    268                                 }
    269                             }
    270                         }
    271                     }
    272                 }
    273                 that.oneStep(u, v, false);  //计算机落子
    274                 chessBoard[u][v] = 2;  ////玩家白棋落子为2
    275                 //判断当前落点是否已有棋子,如果没有则落子成功,如果有则后台提示
    276                 for(var k = 0; k < count; k++){
    277                     if(wins[u][v][k]){
    278                         computerWin[k]++;
    279                         myWin[k] = 999;
    280                         if(computerWin[k] == 5){
    281                             window.alert("Computer Win !")
    282                             over = true;
    283                         }
    284                     }
    285                 }
    286                 if(over == false){
    287                     me = !me;
    288                 }    
    289             })();
    290         },
    291     };
    292 
    293     //重新开始
    294     document.getElementById('restart').onclick = function(){
    295         window.location.reload();
    296     }
    297     //执行代码
    298     goBang.init(); 
    299     
    300 })();
    View Code

    棋盘背景图

     效果预览

  • 相关阅读:
    JavaScript的语法、数据类型、基本算数和逻辑运算操作
    ES6之常用开发知识点:入门(一)
    ES6中map数据结构
    VUE路径问题

    JS简易计算器的实现,以及代码的优化
    格雷编码
    H5网页布局+css代码美化
    jQuery---五角星评分案例
    Ajax工作原理及优缺点
  • 原文地址:https://www.cnblogs.com/guorange/p/7191874.html
Copyright © 2011-2022 走看看