简单AI五子棋,js,canvas
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单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; } }
关键是每次计算机落子的时候,遍历棋盘上的所有点,计算出该点落子的得分。
得分有两种,一种是阻击对方胜利,一种是己方胜利得分。
按代码逻辑来说,应该是计算机主动攻击,不过在实际过程中倒是计算机一直在被动防御。
这里有几个比较吊的地方。首先是在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的主要内容,如果未能解决你的问题,请参考以下文章