第6講 数独を作ろう!
第6話 数独プログラム改良

数独プログラム改良例

改良したのはhyouji()の部分です。
では改良前のプログラムソースと
改良後のプログラムソースを掲載してみましょう。

改良前
a = (cn - 1) Mod 10
s = Int((cn - 1) / 10)
For i = 0 To n * n - 1
  For j = 0 To n * n - 1
    Cells(i + 7 + (n * n + 1) * s, j + 1 + (n * n + 1) * a) = mah(i, j)
  Next
Next

改良後
a = (cn - 1) Mod 10
s = Int((cn - 1) / 10)
For i = 0 To n * n - 1
  For j = 0 To n * n - 1
    ii = Int(i / n)
    js = Int(j / n)

    Cells(i + 7 + ii + (n * n + n) * s, j + 1 + js + (n * n + n) * a) = mah(i, j)

    If ii > 0 Then
      Cells(6 + (n + 1) * ii + (n * n + n) * s, j + 1 + js + (n * n + n) * a) = "*"
    End If
    If js > 0 Then
      Cells(i + 7 + ii + (n * n + n) * s, (n + 1) * js + (n * n + n) * a) = "*"
    End If
    If ii < n - 1 And js < n - 1 Then
      Cells(6 + (n + 1) * (ii + 1) + (n * n + n) * s, (n + 1) * (js + 1) + (n * n + n) * a) = "*"
    End If

  Next
Next

ピンクに変更されています。
変更点を順に解説していきましょう。
ii = Int(i / n)  js = Int(j / n)
はそれぞれiをnで割った商(isとしたいところですがこれはイズとなりVisualBasicからチェックされ不可とされてしまいます。)、
jをnで割った商を表しています。n=3の場合、つまり9(3の2乗)次数列の場合で以降話を進めます。

 0  1  2  3  4  5  6  7  8  9 10
 0 1 2 3 * 4 5 6 * 7 8 9
 1 4 5 6 * 7 8 9 * 1 2 3
 2 7 8 9 * 1 2 3 * 4 5 6
 3 * * * * * * * * * * *
 4 2 1 4 * 3 6 5 * 8 9 7
 5 3 6 5 * 8 9 7 * 2 1 4
 6 8 9 7 * 2 1 4 * 3 6 5
 7 * * * * * * * * * * *
 8 5 3 1 * 6 4 2 * 9 7 8
 9 6 4 2 * 9 7 8 * 5 3 1
10 9 7 8 * 5 3 1 * 6 4 2

いくつかの場合を見て動きを追ってみましょう。
@0≦i≦2,0≦j≦2すなわち水色の場合
 ii=0,js=0となります。
 このときはCells(i + 7 + ii + (n * n + n) * s, j + 1 + js + (n * n + n) * a)= mah(i, j)
  Cells(i + 7 + (n * n + 1) * s, j + 1 + (n * n + 1) * a) = mah(i, j)と同じになります。
 つまり水色を順に埋めていきます。
Ai=3かつi≠jの場合
 i=3,ii=1となりCells(6 + (n + 1) * ii + (n * n + n) * s, j + 1 + js + (n * n + n) * a) = "*"
 Cells(6 + (n + 1) * 1+ (n * n + n) * s, j + 1 + js + (n * n + n) * a) = "*"
 となり紺色を順に埋めていきます。尚オレンジはjsの存在のため飛ばされてしまいます。
 例えばj=2のとき、js=0でj + 1 + jsは2であるのに対して
 j=3ではjs=1となりj + 1 + jsは4となり、オレンジのところが飛ばされてしまうのが分かると思います。
Bj=7かつi≠jの場合
 j=7,js=2となりCells(i + 7 + ii + (n * n + n) * s, (n + 1) * js + (n * n + n) * a) = "*"
 Cells(i + 7 + ii + (n * n + n) * s, (n + 1) * 2 + (n * n + n) * a) = "*"
 となり(n + 1) * 2は8でこれはj=7場合になります。j + 1でjとは1つずれていますので)を順に埋めていきます。
 A尚オレンジは2の場合と同様にiiの存在のため飛ばされてしまいます。
 例えばi=2のとき、ii=0ではi + 7 + iiは9(i番号に相当、i + 7によってi番号と7ずれているため)であるのに対して
 i=3ではii=1となりi + 7 + iiは11(i番号に相当)となり、オレンジのところが飛ばされてしまうのが分かると思います。
C6≦i≦8,3≦j≦5の場合
 ii=2,js=1となります。
 このときはCells(i + 7 + ii + (n * n + n) * s, j + 1 + js + (n * n + n) * a)= mah(i, j)
  Cells(i + 7 + 2 + (n * n + n) * s, j + 1 + 1 + (n * n + n) * a)= mah(i, j)となり
 これは薄ピンクを順に埋めていきます。
Di=j=2またはi=2,j=6またはi=6,j=2またはi=j=6のとき
 i=j=2ならii=0,js=0で
 Cells(6 + (n + 1) * (ii + 1) + (n * n + n) * s, (n + 1) * (js + 1) + (n * n + n) * a) = "*"
 
Cells(6 + 4 + (n * n + n) * s, 4 + (n * n + n) * a) = "*"
 
となりこれは()の場合でそこに*が入ります。
読者の方は、@からDの場合のi,jを例示されている以外も動かしトレースしましょう。
また、@からD以外の場合を考えて、表のようにうまく表示されることを確認しましょう。

さて、それでは読者の皆さん、数独プログラム改良例をさらに改良して
答えがもっと数独らしくなるようにランダム要素を入れてみましょう。

第5話へ 
第7話へ


VB入門講義応用編トップへ

VB入門講義トップへ