第6講 数独作成アプリVer.1にライン排除確定を組み込む
第8話 数独作成アプリVer.2一歩前バージョン
コードの変更部分のみを掲載
・
Dim rh(80) As Byte
Private Sub CommandButton1_Click()
・
Sub sds(g As Byte, mok As Byte) '数独作成プロシージャ
If mok = 0 Then If cn = 1 Then Exit Sub
・
If u = 1 Then '局所リスト解析プロシージャ
If g + 1 < n2 Then
Call nck(g + 1, mok)
Call sds(g + 1, mok)
If rh(g + 1) = 1 Then
mx(y(g + 1), x(g + 1)) = cmx(g + 1, y(g + 1), x(g + 1))
For j = 0 To n_1
rlst(y(g + 1), x(g + 1), j) = crlst(g + 1, y(g + 1), x(g + 1), j)
Next
For j = 0 To n_1
kh(y(g + 1), x(g + 1), j) = ckh(g + 1, y(g + 1), x(g + 1), j)
Next
End If
・
End Sub
Sub rhk(g As Byte) 'ライン排除確定解析プロシージャ
Dim i As Byte, j As Byte, k As Byte, l As Byte, w As Byte 'wは行・列・ブロックにおける白の個数を数えるカウンタ
Dim ys As Byte 'y座標を記録する変数
Dim xs As Byte 'x座標を記録する変数
rh(g) = 0
'以下各数字に対応する行におけるライン排除確定があるかを調べるための手順
For i = 0 To n_1 'i + 1 は入力する数字を示す。
For j = 0 To n_1 'jはy座標(縦座標)
'以下行における白のセルのカウント
w = 0
For k = 0 To n_1 'kはx座標(横座標)
If p(j, k) = 0 Then
If kh(j, k, i) = 1 Then
xs = k
w = w + 1
End If
End If
Next
If w = 1 Then
For k = 0 To mx(j, xs)
If rlst(j, xs, k) = i + 1 Then
y(g) = j
x(g) = xs
cmx(g, y(g), x(g)) = mx(y(g), x(g))
For l = 0 To n_1
crlst(g, y(g), x(g), l) = rlst(y(g), x(g), l)
Next
For l = 0 To n_1
ckh(g, y(g), x(g), l) = kh(y(g), x(g), l)
Next
rlst(y(g), x(g), k) = rlst(y(g), x(g), 0)
rlst(y(g), x(g), 0) = i + 1
mx(y(g), x(g)) = 0
rh(g) = 1
Exit Sub
End If
Next
End If
'以上行における白いセルのカウント
Next
Next
' 以下各数字に対応する列におけるライン排除確定があるかを調べるための手順
For i = 0 To n_1 'i + 1 は入力する数字を示す。
For j = 0 To n_1 'jはy座標(縦座標)
'以下行における白のセルのカウント
w = 0
For k = 0 To n_1 'kはx座標(横座標)
If p(k, j) = 0 Then
If kh(k, j, i) = 1 Then
ys = k
w = w + 1
End If
End If
Next
If w = 1 Then
For k = 0 To mx(ys, j)
If rlst(ys, j, k) = i + 1 Then
y(g) = ys
x(g) = j
cmx(g, y(g), x(g)) = mx(y(g), x(g))
For l = 0 To n_1
crlst(g, y(g), x(g), l) = rlst(y(g), x(g), l)
Next
For l = 0 To n_1
ckh(g, y(g), x(g), l) = kh(y(g), x(g), l)
Next
rlst(y(g), x(g), k) = rlst(y(g), x(g), 0)
rlst(y(g), x(g), 0) = i + 1
mx(y(g), x(g)) = 0
rh(g) = 1
Exit Sub
End If
Next
End If
'以上行における白いセルのカウント
Next
Next
'以下各数字に対応するブロックにおけるライン排除確定があるかを調べるための手順
Dim ybs As Byte, xbs As Byte
Dim ks As Byte, ka As Byte
For i = 0 To n_1 'i + 1 は入力する数字を示す。
For j = 0 To n_1 'jはy座標(縦座標)
ybs = rn * Int(j / rn)
xbs = rn * (j Mod rn)
'以下行における白のセルのカウント
w = 0
For k = 0 To n_1 'kはx座標(横座標)
ks = Int(k / rn)
ka = k Mod rn
If p(ybs + ks, xbs + ka) = 0 Then
If kh(ybs + ks, xbs + ka, i) = 1 Then
ys = ybs + ks
xs = xbs + ka
w = w + 1
End If
End If
Next
If w = 1 Then
For k = 0 To mx(ys, xs)
If rlst(ys, xs, k) = i + 1 Then
y(g) = ys
x(g) = xs
cmx(g, y(g), x(g)) = mx(y(g), x(g))
For l = 0 To n_1
crlst(g, y(g), x(g), l) = rlst(y(g), x(g), l)
Next
For l = 0 To n_1
ckh(g, y(g), x(g), l) = kh(y(g), x(g), l)
Next
rlst(y(g), x(g), k) = rlst(y(g), x(g), 0)
rlst(y(g), x(g), 0) = i + 1
mx(y(g), x(g)) = 0
rh(g) = 1
Exit Sub
End If
Next
End If
'以上行における白いセルのカウント
Next
Next
End Sub
Sub nck(g As Byte, mok As Byte)
Dim i As Byte, j As Byte, mn As Byte, ik As Byte, jk As Byte
mn = 100
For i = 0 To n_1
For j = 0 To n_1
If p(i, j) = 0 Then
If mn > mx(i, j) Then
mn = mx(i, j)
ik = i
jk = j
If mn = 0 Then
y(g) = ik
x(g) = jk
Exit Sub
End If
End If
End If
Next
Next
y(g) = ik
x(g) = jk
If mok = 1 Then
rhk (g)
End If
End Sub
・
数独作成アプリVer.2一歩前バージョン
Ver.2によって1200題を作成するソフト
と前話の1200題適正検証ソフト
によってすべて○になることを確認して下さい。
30題に1題の割合で、
別解のある問題を作ってしまうという不具合の問題の解消に丸2日もかかってしまいました。
基本的には、復元プロシージャhukubenと同様に、
変更したセルの場所を時間を含む配列hth(g, i, j)に記録して、
変更したセルを元に戻すという方式で、
いいはずなのですが、
どうしてもこの配列を使う方法では成功しませんでした。
で、結局
Dim rh(80) As Byte
を導入して、不具合を解消できました。
第6話でも述べましたように、
今の方式は、
今回1つでも確定できるセルが見つかった段階で、
強制的にライン排除確定解析プロシージャSub rhk(g As Byte) を抜けるようになっていますので、
変更される場所は1カ所のみですから、
3次元配列にする必要はないというのはわかりますが、
hth(g, i, j)を使ってはいけないということはないと思いますで、
If hth(g + 1, y(g + 1), x(g + 1)) = 1 Then
mx(y(g + 1), x(g + 1)) = cmx(g + 1, y(g + 1), x(g + 1))
For j = 0 To n_1
rlst(y(g + 1), x(g + 1), j) = crlst(g + 1, y(g + 1), x(g + 1), j)
Next
For j = 0 To n_1
kh(y(g + 1), x(g + 1), j) = ckh(g + 1, y(g + 1), x(g + 1), j)
Next
End If
で何が問題なのかは、今も分かりません。
さて、第6講最後の課題です。
今回、ライン排除確定を組み込みましたが、
最後に破綻処理を入れて
数独作成アプリVer.2の完成としましょう。
オレンジのセルに2を入れると、
ライン排除確定によって、
青のセルが2に確定しますが、
この確定によって破綻しています。
何故かというと、
確定によって新たな排除が発生して、
黄色の囲いのブロックに2を入れる場所がなくなってしまいます。
数独作成アプリVer.2一歩前バージョン
はライン排除確定のみを組み込んだだけで、
ライン排除確定による排除を組み込んでいませんので、
破綻判定が出来ずに、
無駄に試行錯誤が繰り返される可能性があります。
そこで、ライン排除確定による排除を組み込みこむことによって、
オレンジのセルに2を入れると破綻することをプログラムに教えてやって下さい。
Sub rhkとSub nckはFunctionプロシージャに変更する必要があると思います。
eclipse c++ 入門
魔方陣 数独(ナンプレ)で学ぶ VBA 入門
数独(ナンプレ)のシンプルな解き方・簡単な解法の研究
vc++講義へ
excel 2013 2010 2007 vba入門へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
専門用語なしの C言語 C++ 入門(Visual C++ 2010で学ぶ C言語 C++ 入門)
専門用語なしの excel vba マクロ 入門 2013 2010 2007 対応講義 第1部
eclipse java 入門へ
excel 2016 vba 入門へ
小学生からエンジニアまでのRuby入門へ
本サイトトップへ