最近の記事
- 9/1 - 将棋始めました
- 5/16 - サーバー引っ越し
- 4/24 - 優先順位
- 3/17 - vbNullString と 空文字列 ""
- 3/15 - InputBox 関数の戻り値
- 3/13 - 紙と Excel と VBA
- 3/9 - 未だに Visual Basic 6
- 11/14 - ぼて閉鎖
- 11/9 - 関数オブジェクトの呼び出し
- 9/7 - メソッドとしての関数オブジェクト
Entering Passive Mode
今日は PuzzleSolver のコンストラクタを作る。
行や列、解答を独立したオブジェクトとして管理するので、
PuzzleSolver はそれらを構築するだけだ。
コンストラクタを作る。今回も一般的なエラー処理は省く。
Public Sub Construct(ByVal Loader As IPuzzleLoader)
Dim x As Long
Dim y As Long
' 解答状況クラスを構築
Set m_oAnswer = New PuzzleAnswer
Call m_oAnswer.Construct(Loader)
設計が続く。今日は PuzzleAnswer だ。
解答を保持するクラスである。
PuzzleSolver や PuzzleLine から使われ、
解答状況は全てここに格納する。
PuzzleAnswer は解答欄であるため、
2 次元配列を模倣するのが好ましい。
メソッドやプロパティ。
・内部コンストラクタ
・セル値の取得・設定:(インデクサ)
・幅の取得: Width
・高さの取得: Height
さて、昨日の考察ででてきた、
ヒント値の配列のラッパを作成しよう。
列挙はできないが PuzzleHintCollection という名前にする。
不変クラスということで、値の設定はコンストラクタのみ。
コンストラクタで受け取るのは、ヒント値の配列だ。
IPuzzleLoader との親和性を考えて、
ArrayList で受け取る形にしよう。
後は参照系のプロパティが殆どという形となる。
例によって必要なプロパティを洗い出す。
本来の解法アルゴリズムを考えるには、まだまだ準備がいる。
しばらくは設計が続きそうだ。
PuzzleSolver はおいといて、PuzzleLine を考えよう。
PuzzleLine は、単独の行や列に限定したクラスである。
ののぐらむの基本は、1 つの行に着目して解いていくので、
解答を進める上で、行という単位で扱えると便利だ。
では、PuzzleLine に必要なメソッドを洗い出す。
・内部コンストラクタ
・行の範囲内で解答を求める: Solve()
VBA は COM の技術基盤を使用するので、
インスタンスの生存期間を、参照カウンタを使って管理する。
変数にインスタンスへの参照を格納した場合、
インスタンスが持つ参照カウンタを 1 つ増加させる。
スコープを外れる、または Nothing を代入すると、
インスタンスが持つ参照カウンタを 1 つ減少させる。
これらは内部的に行なわれている。
もし、クラスのフィールドとして、
別のクラスのインスタンスを格納した場合、
所有する側のフィールドが Nothing にならない限り
所有される側のインスタンスは解放されないことになる。
IPuzzleLoader によって問題をロードする準備ができた。
次はいよいよ、自動解答機能を実装する。
解答用のクラスには PuzzleSolver と名づけよう。
クラスのコンストラクタは、
IPuzzleLoader を引数に取り、問題を受け取る。
最低限必要なメソッド/プロパティは、以下の通り。
・自動解答を実行する: Solve()
・解答を取得する: Answer
さて、シートから問題を読めるようになったはずなので、
正常に読み出せているか、テストをしてみよう。
まず、当然ながら問題を用意する必要がある。
5/5 の日記に、適当に作った問題の画像を載せているので、
これを使ってテストをすることにする。
http://mixi.jp/view_diary.pl?id=129399396&owner_id=2300658
まずはこれをシートに入力しよう。
罫線は関係ないが、見やすくために入れておく。
そして、入力が終わったら、解答欄部分を選択して、
VBE の環境に戻って、テストコードを書く。
ヒントは列や行によって数が異なるため、
単純に特定範囲という風に決めることができない。
セルを順番に調べていく必要がある。
しかしながらルールがなければ読み込みはできないので、
まずはヒントのあり方についてルールを決めよう。
雑誌を見てみると、大体がこの法則に従っている。
●行のヒントについて
・各行の解答欄と同じ行の左側のセルに入力される
・行には必ず 1 つ以上のヒント数値がある。
・常に右寄せで入力され、
解答欄の左の隣接したセルには必ず数値が入る。
今日は、Excel の選択範囲を読み出す処理を行なう。
Excel のセル範囲は、Range というオブジェクトだ。
Range を制した者は Excel を制す(?)と言われるほど、
複雑怪奇で魑魅魍魎の多機能オブジェクトだ。
セルにアクセスするためにはこれを使い倒す必要がある。
では、PuzzleSheetLoader の実装をはじめよう。
まず、偽コンストラクタ周辺。
コンストラクタではあまり処理をしないようにしよう。
IPuzzleLoader のインタフェースは作成したので、
それを実装したクラスを作成しよう。
まず必要となるのは、セル範囲から問題を読み出すクラスだ。
PuzzleSheetLoader とでも名前をつけよう。
このクラスには IPuzzleLoader を実装する。
わざわざ IPuzzleLoader インタフェースを定義したのは、
ファイルなどから問題を読み出すクラスを
後から容易に作成することができるように考えたからだ。