第24講 数独解答作成の作成
第4話 ブロック重複判定部分解説
では、お約束の通りブロック重複判定部分のプログラム
if(h==1){
xs=x[g]/3;
ys=y[g]/3;
for(j=0;j<=y[g]-3*ys;j++){
for(k=0;k<3;k++){
if(j==y[g])if(k==x[g])break;
if((y[g]!=3*ys+j) && (x[g]!=3*xs+k)){
if(a[y[g]][x[g]]==a[3*ys+j][3*xs+k]){
h=0;
break;
}
}
}
if(h==0)break;
}
}
を解説しましょう。
まず、xsとysの役割は何でしょうか。
** | 0 | 1 | 2 | ||||||
0 | ** | ** | ** | ** | ** | ** | ** | ** | ** |
** | ** | ** | ** | ** | ** | ** | ** | ** | |
** | ** | ** | ** | ** | ** | ** | ** | ** | |
1 | ** | ** | ** | ** | ** | ** | ** | ** | ** |
** | ** | ** | ** | ** | ** | ** | ** | ** | |
** | ** | ** | ** | ** | ** | ** | ** | ** | |
2 | ** | ** | ** | ** | ** | ** | ** | ** | ** |
** | ** | ** | ** | ** | ** | ** | ** | ** | |
** | ** | ** | ** | ** | ** | ** | ** | ** |
xsとysはそれぞれ左の表の
紺と赤に対応しています。
すなわち、ブロックの横位置と縦位置
を示す番号なのです。
とすると、次のfor文の条件
(j=0;j<=y[g]-3*ys;j++)
は何でしょうか。
y[g]-3*ysを理解することが枢要になります。
これはブロックの中の縦番号の終わりの番号です。
2 | ||||
0 | 1 | 2 | ||
1 | 0 | ** | ** | ** |
1 | ** | ** | ** | |
2 | ** | ** | ** |
ですから、jはピンクの番号に相当します。
そして、次のfor文のkは左の薄緑番号に対応しています。
縦番号の終わりの位置とは何でしょうか。
g=43のときは、左の薄茶セルの位置にいることは、
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
2 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
3 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
4 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
5 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
6 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
7 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
8 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 |
g番号とx座標・y座標との関連を示す
左の表をご覧になればおわかりですね。
この場合には終わりの縦番号とは
2 | ||||
0 | 1 | 2 | ||
1 | 0 | ** | ** | ** |
1 | ** | ** | ** | |
2 | ** | ** | ** |
1です。
** |
以降のセルはまだ空白ですから、
** |
と**のセルを比較すればよいのです。
2 | ||||
0 | 1 | 2 | ||
1 | 0 | ** | ** | ** |
1 | ** | ** | ** | |
2 | ** | ** | ** |
すると、
if(j==y[g])if(k==x[g])break;
の意味も掴めるのではないでしょうか。
これはj==y[g]かつk==x[g]のとき、
for文を終了しなさいという命令ですから、
** |
まで来たら、for文を終わりにしなさいという意味になります。
**のセルとの比較のみでいいのですから。
if(a[y[g]][x[g]]==a[3*ys+j][3*xs+k])のa[y[g]][x[g]]==a[3*ys+j][3*xs+k]が現在のセル
とそのセルが属しているブロック内のセル
** | ** | ** |
** |
との比較になっていることがおわかりでしょうか。
このプログラムの肝要な点は、
ブロック番号xs、ysを用意して、さらに3*ys+jと3*xs+kを考えることによって、ブロック内のセルとのみ比較させていることです。
今の例ではxs=2、ys=1ですから、
j=0、k=0なら3*ys+j=3、3*xs+k=6で
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
2 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
3 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
4 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
5 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
6 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
7 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
8 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 |
33 |
と比較しています。
つまり同一ブロック内のセルと比較しています。
j=0、k=1ならその隣のセル34ですね。
その他もご自分でトレースされて必ず同一ブロック内のセルで
現在位置より手前のセルと比較していることを
確認して下さい。
さて、課題を出してこの話を閉めましょう。
今回は9次数独を作りましたが、数独には16次数独もあります。
(数独改良版を参照して下さい。)
この16次数独に挑戦しましょう。
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual
Basic入門基礎講座