二维数组的定义 , 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]=new Array(); //声明二维,每一个一维数组里面的一个元素都是一个数组; 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"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>人工智能五子棋</title> <meta charset="UTF-8" /> <meta name="author" content="张" /> <meta name="keywords" content="五子棋" /> <meta name="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> <canvas width="450" height="450" id="canvas"></canvas> <script> var over = false; var chess = document.getElementById("canvas"); //拿到权限 上下文 2d平面 var context = chess.getContext("2d"); context.strokeStyle="#a8a8a8"; //定义方法 var drawChessboard = function(){ //线条 起点终点坐标(x,y) /* context.moveTo(0,0);//起点坐标 context.lineTo(450,450);//终点坐标 context.stroke();//两点坐标相连 */ 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(); } } drawChessboard(); //绘制棋子 var onStep = function(i,j,me) { //绘制棋子 圆形 圆心(x,y) 半径 //开始路径 区分大小写 context.beginPath(); context.arc(15+i*30,15+j*30,13,0,Math.PI*2); //结束路径 context.closePath(); //渐变色 看文档,两个圆心 半径, var gradient = 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(); } //建立一个二维数组判断棋盘上的落子情况 var chessBoard = []; //把棋盘上面所有的点全部存进去 for (var i=0; i<15; i++) { chessBoard[i] = []; //一维中存入还是数组 for (var j=0; j<15; j++) { chessBoard[i][j] = 0;//等于0的地方没有下棋 } } //下棋 var me = true; chess.onclick = function(e) { if(over) { return false; } if(!me) { return false; } //获取鼠标坐标 var x = e.offsetX; var y = e.offsetY; //点击范围30都可以下棋 向下取整 var i = Math.floor(x/30); var j = Math.floor(y/30); //把落的子放到数组中存储 if (chessBoard[i][j] == 0) { onStep(i,j,me); chessBoard[i][j] = 1; for (var k=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(); } } } //统计赢法的种类 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 (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++; } } //本棋盘 有572中赢发, //统计赢法组 var myWin = [];//全局,用于记录 每在此赢法上下子一个即加一,判断每一种赢法是否达到了5, var computerWin = []; for (var i=0; i<count; i++) { myWin[i] = 0; computerWin[i] = 0; } //计算机AI算法 var computerAI = function () { //统计分数 var mySource = [];//局部数组,我方分数,每次计算机下棋都计算一遍 var computerSource = [];//计算机分数 var max = 0; //最高点分数 var u = 0,v = 0;//最高点分数坐标 //初始化我方和计算机分数 for (var i=0; i<15; i++) { mySource[i] = []; computerSource[i] = []; for (var j=0; j<15; j++) { mySource[i][j] = 0; computerSource[i][j] = 0; } } for (var i=0; i<15; i++) { for (var j=0; j<15; j++) { //这里的两个for是遍历棋盘 if (chessBoard[i][j] == 0) {//这里对每一个没有下过子的 坐标分析,计算该落子的可能性多大 for (var k=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 (var k=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>