2006 年 5 月 5 日 23 時 57 分

プログラムから見た問題


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


[写真]


プログラムでパズルを解くためには、
解答欄のサイズだけでなく、ヒントを得る必要がある。
Excel のシートの表記では、人間には便利だが、
プログラム的にはちょっと扱いにくい。

プログラムでは、ヒント数値が配列になっている方が良い。
また、ヒントもいちいちワークシートを探索すると大変だ。
専用のクラスを作って格納しておくほうがいいだろう。

ということで、問題を読み込むためのクラスを設計する。
まずは、ののぐらむの持つ要素を考えてみよう。

・問題の幅
・問題の高さ
・各行のヒント配列
・各列のヒント配列
・解答欄の状態の二次元配列

これくらいだろうか。最後の「解答欄の状態」は、
途中から自動解答に切り替える時などを想定している。
既に幾つかの升目が確定している状態から始まる場合、
現在の解答欄の状態を読み込む必要があるからである。

では、上記をインタフェースとして定義してみよう。
読み込み専用のクラスなので、ローダ = Loader だ。
ではインタフェース名は、IPuzzleLoader としよう。

問題の幅や高さは整数のプロパティとして表現できる。

Property Get Width() As Long
Property Get Height() As Long

ヒント配列は少し難しい。行や列自体が配列であり、
さらにそれらにヒントの数値が配列となる。

オブジェクト指向の設計で行くと、
ヒント配列をオブジェクトとし、
さらにその配列も行コレクションオブジェクトとし、
それを返却するプロパティが最適と考えられる。

Property Get RowHints() As RowHintsCollection

しかしながら、オブジェクト階層が深くなってしまうし、
今回は VBA なので少し手抜きをして、
インデックス付きプロパティとしよう。

Property Get RowHints(ByVal Index As Long) As ArrayList

ヒント配列はただの整数の配列なので、
Long 配列を返す手もあるのだが、
VBA の配列は値型なので、戻り値として利用すると、
コピーが発生するのでよろしくない。
そこで、可変配列の参照型ラッパである、
ArrayList クラスを自作し、それを返却するようにしよう。

解答欄の状態配列も同じように返そう。
ArrayList の ArrayList を使うことにする。
いわゆるジャグ配列ってやつだ。

Property Get Answer() As ArrayList

よし、では実装してみよう。

実は、VBA には「本当」のインタフェースはない。
特殊な方法を使えば定義することはできるが、
外部の手段に頼る必要がある。
そこで今回は、クラスモジュールを使って定義する。

挿入⇒クラスモジュールを選択し、
プロジェクトにクラスモジュールを追加する。
名前は、「IPuzzleLoader」とする。

このクラスはインタフェース的に使用するので、
名前の先頭には I を追加して定義し、
クラスには一切実装を記述しない。

それでもクラスであることは変わりないので、
インスタンスを作成することができてしまう。
万全を期するために、クラスの初期化コードで
強制的にエラーを発生させる方法はあるが、
今回はそこまでしないことにしよう。

========== クラスモジュール: IPuzzleLoader ==========

Option Explicit

'##################################################
'# 問題を読み込むインタフェース
'##################################################

' セルの状態
Public Enum CellStateConstants
    CELL_UNSOLVED = -1      ' 未解答のセル
    CELL_CHECKED = 0        ' ×チェックのセル
    CELL_FILLED = 1        ' 塗りつぶされたセル
End Enum

' 解答欄の幅を取得する
Public Property Get Width() As Long
End Property

' 解答欄の高さを取得する
Public Property Get Height() As Long
End Property

' 行ヒントを取得する
Public Property Get RowHints(ByVal Index As Long) As ArrayList
End Property

' 列ヒントを取得する
Public Property Get ColumnHints(ByVal Index As Long) As ArrayList
End Property

' 解答欄の状態を取得する
Public Property Get Answer() As PuzzleAnswer
End Property

========== end of IPuzzleLoader ==========



Copyright (c) 1994-2007 Project Loafer. All rights reserved.