第28講 細胞構成法による魔方陣の作成△

第5話 細胞の作成の解説その3

コード例

               ・
               ・
        //細胞の作成関数
        void sbs(char
g){
          char i,j,k,h;
          for(i=1;i<5;i++){
             sb[sy[g]][sx[g]]=i;
             h=1;
             if(g>0){
               for(j=0;j<g;j++){
                 if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
               }
             }
             if(h==1){
               if(g+1<4){
                 sbs(g+1);
               }
               else{
                 for(j=0;j<2;j++){
                   for(k=0;k<2;k++){
                     sbr[cn][j][k]=sb[j][k];
                   }
                 }
                 cn++;
               }
             }
           }
         }

              ・
              ・
解説の続きその2
ではトレースしていきましょう。世界次元番号(セル番号)を

  0  1 

で表し、内容を

  0  1 

で表すことにします。空間識別番号(世界次元番号)と内容が似ていますが、
くどいようですが、空間識別番号はビール瓶のラベルですし、内容はビール瓶に入っているビールに相当するものなので、
全然違うものです。
        void sbs(char g){
          char i,j,k,h;
          for(
i=1;i<5;i++){                
の役割の違いを明確に理解することが、コード理解のミソです。

ではトレースを開始します。
最初、private: System::Void button1_Clickから
            sbs(0); //細胞の作成
によって、次元番号
の世界が呼び出されます。

  0  1 
  0  1 

          for(i=1;i<5;i++){
             sb[sy[g]][sx[g]]=
i;
の最初のループによって

  0  1 
  0  1 

となります。
             if(g>0){
               for(j=0;j<g;j++){
                 if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
               }
             }

             if(h==1){
               if(g+1<4){
                 sbs(g+1);
               }

               else{
                 for(j=0;j<2;j++){
                   for(k=0;k<2;k++){
                     sbr[cn][j][k]=sb[j][k];
                   }
                 }
                 cn++;
               }
             }
g = 0ですから、
             if(g>0){
               for(j=0;j<g;j++){
                 if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
               }
             }

は無視され、
             if(h==1){
               if(g+1<4){
                 sbs(g+1);
               }

が実行されて、

  0  1 
  0  1 

空間識別番号の世界に入ります。
          for(i=1;i<5;i++){
             sb[sy[g]][sx[g]]=i;
の最初のループによって

  0  1 
  0  1 

となりますが、今回はg = 1ですから、
             
if(g>0){
               for(j=0;j<g;j++){
                 if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
               }
             }

に抵触し、
             if(h==1){
               if(g+1<4){
                 sbs(g+1);
               }

               else{
                 for(j=0;j<2;j++){
                   for(k=0;k<2;k++){
                     sbr[cn][j][k]=sb[j][k];
                   }
                 }
                 cn++;
               }
             }
がスルーされ、
          for(i=1;i<5;i++){
             sb[sy[g]][sx[g]]=i;
の2回目のループによって

  0  1 
  0  1 

となります。今回は、
             if(g>0){
               for(j=0;j<g;j++){
                 if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
               }
             }

をクリアして、
            
 if(h==1){
               if(g+1<4){
                 sbs(g+1);
               }

が実行されて、空間識別番号
の世界へと飛翔します。

  0  1 
  0  1 

          for(i=1;i<5;i++){
             sb[sy[g]][sx[g]]=i;
の最初のループによって

  0  1 
  0  1 

となりますが、
             if(g>0){
               for(j=0;j<g;j++){
                 if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
               }
             }

の1巡目でチェックされ、
             if(h==1){
               if(g+1<4){
                 sbs(g+1);
               }
               else{
                 for(j=0;j<2;j++){
                   for(k=0;k<2;k++){
                     sbr[cn][j][k]=sb[j][k];
                   }
                 }
                 cn++;
               }
             }
は行われず、
          for(i=1;i<5;i++){
             sb[sy[g]][sx[g]]=i;
の2巡目となり、

  0  1 
  0  1 

となりますが、
             if(g>0){
               for(j=0;j<g;j++){
                 if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
               }
             }

の2巡目でチェックされ、
          for(
i=1;i<5;i++){
             sb[sy[g]][sx[g]]=
i;
の3巡目となり、

  0  1 
  0  1 

でようやく検査
             if(g>0){
               for(j=0;j<g;j++){
                 if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
               }
             }

をクリアして、
             if(h==1){
               if(g+1<4){
                 sbs(g+1);
               }

が実行され、最後の次元世界
へと跳躍します。

  0  1 
  0  1 

          for(i=1;i<5;i++){
             sb[sy[g]][sx[g]]=
i;
によって、

  0  1 
  0  1 


  0  1 
  0  1 


  0  1 
  0  1 


  0  1 
  0  1 

と動いていって、はじめて試験
             if(g>0){
               for(j=0;j<g;j++){
                 if(sb[sy[g]][sx[g]]==sb[sy[j]][sx[j]])h=0;
               }
             }

突破しますが、
g = 3であるため
             if(h==1){
               if(g+1<4){
                 sbs(g+1);
               }
               
else{
                 for(j=0;j<2;j++){
                   for(k=0;k<2;k++){
                     sbr[cn][j][k]=sb[j][k];
                   }
                 }
                 cn++;
               }

             }
の否定側がはじめて遂行され、細胞の1個目がchar sbr[24][2][2];に登録され、
カウンタもcn++;により、1となります。






第4話へ
第6話へ

戻る

VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座