今回は棚クラスです。クラスの概要はこの連載の「(1)はじめに」を参考にしてください。
・クラス宣言
クラスの名前は "Shelf" です。
Public Class Shelf
・プロパティ:名前 Name
棚の名前です。中に入れる部品の名前をそのまま使います。解の表示で使用します。
ReadOnly Property Name As String
・プロパティ:表示色 Color
解の表示で背景色として使用します。
ReadOnly Property Color As Color
・プロパティ:部品集 Pieces
部品コレクション。回転や裏返しをしたものをあらかじめ入れておきます。
ReadOnly Property Pieces As List(Of Piece)
・プロパティ:部品を箱に置いたとき
部品集から部品を選択して箱に置いたときの部品と置いた座標。選択していないときはともにNothing
Property PlacedPiece As Piece Property PlacedCoord As Coord
・初期化
引数のうち name と color はそのままプロパティに、expressionは部品集(Pieces)をつくるための文字列です。
Sub New(name As String, color As Color, expression As String) _Name = name _Color = color _Pieces = New List(Of Piece) _PlacedPiece = Nothing _PlacedCoord = Nothing Dim piece As New Piece(expression) For i = 0 To 7 Dim p = piece.Clone() If i > 3 Then p.HorizontalReverse() End If p.AntiClockWiseRotate(i Mod 4) p.ShiftToOrigin() If Pieces.Any(Function(s) s = p) = False Then Pieces.Add(p) End If 'シノニム除外("F","N","L","Y","P"のどれかで設定) If name = "F" And i = 1 Then Exit For End If Next End Sub '=====(例)===== Dim piece As New Piece("RDRdL") '部品"F"を作成します
コード中の "シノニム" とはボード全体を180度回転させたり裏返したりするとぴったり重なる解となるものをいいます。パズルのルールではシノニムは同一解となります。シノニムを除外するにはどうしたらいいでしょうか?
図では8通りの解のうち6通りが シノニム となってしまいますが、部品集に原因となる6個を除外した2個(図の①と②)のみを登録すればシノニムはできなくなります。コードの「シノニム除外」のところで部品"F"について①と②以外が部品集に登録されるのを防いでいます。あとはどのように部品を配置してもシノニムができる心配はありません。
なおこの処理ができるのは8種類の向きがある部品("F", "N", "L", "Y", "P")に限ります。
以上が「棚クラス」です。クラス全体のソースは以下のとおりです。
Public Class Shelf '********************************************** '* Shelf (部品棚クラス) '********************************************** ReadOnly Property Name As String '名前 ReadOnly Property Color As Color '表示色 ReadOnly Property Pieces As List(Of Piece) '向きや裏返し別のコレクション(同じ形は含まない) Property PlacedPiece As Piece 'ボードに置いた部品(Pieces内の1個),置いてないときはNothing Property PlacedCoord As Coord 'PlacedPieceを置いた場所,置いてないときはNothing Sub New(name As String, color As Color, expression As String) _Name = name _Color = color _Pieces = New List(Of Piece) _PlacedPiece = Nothing _PlacedCoord = Nothing Dim piece As New Piece(expression) For i = 0 To 7 Dim p = piece.Clone() If i > 3 Then p.HorizontalReverse() End If p.AntiClockWiseRotate(i Mod 4) p.ShiftToOrigin() If Pieces.Any(Function(s) s = p) = False Then Pieces.Add(p) End If 'シノニム除外("F","N","L","Y","P"のどれかで設定) If name = "F" And i = 1 Then Exit For End If Next End Sub End Class
次は「箱クラス」です。