第4講 数独を解くソフトの開発(1)
第2話 セルのデータをm(i, j)に入力する
を実現するプログラム例
Dim n As Byte, m(8, 8) As Byte, cn As Integer, hnt As Byte 'nは数独の一辺、x(15)は数独を収納する配列、cnは数独総数をカウント、hntはヒント数
Private Sub CommandButton1_Click()
CommandButton2_Click
n = 9
cn = 0
Randomize (Timer) 'シード値を時間から取得
dainyu 'シートのB4からJ12のセルからm(i, j)に代入することが任務
' f (0) '数独解答作成プロシージ
hyouji
End Sub
Sub dainyu() 'シートのB4からJ12のセルからm(i, j)に代入することが任務
Dim i As Byte, j As Byte
hnt = 0
For i = 0 To n - 1
For j = 0 To n - 1
If Cells(4 + i, 2 + j) > 0 Then 'シートが空欄""でないときにシートの値を代入
m(i, j) = Cells(4 + i, 2 + j)
hnt = hnt + 1 'ヒント数をカウント
End If
If Cells(4 + i, 2 + j) = "" Then 'シートが空欄""であるときに0を代入
m(i, j) = 0
End If
Next
Next
End Sub
Sub hyouji()
Dim i As Byte, j As Byte
For i = 0 To n - 1
For j = 0 To n - 1
Cells(14 + i, 2 + j) = m(i, j)
Next
Next
Cells(8, 12) = "ヒント数は"
Cells(9, 12) = hnt
Cells(10, 12) = "です。"
End Sub
Sub f(g As Byte)
Dim i As Byte, j As Byte, h As Byte, w As Byte
Dim y As Byte, x As Byte, yy As Byte, xx As Byte, ii As Byte, iii As Byte
y = Int(g / n)
x = g Mod n
ii = Int(n * Rnd)
For i = 0 To n - 1
iii = (i + ii) Mod n '1から9までの数字を代入
m(y, x) = iii + 1
h = 1
If x > 0 Then '行の重複を検査して、重複がある場合にはhを0として以下の処理をさせない。
For j = 0 To x - 1
If m(y, x) = m(y, j) Then
h = 0
Exit For
End If
Next
End If
If h = 1 And y > 0 Then '列の重複を検査して、重複がある場合にはhを0として以下の処理をさせない。
For j = 0 To y - 1
If m(y, x) = m(j, x) Then
h = 0
Exit For
End If
Next
End If
If h = 1 And y > 0 Then 'ブロックの重複を検査して、重複がある場合にはhを0として以下の処理をさせない。
For j = 0 To n - 1
xx = 3 * Int(x / 3) + (j Mod 3)
yy = 3 * Int(y / 3) + Int(j / 3)
If x = xx And y = yy Then Exit For
If x <> xx And y <> yy Then
If m(yy, xx) = m(y, x) Then
h = 0
Exit For
End If
End If
Next
End If
If h = 1 Then
If g + 1 < n * n Then '行の重複がなく、g + 1がn * n以下のときに、次のセル番号の世界に飛ぶ
f (g + 1)
If cn = 10 Then Exit Sub '数独が10個生成した段階で探索をやめさせている。
Else
cn = cn + 1 '数独総数カウント
If cn = 10 Then Exit Sub '数独が10個生成した段階で探索をやめさせている。
End If
End If
Next
End Sub
Private Sub CommandButton2_Click()
Rows("14:30000").Select
Selection.ClearContents
Cells(1, 1).Select
End Sub
参考ダウンロード添付ファイル
次話の課題です。
問題の数字は*で表示して、
それ以外は入力順が表示されるように、
改良してください。
具体的にいじる場所は
dainyuとhyoujiです。
「入力順を確定する=問題にあるデータ(*印のデータ)をいじらない」ために、
グローバル変数
Dim iz(80) As Byte, jz(80) As Byte
を用意してください。
この入力順で入れていくと最後は
If g + 1 < n * n Then
ではなく、
If g + 1 < n * n - hnt Then
となります。