JavaScript-实现五子棋的简单整体设计

这个程序界面大体是参考B站上的视频"B站技术最屌的程序员,30分钟java开发人工智能五子棋,看完我是服气"
算法部分视频中没解释,我是参考网上的各种资源选定的一个比较简单的算法.

先上代码,我把自己修改的和之前的都保存着.

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>Document</title>

  <style>
  *{margin:0;}/*解决浏览器的兼容性问题*/
  body{background:url("http://pic.58pic.com/58pic/15/24/50/43Q58PICkj4_1024.jpg");background-size:cover;}
  canvas{background:#fff;margin:100px auto;display:block;/*border:10px solid #ccff33;*/box-shadow:0px 0px 0px #000}/*margin 上下 左右*/
  
 </style>
 </head>
 <body>
  <canvas id="myCanvas" width="450" height="450"></canvas>

  <script>

  var me = true;  
var over = false;  
var chessBox = [];  
var wins = [];         //定义三维数组  
//赢法统计数组  
var myWin = [];  
var computerWin = [];  

/*这是表征棋盘的二维数组*/
for(i=0;i<15;i++){  
    chessBox[i]=[];  
    for(j=0;j<15;j++){  
        chessBox[i][j]=0;  
    }     
}  


for(var i=0;i<15;i++){  
    wins[i]=[];  
    for(var j=0;j<15;j++){  
        wins[i][j]=[];  
    }  
}  
var count =0;  
//所有横线  
for(var i=0;i<15;i++){  
    for(var j=0;j<11;j++){  

		/*这五种表示赢法0
		*
        //执行1次  
        // wins[0][0][0]=true;  
        // wins[0][1][0]=true;  
        // wins[0][2][0]=true;  
        // wins[0][3][0]=true;  
        // wins[0][4][0]=true;
		*
		*/
        //执行2次  
        // wins[0][1][1]=true;  
        // wins[0][2][1]=true;  
        // wins[0][3][1]=true;  
        // wins[0][4][1]=true;  
        // wins[0][5][1]=true;  
        for(var k=0; k<5;k++){  
			
            wins[i][j+k][count] = true;  //这里的count的放入是干啥呢???
        }  
        count++;  
    }  
}  
//所有竖线  
for(var i=0;i<15;i++){  
    for(var j=0;j<11;j++){  
        for(var k=0; k<5;k++){  
            wins[j+k][i][count] = true;  
        }  
        count++;  
    }  
}  
//所有斜线  
for(var i=0;i<11;i++){  
    for(var j=0;j<11;j++){  
        for(var k=0; k<5;k++){  
            wins[i+k][j+k][count] = true;  
        }  
        count++;  
    }  
}  
//所有反斜线,确定一个划线方向  
for(var i=0;i<11;i++){  
    for(var j=14;j>3;j--){  
        for(var k=0; k<5;k++){  
            wins[i+k][j-k][count] = true;  
        }  
        count++;  
    }  
}  
  
console.log(count);  //统计有多少种赢法
for (var i=0;i<count;i++) {  
    myWin[i] = 0;  
    computerWin[i] = 0;  
}  
  
var chess = document.getElementById('myCanvas');  
var context = chess.getContext('2d');  
context.strokeStyle = "#BFBFBF";  
//var logo= new Image();  
//logo.src = "img/木头.jpg";  
//logo.onload = function(){  
   // context.drawImage(logo,0,0,450,450);  
    //drawChessBoard();  
//  oneStep(0,0,true);  
//  oneStep(1,1,false);  
//}  

/*
*
function drawChessBoard(){  
    for(var i=0;i<15;i++){  
    context.moveTo(15+i*30,15);  
    context.lineTo(15+i*30,435);  
    context.moveTo(15,15+i*30);  
    context.lineTo(435,15+i*30);  
    context.stroke();  
 }  
      
} 
*
*/



/*这是画线的*/
var drawChessBoard = function(){

	
for(var i=0;i<15;i++){
	context.moveTo(15+30*i,15);
	context.lineTo(15+30*i,435);
	context.stroke();

	context.moveTo(15,15+30*i);
	context.lineTo(435,15+30*i);
	context.stroke();
 }
}

 window.onload = function(){
           drawChessBoard();
		   //onStep(1,2,true);
 }


/*画棋子*/
var oneStep = function(i,j,me){  
    context.beginPath();  
    context.arc(15+i*30,15+j*30,13,0,2*Math.PI);  
    context.closePath();  
    var gradient = context.createRadialGradient(15+i*30,15+j*30,13,15+i*30,15+j*30,0);  
    if(me){  
        gradient.addColorStop(0,"#0A0A0A");  
        gradient.addColorStop(1,"#636766");  
    }else{  
        gradient.addColorStop(0,"#D1D1D1");  
        gradient.addColorStop(1,"#F9F9F9");  
    }  
      
    context.fillStyle = gradient;  
    context.fill();  
}  
 
  

chess.onclick = function(e){  
    if(over){  //如果结束了
        return;  
    }  
    if(!me){   //不是我
        return;  
    }  
    var x = e.offsetX;  
    var y = e.offsetY;  
    var i = Math.floor(x/30);  //i,j为索引序列号  
    var j = Math.floor(y/30);  
    if(chessBox[i][j]==0){  //这个判定就把
        oneStep(i,j,me);  
      
        chessBox[i][j]=1;  
  
          
        for(var k=0;k < count; k++){  
            if(wins[i][j][k]) {  //表示第k种赢法且棋的坐标位置是i,j,之前已经通过全范围的扫描确定了所有有效的位置
                myWin[k]++;      //第6=k种赢法的标志加1,表示有几颗棋子连线了
                computerWin[k] = 6; //设置异常值  
                if(myWin[k] == 5) {  
                    window.alert("你赢了");  
                    over = true;  
                }  
            }  
        }  
        if(!over){  
            me=!me;  
            computerAI();  
        }  
    }     
      
}  
var computerAI = function(){  
	 //这些标志应该是
     var myScore = [];  
     var computerScore = [];  
     var max = 0; //保存最高分数;  
     var u = 0, v =0; //保存坐标  
     for(var i=0;i<15;i++){  
        myScore[i] = [];  
        computerScore [i] = [];  
        for(var j=0;j<15;j++){  
            myScore[i][j] = 0;  
            computerScore[i][j] = 0;  
        }  
     }  
     for (var i=0; i<15;i++) {  
        for (var j=0;j<15;j++) {  
            if(chessBox[i][j] == 0){  //假定各种目标可能时已经把下过子的地方去掉了,所以不用担心四个黑字夹着一个白子的情况
                for(var k =0 ;k<count;k++){  
                    if(wins[i][j][k]){  
                        if(myWin[k]==1){  
                            myScore[i][j]+= 200;  
                        }else if(myWin[k]==2){  
                            myScore[i][j]+= 400;  
                        }else if(myWin[k]==3){  
                            myScore[i][j]+= 2000;  
                        }else if(myWin[k]==4){  
                            myScore[i][j]+= 10000;  
                        }  

						/*下部是对于电脑棋子的威胁判定*/
                        if(computerWin[k]==1){  
                            computerScore[i][j]+= 220;  
						 //  computerScore[i][j]+= 180;  
                        }else if(computerWin[k]==2){  
                            computerScore[i][j]+= 420;
						   //computerScore[i][j]+= 380;
                        }else if(computerWin[k]==3){  
                            computerScore[i][j]+= 2020;
							//computerScore[i][j]+= 1880;  
                        }else if(computerWin[k]==4){  
                            computerScore[i][j]+= 10020;
							//computerScore[i][j]+= 9800;
                        }  
                    }  
                }  
				//i,j和u,v互换是要干什么,u,v是白棋的坐标,通过上面危险度的比较,确定一个有危险的位置,像现在设定的危险系数,电脑会优先考虑自己的连线
				//???这样是否会造成电脑会优先不管怎样先自己连成四颗子?
                if(myScore[i][j]>max){  
                    max = myScore[i][j];  
                    u = i;  
                    v = j;  
                }else if(myScore[i][j] == max){  
                    if(computerScore[i][j] > computerScore[u][v]){  
                        u = i;  
                        v = j;  
                    }  
                }  
                if(computerScore[i][j]>max){  
                    max = computerScore[i][j];  
                    u = i;  
                    v = j;  
                }else if(computerScore[i][j] == max){  
                    if(myScore[i][j] > myScore[u][v]){  
                        u = i;  
                        v = j;  
                    }  
                }  
            }  
        }  
     }  
     oneStep(u,v,false);  //画白棋
     chessBox[u][v] = 2;  
     for(var k=0;k < count; k++){  
            if(wins[u][v][k]) {  
                computerWin[k]++;  
                myWin[k] = 6; //设置异常值  
                if(computerWin[k] == 5) {  
                    window.alert("计算机赢了");  
                    over = true;  
                }  
            }  
        }  
        if(!over){  
            me=!me;       
        }  
}  
  </script>
 </body>
</html>

这是我第一次接触人工智能的写法,可以看出这种带系数的AI设定是比较简单的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值