老师,为何【赢法统计数组初始化】写到【赢法种类索引】前面(24--27行)会出现白棋只在(0,0)处下一步,后续不再下棋的状况?鞠躬感谢!!
按照教程中老师的写法:将【赢法统计数组初始化】写在【赢法种类索引】后面(67-71行),本代码可以正常运行。但我发现将【赢法统计数组初始化】写在【赢法种类索引】前面时(24-27行),白棋只会在(0,0)处下第一步,后续无动作,且不会弹框。如下图一所示:
赢法统计数组myWin[i],computerWin[i]明明只会在【赢法种类索引】后续(139行以后)才会用到,为何在【赢法种类索引】前初始化会对程序造成影响??
图一:【赢法统计数组初始化】写在24-27行,错误结果
对应错误代码如下:
var me=true;//下棋方为我方黑棋 var chessboard=[];//棋盘状态 var over=false;//棋局未结束 var wins=[];//赢法数组 var myWin=[];//我方赢法统计数组 var computerWin=[];//电脑方赢法统计数组 for (var i=0;i<15;i++) { chessboard[i]=[]; for (var j=0; j<15;j++) { chessboard[i][j]=0; } }//棋盘未落子初始化 for(var i = 0; i < 15; i++) { wins[i]=[]; for(var j = 0; j < 15; j++) { wins[i][j]=[]; } }//赢法数组初始化 for(var i=0;i<count;i++){ myWin[i]=0; computerWin[i]=0; }//赢法统计数组初始化【错误位置】 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++; } }//所有反斜线赢法 console.log(count);// /* for(var i=0;i<count;i++){ myWin[i]=0; computerWin[i]=0; }//赢法统计数组初始化【正确位置】 */ var chess=document.getElementById('chess'); var context=chess.getContext('2d');//返回2D画布绘图的环境 context.strokeStyle="#BFBFBF";//设置绘制颜色#BFBFBF var logo=new Image(); logo.src="images/GoBang.png"; logo.onload=function () { context.drawImage(logo,0,0,450,450);// 图片加载http://www.w3school.com.cn/tags/canvas_drawimage.asp drawChessBoard();//先logo后棋盘网格,避免网格覆盖 //test:oneStep(0,0,true);oneStep(1,1,false); } 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);//交换XY坐标,画纵线 context.stroke(); } } var oneStep = function(i,j,me){//棋盘索引 下棋方 //以下画棋子轮廓--------- context.beginPath(); context.arc(15+i*30,15+j*30,13,0,2*Math.PI);//画弧/圆(圆心X/Y,半径,起始/终止弧度) context.closePath();//用弦封闭弧,可删除 context.stroke();//画轮廓线,原文删除 //以下渐变填充棋子-------- var gradient=context.createRadialGradient(15+i*30+2,15+j*30-2,13,15+i*30+1,15+j*30-1,0); //返回渐变对象,a圆x/y/R b圆x/y/R if(me){ gradient.addColorStop(0,"#0A0A0A");//a圆边缘颜色#0A0A0A gradient.addColorStop(1,"#636766");//b圆边缘颜色#636766 }else{ gradient.addColorStop(0,"#D1D1D1");//a圆边缘颜色#D1D1D1 gradient.addColorStop(1,"#F9F9F9");//b圆边缘颜色#F9F9F9 } //判断下棋是否为我方(黑) context.fillStyle=gradient; //改变纯色填充样式 context.fillStyle="#636766"; context.fill();//填充,默认黑色?? } chess.onclick=function(e){ if(over){ return; }//棋局已结束 if(!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]++; computerWin[k]=6; if(myWin[k]==5){ window.alert("黑棋胜"); over=true; } } } if(!over){ me=!me; computerAI(); } } } var computerAI=function(){ var myScore=[]; var computerScore=[];//得分数组 var max=0;//最高分数 var 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(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(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]+=20000; } } } if(myScore[i][j]>max){ max=myScore[i][j]; u=i; v=j; }else if(myScore[i][j]==max){ if(computerScore[i][j]>computerScore[u][v]){ u=i; v=j; } } if(computerScore[i][j]>max){ max=computerScore[i][j]; u=i; v=j; }else if(computerScore[i][j]==max){ if(myScore[i][j]>myScore[u][v]){ u=i; v=j; } } } } } oneStep(u,v,false); chessboard[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;//轮流下棋 } } /*无法判断胜负???????????? 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(chessboard[i][j]==0){//避免在已落子位置 再次落子 oneStep(i,j,me); if(me){ chessboard[i][j]=1; for(var k=0;k<count;k++){ if(wins[i][j][k]){ myWin[k]++; computerWin[k]=6;//黑子可能占用该种赢法,白子不可能用该种方法赢,顾设为异常值 if(myWin[k]==5){ window.alert("黑棋胜"); over=true; } } } }else{ chessboard[i][j]=2; for(var k=0;k<count;k++){ if(wins[i][j][k]){ computerWin[k]++; myWin[k]=6; if(computerWin[k]==5){ window.alert("白棋胜"); over=true; } } } } me=!me;//轮流下棋 } } */