第15講 3次魔方陣と4次魔方陣の作成

第5話 3次魔方陣と4次魔方陣の自動生成コード解説その2

コード再掲
Dim mah(4, 4) As Byte, x(16) As Byte, y(16) As Byte
Dim n As Byte, cn As Integer
Private Sub CommandButton1_Click()

  n = Cells(3, 8)
  cn = 0
  zhy
  ms (0)
  Cells(4, 12) = cn

End Sub


Sub zhy()

  Dim i As Byte
  For i = 0 To n * n - 1
    x(i) = i Mod n
    y(i) = Int(i / n)
  Next

End Sub


Sub ms(g As Byte)

  Dim i As Byte, j As Byte, k As Byte, a As Byte, b As Byte, w As Byte
  a = x(g)
  b = y(g)

  For i = 0 To n * n - 1
    mah(b, a) = i + 1
    If g > 0 Then
      For j = 0 To g - 1
        If mah(b, a) = mah(y(j), x(j)) Then GoTo tobi
      Next
    End If
    If a = n - 1 Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(b, j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If b = n - 1 Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(j, a)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If (a = n - 1) And (b = n - 1) Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(j, j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If (a = 0) And (b = n - 1) Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(j, n - 1 - j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If g + 1 < n * n Then
      ms (g + 1)
    Else
      For j = 0 To n - 1
        For k = 0 To n - 1
          Cells(6 + j + Int(cn / 10) * (n + 1), 1 + k + (cn Mod 10) * (n + 1)) = mah(j, k)
        Next
      Next
      cn = cn + 1
    End If
tobi:
  Next

End Sub

解説

ではコードを上から順に見ていきましょう。
Dim mah(4, 4) As Byte, x(16) As Byte, y(16) As Byte
Dim n As Byte, cn As Integer
この2行はグローバル変数とグローバル配列を宣言しています。
引数で渡すようにすれば、グローバルにする必要はありませんが、
コードを単純にするためにグローバル配列とグローバル変数を選んでいます。
Private Sub CommandButton1_Click()

  n = Cells(3, 8)
  cn = 0
  zhy
  ms (0)
  Cells(4, 12) = cn

End Sub
ここでは、
n = Cells(3, 8)でシートのL4入門からnの値をもらっています。
今の時点では、nは3または4です。5を入れてしまうと、処理にかなり時間がかかってしまいます。
cn = 0は魔方陣総数カウンタの初期化です。
次のzhyでは、座標の作成を行っています。
Sub zhy()

  Dim i As Byte
  For i = 0 To n * n - 1
    x(i) = i Mod n
    y(i) = Int(i / n)
  Next

End Sub
一度すでに解説を行っていますが、再度n=3でトレースをしてみましょう。
n*n−1は3×3−1=8ですから、iは0から8まで変化します。
i=0とき、
    x(
)= Mod n = Mod 3=
    y(
)= Int( /n)=Int(/3)=
i=1とき、
    x()= Mod n = Mod 3=
    y()= Int( /n)=Int(/3)=
i=2とき、
    x()= Mod n = Mod 3=
    y()= Int( /n)=Int(/3)=
i=3とき、
    x()= Mod n = Mod 3=
    y()= Int( /n)=Int(/3)=
i=4とき、
    x()= Mod n = Mod 3=
    y()= Int( /n)=Int(/3)=
i=5とき、
    x()= Mod n = Mod 3=
    y()= Int( /n)=Int(/3)=
i=6とき、
    x()= Mod n = Mod 3=
    y()= Int( /n)=Int(/3)=
i=7とき、
    x()= Mod n = Mod 3=
    y()= Int( /n)=Int(/3)=
i=8
とき、
    x(
)= Mod n = Mod 3=
    y(
)= Int( /n)=Int(/3)=

   0
0 0 1 2
1 3 4 5
2 6 7 8

と見事に座標が割り振られました。皆さんは、n=4の場合でもトレースをしてみましょう。



第4話へ 第6話へ

004
  


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

数学研究室に戻る