五子棋.html
二维数组的定义 , canvas对象的使用
二维数组:以下用new,其实简化 [] 即可,
var tArray = new Array(); //先声明一维
for(var k=0;k<i;k++){ //一维长度为i,i为变量,可以根据实际情况改变
tArray[k]=new Array(); //声明二维,每一个一维数组里面的一个元素都是一个数组;
for(var j=0;j<p;j++){ //一维数组里面每个元素数组可以包含的数量p,p也是一个变量;
tArray[k][j]=""; //这里将变量初始化,我这边统一初始化为空,后面在用所需的值覆盖里面的值
}
}
--------
for(var a=0;a<i;a++){
tArray[a]=[ matArray[a],addArray[a] ]; 两个 组成一个二维数组
};
var tArray = new Array(); //先声明一维
for(var k=0;k<i;k++){ //一维长度为i,i为变量,可以根据实际情况改变
tArray[k]=newArray(); //声明二维,每一个一维数组里面的一个元素都是一个数组;
for(var j=0;j<p;j++){//一维数组里面每个元素数组可以包含的数量p,p也是一个变量;
tArray[k][j]=""; //这里将变量初始化,我这边统一初始化为空,后面在用所需的值覆盖里面的值
}
}
五子棋代码如下:曾经把它看懂,现在再看感觉又有点忘了,尴尬 2018-11-26 16:57:07
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <htmlxmlns="http://www.w3.org/1999/xhtml"> <head> <title>人工智能五子棋</title> <metacharset="UTF-8" /> <metaname="author"content="张" /> <metaname="keywords"content="五子棋" /> <metaname="description"content="五子棋" /> <style>*{margin:0;}canvas{background:#fff;margin:120px auto;display:block;border-radius:4px;box-shadow:0px 0px 10px #000; } </style> </head> <body> <canvaswidth="450"height="450"id="canvas"></canvas> <script> varover= false;varchess=document.getElementById("canvas");//拿到权限 上下文 2d平面 varcontext=chess.getContext("2d");
context.strokeStyle="#a8a8a8";//定义方法 vardrawChessboard= function(){//线条 起点终点坐标(x,y) /*context.moveTo(0,0);//起点坐标
context.lineTo(450,450);//终点坐标
context.stroke();//两点坐标相连*/ for(vari=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();
}
}
drawChessboard();//绘制棋子 varonStep= function(i,j,me) {//绘制棋子 圆形 圆心(x,y) 半径 //开始路径 区分大小写 context.beginPath();
context.arc(15+i*30,15+j*30,13,0,Math.PI*2);//结束路径 context.closePath();//渐变色 看文档,两个圆心 半径, vargradient=context.createRadialGradient(15+i*30,15+j*30,0,15+i*30,15+j*30,13);if(me) {
gradient.addColorStop(0,"#0a0a0a");
gradient.addColorStop(1,"#636363");
}else{
gradient.addColorStop(0,"#d1d1d1");
gradient.addColorStop(1,"#f9f9f9");
}//填充颜色 context.fillStyle=gradient;
context.fill();
context.stroke();
}//建立一个二维数组判断棋盘上的落子情况 varchessBoard=[];//把棋盘上面所有的点全部存进去 for(vari=0; i<15; i++) {
chessBoard[i]=[];//一维中存入还是数组 for(varj=0; j<15; j++) {
chessBoard[i][j]= 0;//等于0的地方没有下棋 }
}//下棋 varme= true;
chess.onclick= function(e) {if(over) {return false;
}if(!me) {return false;
}//获取鼠标坐标 varx=e.offsetX;vary=e.offsetY;//点击范围30都可以下棋 向下取整 vari=Math.floor(x/30); varj=Math.floor(y/30); //把落的子放到数组中存储 if(chessBoard[i][j]== 0) {
onStep(i,j,me);
chessBoard[i][j]= 1;for(vark=0; k<count; k++) {if(wins[i][j][k]) {//* 这里应该加多一个判断myWin[k]等于或大于6了,直接不用往下操作了。 if(myWin[k]!=6){
myWin[k]++;
computerWin[k]= 6;if(myWin[k]== 5) {
alert("恭喜你赢了!");
over= true;
}
}
}
}if(!over) {
me= !me;
computerAI();
}
}
}//统计赢法的种类 varwins=[];//遍历棋盘 for(vari=0;i<15;i++) {
wins[i]=[];for(varj=0; j<15; j++) {
wins[i][j]=[];
}
}//赢法的索引 varcount= 0;//横线赢 for(vari=0; i<15; i++) {for(varj=0; j<11; j++) {for(vark=0; k<5; k++) {
wins[i][j+k][count]= true;
}
count++;
}
}//竖线赢 for(vari=0; i<15; i++) {for(varj=0; j<11; j++) {for(vark=0; k<5; k++) {
wins[j+k][i][count]= true;
}
count++;
}
}//斜线赢 for(vari=0; i<11; i++) {for(varj=0; j<11; j++) {for(vark=0; k<5; k++) {
wins[i+k][j+k][count]= true;
}
count++;
}
}//反斜线赢 for(vari=0; i<11; i++) {for(varj=14; j>3; j--) {for(vark=0; k<5; k++) {
wins[i+k][j-k][count]= true;
}
count++;
}
}//本棋盘 有572中赢发, //统计赢法组 varmyWin=[];//全局,用于记录 每在此赢法上下子一个即加一,判断每一种赢法是否达到了5, varcomputerWin=[];for(vari=0; i<count; i++) {
myWin[i]= 0;
computerWin[i]= 0;
}//计算机AI算法 varcomputerAI= function() {//统计分数 varmySource=[];//局部数组,我方分数,每次计算机下棋都计算一遍 varcomputerSource=[];//计算机分数 varmax= 0;//最高点分数 varu= 0,v= 0;//最高点分数坐标 //初始化我方和计算机分数 for(vari=0; i<15; i++) {
mySource[i]=[];
computerSource[i]=[];for(varj=0; j<15; j++) {
mySource[i][j]= 0;
computerSource[i][j]= 0;
}
}for(vari=0; i<15; i++) {for(varj=0; j<15; j++) {//这里的两个for是遍历棋盘 if(chessBoard[i][j]== 0) {//这里对每一个没有下过子的 坐标分析,计算该落子的可能性多大 for(vark=0; k<count; k++) {//遍历所有赢法 572钟 if(wins[i][j][k]) {//遍历和该坐标有关的赢法,有关往下执行 if(myWin[k]== 1) {//若该赢法上 落子为1,加一定的分数;myWin[k]这个值是在我方下棋时累加的 mySource[i][j]+= 200;
}else if(myWin[k]== 2) {//若该赢法上 落子为2,再加一定的分数 mySource[i][j]+= 400;
}else if(myWin[k]== 3) {//若该赢法上 落子为3,再加一定的分数 mySource[i][j]+= 2000;
}else if(myWin[k]== 4) {
mySource[i][j]+= 10000;
}if(computerWin[k]== 1) {//同理,对计算机下的期判断,累加分数 computerSource[i][j]+= 420;
}else if(computerWin[k]== 2) {
computerSource[i][j]+= 820;
}else if(computerWin[k]== 3) {
computerSource[i][j]+= 4100;
}else if(computerWin[k]== 4) {
computerSource[i][j]+= 20000;
}
}
}if(mySource[i][j]>max) {//这个坐标对于我赢的概率和之前最大的比 max=mySource[i][j];
u=i;
v=j;
}else if(mySource[i][j]==max) {//如果两个点对自己相同,那两个点对敌方哪个更有利? if(computerSource[i][j]>computerSource[u][v]) {
u=i;
v=j;
}
}if(computerSource[i][j]>max) {//这个坐标对于计算机的概率和之前最大的比 max=computerSource[i][j];
u=i;
v=j;
}else if(computerSource[i][j]==max) {if(mySource[i][j]>mySource[u][v]) {
u=i;
v=j;
}
}
}
}
}
onStep(u,v,false);
chessBoard[u][v]= 2;for(vark=0; k<count; k++) {if(wins[u][v][k]) {//* 这里应该加多一个判断computerWin[k]等于或大于6了,直接不用往下操作了。 if(computerWin[k]!=6){
computerWin[k]++;
myWin[k]= 6;if(computerWin[k]== 5) {
alert("计算机赢了!");
over= true;
}
}
}
}if(!over) {
me= !me;
}
}</script> </body> </html>