首页 > 代码库 > 简单AI五子棋,js,canvas

简单AI五子棋,js,canvas

新年第一篇博客,最近几天走亲访友的没有学习。今天开始进入学习模式。

<!DOCTYPE html><html><head>    <title>五子棋</title>    <link rel="stylesheet" type="text/css" href="./css/style.css"></head><body>    <canvas id="chess" width="450px" height="450px">            </canvas>    <script type="text/javascript" src="./js/script.js"></script></body></html>
canvas{    display: block;    margin: 50px auto;    box-shadow: -2px -2px 2px #efefef,5px 5px 5px #b9b9b9;}

 

接下来是js代码,也是精华

技术分享
var over=false;//游戏是否结束//构造赢法数组var wins=[];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++){        for(var k=0;k<5;k++){            wins[i][j+k][count]=true;        }        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(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++;    }}//赢法统计数组var myWin=[]var computerWin=[]for(var i=0;i<count;i++){    myWin[i]=0;    computerWin=0;}var chessBorad=[]//标记棋盘是否使用过for(var i=0;i<15;i++){    chessBorad[i]=[];    for(var j=0;j<15;j++){        chessBorad[i][j]=0;    }}var me=true;var chess=document.getElementById(‘chess‘);var context=chess.getContext(‘2d‘);context.strokeStyle="#bfbfbf";var logo=new Image();logo.src="bg.jpg";logo.onload=function(){    context.drawImage(logo,0,0,450,450);    drawChessBoard();    // oneStep(0,0,1)    // oneStep(0,1,0)}var drawChessBoard=function(){    for(var i=0;i<15;i++){        context.moveTo(15+i*30,15)        context.lineTo(15+i*30,435)        context.stroke();        context.moveTo(15,15+i*30)        context.lineTo(435,15+i*30)        context.stroke();        }}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+2,15+j*30+2,13,15+i*30+2,15+j*30+2,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;    var x=e.offsetX;    var y=e.offsetY;    var i=Math.floor(x/30);    var j=Math.floor(y/30);    if(!chessBorad[i][j]){        if(!me) return;        if(me){            oneStep(i,j,me);            chessBorad[i][j]=1;        }else{            oneStep(i,j,me);            chessBorad[i][j]=2;        }        for(var k=0;k<count;k++){            if(wins[i][j][k]) {                myWin[k]++;                computerWin[k]=6;//表示该赢法舍弃            }            if(myWin[k]==5){                window.alert(k);                over=true;            }        }        if(!over){            me=!me;            computerAI();        }    }}computerAI=function(){    var myScore=[];    var computerScore=[];    var max=0,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(chessBorad[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]+=100000;                        }                        if(computerWin[k]==1){                            computerScore[i][j]+=220;                        }else if(computerWin[k]==2){                            computerScore[i][j]+=420;                        }else if(computerWin[k]==3){                            computerScore[i][j]+=2100;                        }else if(computerWin[k]==4){                            computerScore[i][j]+=200000;                        }                    }                }                if(myScore[i][j]>max){                    max=myScore[i][j];                    u=i;                    v=j;                }else if(myScore==max){                    if(computerScore[i][j]>max){                             u=i;                        v=j;                    }                }                if(computerScore[i][j]>max){                    max=cmputerScore[i][j];                    u=i;                    v=j;                }else if(computerScore==max){                    if(myScore[i][j]>max){                             u=i;                        v=j;                    }                }            }        }    }    //计算机落子    oneStep(u,v,false);    chessBorad[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;        }}
View Code

关键是每次计算机落子的时候,遍历棋盘上的所有点,计算出该点落子的得分。

得分有两种,一种是阻击对方胜利,一种是己方胜利得分。

按代码逻辑来说,应该是计算机主动攻击,不过在实际过程中倒是计算机一直在被动防御。

 

这里有几个比较吊的地方。首先是在canvas上面进行绘制棋盘和棋子。

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

 

绘制棋子使用渐变色填充

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+2,15+j*30+2,13,15+i*30+2,15+j*30+2,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;    var x=e.offsetX;    var y=e.offsetY;    var i=Math.floor(x/30);    var j=Math.floor(y/30);

捕捉到canvas上面的点击事件,及鼠标点击位置,将其转化成棋盘上面的坐标。简直神奇。

 

其实我很想骂人的,但我忍住了,,

简单AI五子棋,js,canvas