2006 年 6 月 2 日 18 時 50 分

IPuzzleLineSolver: 解法アルゴリズムの分離


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


さて、帰謬法を応用したの実装を導入したいところだが、
PuzzleLine に追加して肥大化させるのはあまりよくない。

複数のアルゴリズムをうまく使い分けるためにも、
PuzzleLine から解法の実装部分を切り離すことを考えよう。

そこで、IPuzzleLineSolver というインタフェースを定義し、
解法は個別のクラスとして、インタフェースを実装させる。

IPuzzleLineSolver は、なるべくシンプルにしよう。
関数的な役割を持つインタフェースなので、
必要なのは、メソッド 1 つだけとする。

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

Option Explicit

Public Function Execute( _
        ByVal Hints As PuzzleHintCollection, _
        ByRef States() As CellStateConstants) As Long
End Function

#===== end of IPuzzleLineSolver =====

これは、最初に作ったアルゴリズムである SolveLine や、
昨日作った SolveLineByRaa のシグネチャと同じだ。
これらの関数を、個別のアルゴリズムクラスとして、
PuzzleLine とは独立させて実装し、
PuzzleLine からこれらアルゴリズムを利用する。

移植は簡単だ。

例えば、最初のアルゴリズムを、
OverlapDetector という名前のクラスにしてみよう。

SolveLine、PackFront、PackRear の 3 つを、
そのまま引っ越すだけでいい。
SolveLine は、Execute に名前を変更し、
IPuzzleLineSolver_Execute を実装すれば OK だ。

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

Option Explicit

'##################################################
'# 重なる部分を見つけ出すアルゴリズム
'##################################################

' インタフェースの宣言
Implements IPuzzleLineSolver

Public Function Execute( _
        ByVal Hints As PuzzleHintCollection, _
        ByRef States() As CellStateConstants) As Long

    ' 中身は省略、アクセスを Public に
    ' 戻り値用の変数名前も Execute に変える

End Function

' PackFront 省略
' PackRear 省略

' インタフェースの実装
Private Function IPuzzleLineSolver_Execute( _
        ByVal Hints As PuzzleHintCollection, _
        ByRef States() As CellStateConstants) As Long

    IPuzzleLineSolver_Execute = Execute(Hints, States)

End Function

========== end of OverlapDetector ==========

昨日作った SolveLineByRaa も同様に切り離す。
いい名前が思いつかないので、RaaSolver としよう。

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

Option Explicit

'##################################################
'# 帰謬法によりセルをひとつ確定させるアルゴリズム
'##################################################

' インタフェースの宣言
Implements IPuzzleLineSolver

Public Function Execute( _
        ByVal Hints As PuzzleHintCollection, _
        ByRef States() As CellStateConstants) As Long

    ' 中身は省略

End Function

' CheckConsistency 省略

' インタフェースの実装
Private Function IPuzzleLineSolver_Execute( _
        ByVal Hints As PuzzleHintCollection, _
        ByRef States() As CellStateConstants) As Long

    IPuzzleLineSolver_Execute = Execute(Hints, States)

End Function

========== end of RaaSolver ==========

よし。

こうして分離すれば、PuzzleLine は行列の管理と、
アルゴリズムを選択して解答を求める処理がメインとなり、
具体的なアルゴリズムから切り離すことができる。

アルゴリズムクラスは機械的に解くだけなので、
2 つのアルゴリズムをどのように使い分けるかは、
PuzzleLine の実装にかかっていることになる。



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