该网页五子棋的实现参照慕课网上五子棋的相关教程
分为两个部分:一个是页面的搭建,一个是AI的实现
1. 棋盘的设计,本例使用15*15的棋盘设计。
利用canvas进行棋盘设计,<canvas> 标签是 HTML 5 中的新标签。
HTML 5 <canvas> 标签
定义和用法
<canvas> 标签定义图形,比如图表和其他图像。
<canvas> 标签只是图形容器,您必须使用脚本来绘制图形。
display: block;
margin: 50px auto;
box-shadow: -2px -2px 2px #EFEFEF,5px 5px 5px #B9B9B9;
}
设置以上样式,形成棋盘。
然后画棋盘中的网格线
var chess=document.getElementById('chess');//得到键盘元素
var cxt=chess.getContext('2d');//获得canvas进行绘图
cxt.strokeStyle='#bfbfbf';//得到棋盘线的颜色样式,即画笔颜色
var logo=new Image();//棋盘的背景样式
logo.src='./images/logo.jpg';
logo.οnlοad=function () {
/* body... */
cxt.globalAlpha=0.2;//设置整个canvas的透明度
cxt.beginPath();//背景绘制
cxt.drawImage(logo,0,0,450,450);
cxt.closePath();
drawChessBoard();//棋盘绘制
};
var drawChessBoard=function(){
cxt.globalAlpha=1;
cxt.save();
for(i=0;i<15;++i)
{
cxt.moveTo(15+i*30,15);
cxt.lineTo(15+i*30,435);
cxt.moveTo(15,15+i*30);
cxt.lineTo(435,15+i*30);
}
cxt.stroke();//直接线条绘制,不用填充绘制
cxt.restore();
};
棋子绘制and落子:
var me=true;//当前落子情况
var chessBoard=[];//棋盘的位置是否有棋子
for(var i=0;i<15;++i){
chessBoard[i]=[];
for(var j=0;j<15;++j){
chessBoard[i][j]=0;
}
}
var oneStep=function(i,j,me){
cxt.beginPath();
cxt.arc(15+i*30,15+j*30,13,0,2*Math.PI);//利用arc绘制圆形
var linearGrad=cxt.createRadialGradient(15+i*30+2,15+j*30-2,13,15+i*30+2,15+j*30-2,0);//设置棋子的渐变
if(me){
linearGrad.addColorStop(0,'#0a0a0a');//黑子渐变
linearGrad.addColorStop(1,'#636766');
}
else{
linearGrad.addColorStop(0,'#d1d1d1');//白子渐变
linearGrad.addColorStop(1,'#f9f9f9');
}
cxt.fillStyle=linearGrad;//填充样式设为渐变
cxt.fill();//进行填充绘制
cxt.closePath();
};
2. AI实现,五子棋的人工智能方法
其中数据结构的设计:
1)赢法数组:记录五子棋所有的赢法,三维数组
2)每一种赢法的统计数组,一维数组
3)如何判断胜负
4)计算机的落子规则
赢法数组
//赢法数组
var wins=[];
//init 所有的赢法数组统计
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(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++;
}
}
//赢法的统计数组
var myWin=[];//人的赢法
var comWin=[];//计算机的赢法
for(var i=0;i<count;++i){
myWin[i]=0;
comWin[i]=0;
}
赢的判断
chess.οnclick=function(e){
if(over||!me)
return;
var x=e.offsetX;
var y=e.offsetY;
var i=Math.floor(x/30);
var j=Math.floor(y/30);
if(chessBoard[i][j]==0){
oneStep(i,j,me);
chessBoard[i][j]=1;
for(var k=0;k<count;++k){
if(wins[i][j][k]){
myWin[k]++;
comWin[k]=6;
if(myWin[k]==5){
window.alert("你赢了!");
over=true;
}
}
}
if(!over){
me=!me;
computerAI();
}
}
};
计算机AI的实现,计算机落在那个子的判断
var computerAI=function(){
var myScore=[];//记录我方得分
var comScore=[];//计录计算机的得分
var max=0;//记录最高分
var u=0,v=0;//记录最高分位置
for(var i=0;i<15;++i){
myScore[i]=[];
comScore[i]=[];
for(var j=0;j<15;++j){
myScore[i][j]=0;
comScore[i][j]=0;
}
}
for(var i=0;i<15;++i)
{
for(var j=0;j<15;++j)
{
if(chessBoard[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(comWin[k]==1){
comScore[i][j]+=220;
}
else if(comWin[k]==2){
comScore[i][j]+=420;
}
else if(comWin[k]==3){
comScore[i][j]+=2100;
}
else if(comWin[k]==4){
comScore[i][j]+=20000;
}
}
}
if(myScore[i][j]>max){
max=myScore[i][j];
u=i;v=j;
}
else if(myScore[i][j]==max){
if(comScore[i][j]>comScore[u][v])
{
u=i;v=j;
}
}
if(comScore[i][j]>max){
max=comScore[i][j];
u=i;v=j;
}
else if(comScore[i][j]==max){
if(myScore[i][j]>myScore[u][v])
{
u=i;v=j;
}
}
}
}
}
oneStep(u,v,false);//u,v位置落子
chessBoard[u][v]=2;
for(var k=0;k<count;++k){
if(wins[u][v][k]){
comWin[k]++;
myWin[k]=6;
if(comWin[k]==5){
window.alert("计算机赢了!");
over=true;
}
}
}//判断计算机是否赢
if(!over){
me=!me;
}
};
实现结束。
AI过程重要在于权值的计算。得分位置最大的即为计算机要下的位置。