第17講 関数の再帰的呼び出しによる3次・4次魔方陣ソフトの改良 
第5話 偶数版枠番号付けの解説その3
いよいよ偶数版の最後
            else if(i<(m+1)*n){
              x[i]=(i-2*n)%(n-2);
              y[i]=(i-2*n)/(n-2);
              if(x[i]>=y[i])x[i]++;
              if(x[i]>=n-y[i]-1)x[i]++;
            }
            else{
              x[i]=(i-2*n)%(n-2);
              y[i]=(i-2*n)/(n-2);
              if(x[i]>=n-y[i]-1)x[i]++;
              if(x[i]>=y[i])x[i]++;
            }
のピンクの部分の解説です。
i<(m+1)*nではないわけですからでi≧(m+1)*nで(2+1)×4=12の計算から
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 13 | 2 | □ | 
| 3 | 14 | 15 | 00 | □ | 
該当するiは 
| 12 | 13 | 
| 14 | 15 | 
の部分です。
i=12のとき、
| 12 | 
は
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
 
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
のいずれのラインもまたぎませんから
              if(x[i]>=n-y[i]-1)x[i]++;
              if(x[i]>=y[i])x[i]++;
は両方とも実行されず
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 13 | 2 | □ | 
| 3 | 14 | 15 | 00 | □ | 
のまま変わりません。
i=13のとき、
| 13 | 
は
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
のラインにかかり、
if(x[i]>=n-y[i]-1)x[i]++;が実行され、
| 13 | 
はひとつずれて
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | □ | 13 | □ | 
| 3 | 14 | 15 | 00 | □ | 
となります。
すると、
| 13 | 
は
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
のラインに掛かり、再び1つずれて
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | □ | □ | 13 | 
| 3 | 14 | 15 | 00 | □ | 
となります。
| 14 | 15 | 
に関しては
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
のラインに掛かるかまたぎますが、
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
は掛かりもまたぎもしませんから、1つだけずれて
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | □ | □ | 13 | 
| 3 | □ | 14 | 15 | □ | 
となります。
最初にできていた0から7までを加えると、
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
となって思惑通りの番号付けができています。
ポイントは2つのライン
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
 
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
をに掛かるかまたはまたぐということなのです。掛かるかまたぐとき、1つずれるのです。
            else if(i<(m+1)*n){
              x[i]=(i-2*n)%(n-2);
              y[i]=(i-2*n)/(n-2);
              if(x[i]>=y[i])x[i]++;
              if(x[i]>=n-y[i]-1)x[i]++;
            }
            else{
              x[i]=(i-2*n)%(n-2);
              y[i]=(i-2*n)/(n-2);
              if(x[i]>=n-y[i]-1)x[i]++;
              if(x[i]>=y[i])x[i]++;
            }  
の前半と後半ではif(x[i]>=y[i])x[i]++;とif(x[i]>=n-y[i]-1)x[i]++;の順が逆になっている点も注意して下さい。
| 0 | 1 | |
| 0 | 8 | 9 | 
| 1 | 10 | 11 | 
| 2 | 12 | 13 | 
| 3 | 14 | 15 | 
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
 
と
| 0 | 1 | |
| 0 | 8 | 9 | 
| 1 | 10 | 11 | 
| 2 | 12 | 13 | 
| 3 | 14 | 15 | 
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
 
| 0 | 1 | 2 | 3 | |
| 0 | 0 | 8 | 9 | 4 | 
| 1 | 10 | 1 | 5 | 11 | 
| 2 | 12 | 6 | 2 | 13 | 
| 3 | 7 | 14 | 15 | 3 | 
の両方をご覧になって、どうして逆順なっているかよく考えてみて下さい。
そして、掛かるかまたぐかをすると1とずれて意図通りに動いていくことを確認して頂ければと思います。
第11講第6話へ 第12講第1話へ  第17講第4話へ 第17講第6話へ

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