老師,為何【贏法統計數組初始化】寫到【贏法種類索引】前面(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;//輪流下棋
}
}
*/
2016-04-20
javascript的執行順序是從上到下,for(var i=0; i<count; i++)里的count是在后面定義且經過循環自增的,你可以在這里alert(count)看下結果應該是undefiend.