第22講 数独=ナンプレの自動生成
第4話 ブロック境界線を入れる
vb
解答例
Dim m(9, 9), cn As Integer
Private Sub CommandButton1_Click()
  cn = 0
  f (0)
End Sub
Sub f(g As Integer)
  Dim x As Byte, y As Byte
  y = Int(g / 9)
  x = g Mod 9
  Dim i, j, k, zy, zx As Byte
  Dim cna As Integer, cns As Integer
  For i = 1 To 9
    m(x, y) = i
    
    If x > 0 Then
      For j = 0 To x - 1
        If m(x, y) = m(j, y) Then GoTo tobi
      Next
    End If
    If y > 0 Then
      For j = 0 To y - 1
        If m(x, y) = m(x, j) Then GoTo tobi
      Next
    End If
    If g + 1 < 81 Then
      f (g + 1)
    Else
      cna = cn Mod 9
      cns = Int(cn / 9)
      z = 0
      For j = 0 To 9
        If j Mod 3 = 0 Then
          For k = 0 To 12
            Cells(7 + 14 * cns + j + zy, 1 + 14 * cna + k) = "*"
          Next
          zy = zy + 1
        End If
        If j < 9 Then
          zx = 0
          For k = 0 To 9
            If k Mod 3 = 0 Then
              Cells(7 + 14 * cns + j + zy, 1 + 14 * cna + k + zx) = "*"
              zx = zx + 1
            End If
            If k < 9 Then Cells(7 + 14 * cns + j + zy, 1 + 14 * cna + k + zx) = m(j, k)
          Next
        End If
      Next
      cn = cn + 1
    End If
tobi:
  Next
End Sub
Private Sub CommandButton2_Click()
  Cells.Select
  Selection.ClearContents
  Cells(1, 1).Select
End Sub

解説
どうです。結構頭が混乱しましたよね。
私も大分苦戦しました。
試行錯誤を粘り強く繰り返すしかありません。
      For j = 0 To 9
        If j Mod 3 = 0 Then
まず、これの意味を説明しましょう。
jを3で割ったときの余りが0になるのは、
jが0,3,6,9のときです。
そして、このときに
          For k = 0 To 12
            Cells(7 + 14 * cns + j + zy, 1 + 14 * cna + k) = "*"
          Next
の命令を遂行します。
これは横線****です。では
          zy = zy + 1
はなんでしょうか。****の線を入れる度に、数字を入れる行がずれていきます。
zyは入っている横線****の数を数えているのです。
        If j < 9 Then
          zx = 0
          For k = 0 To 9
            If k Mod 3 = 0 Then
              Cells(7 + 14 * cns + j + zy, 1 + 14 * cna + k + zx) = "*"
              zx = zx + 1
            End If
            If k < 9 Then Cells(7 + 14 * cns + j + zy, 1 + 14 * cna + k + zx) = m(j, k)
          Next
        End If
このピンクなぜ入れてあるのでしょうか。入れないとエラーするからです。
Dim m(9, 9), cn As Integerですから、添え字は、8までしか有効ではありません。
ですからjが9未満のときのみ中の処理を実行するようになっているのです。
            If k Mod 3 = 0 Then
              Cells(7 + 14 * cns + j + zy, 1 + 14 * cna + k + zx) = "*"
              zx = zx + 1
            End If
            If k < 9 Then Cells(7 + 14 * cns + j + zy, 1 + 14 * cna + k + zx) = m(j, k)
以上の説明から、この部分が何をしているかはお分かりになるのではないでしょうか。
そうです。縦線
*
*
*
*
を入れています。
kが0,3,6,9のときに、*を挿入しています。
If k < 9 Then Cells(7 + 14 * cns + j + zy, 1 + 14 * cna + k + zx) = m(j, k)についてはいうまでもありませんね。
横線のときと同じ理由です。

さて、最後の難問です。現在はブロックのチェックを行っていませんので、ブロック内に数字の重複が起きています。
これを解消してください。

参考ダウンロードファイル


第3話へ 第5話へ

004
  

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

数学研究室に戻る