VBAサンプル集Excel将棋:駒クラスの作成(№3)
Excel VBAを用いた将棋プログラムの開発において、最も重要な設計思想は「オブジェクト指向」の導入です。前回の記事では盤面の管理について触れましたが、今回はその最小単位である「駒」をクラスモジュールとして定義し、その挙動を制御する実装の詳細を解説します。
将棋の駒は、単なる「歩」や「飛車」といった名前のデータではありません。現在の座標、所有者(先手・後手)、成りの状態、そして何より「その駒がどのような動きを許容されるか」というルールを内包するオブジェクトです。VBAでこれを実装することで、複雑な条件分岐を排除し、拡張性の高いプログラムを構築することが可能になります。
クラスモジュール設計の要諦
VBAでクラスモジュールを作成する際、まずはプロパティ(属性)とメソッド(操作)を明確に定義する必要があります。駒クラス(C_Piece)に必要なプロパティは以下の通りです。
1. PieceType: 駒の種類(歩、香、桂、銀、金、角、飛、玉、および成駒)
2. Owner: 所有者(0: 空、1: 先手、2: 後手)
3. IsPromoted: 成り状態のフラグ
4. CurrentX, CurrentY: 盤面上の座標
これらのプロパティを保持することで、特定の駒がどの位置に存在し、誰の所有物であるかを一意に特定できます。次に、メソッドとして「移動可能かどうかの判定(CanMove)」や「成りの判定」を実装します。
駒クラスの実装例
以下に、駒クラス(クラスモジュール名:C_Piece)の基本的な実装コードを示します。このコードは、オブジェクト指向の恩恵を最大限に受けるための最小構成です。
' クラスモジュール: C_Piece
Option Explicit
Public Enum PieceType
pNone = 0
pFu = 1
pKy = 2
pKe = 3
pGi = 4
pKi = 5
pKa = 6
pHi = 7
pOu = 8
' 成駒は適宜追加
End Enum
Public TypeId As PieceType
Public Owner As Integer
Public IsPromoted As Boolean
Public X As Integer
Public Y As Integer
' 駒の動きを判定するメソッド
Public Function CanMove(TargetX As Integer, TargetY As Integer) As Boolean
Dim dx As Integer, dy As Integer
dx = TargetX - Me.X
dy = TargetY - Me.Y
Select Case Me.TypeId
Case pFu
If Me.Owner = 1 Then ' 先手
If dx = 0 And dy = -1 Then CanMove = True
Else ' 後手
If dx = 0 And dy = 1 Then CanMove = True
End If
' 他の駒のロジックをここに記述
Case pHi
If dx = 0 Or dy = 0 Then CanMove = True
End Select
End Function
この実装のポイントは、メソッド内に条件分岐を集約させることです。メインのプログラムから「この駒は動けるか?」と問い合わせるだけで、駒自身が自分のルールに基づいて回答する仕組みを作ります。これにより、メインプログラムが「歩の動き」をいちいち記憶する必要がなくなります。
詳細解説:なぜクラス化が必要か
多くの初心者は、盤面を二次元配列(Integer型など)で管理し、その配列の値を条件分岐で判定しようとします。しかし、駒の種類が増え、成りのルールが複雑化してくると、コードは「スパゲッティ状態」に陥ります。
例えば、角が成った「龍馬」の動きを判定する場合、配列管理では「もし値がXで、かつ成りフラグが立っていれば、斜めと上下左右の動きを許可する」といった巨大なIf文が必要になります。一方、クラスモジュールを使用すれば、「龍馬クラス」あるいは「成った駒」というオブジェクトとして振る舞いをカプセル化できるため、修正箇所が局所化されます。
また、クラスモジュールを用いる最大の利点は、VBAの「コレクション」との相性の良さにあります。盤面上の駒をすべてコレクションに格納しておけば、盤面全体を走査して「王手がかかっているか」を判定する際、各駒のオブジェクトに対して一斉にCanMoveメソッドを呼び出すだけで済みます。
実務的なアドバイス:メモリ管理とパフォーマンス
VBAでクラスを多用する場合、メモリの解放(Nothingの明示)には細心の注意を払う必要があります。将棋プログラムでは、棋譜の解析などで大量の駒オブジェクトを生成・破棄することが予想されます。
1. 不要になったオブジェクトは必ず Set obj = Nothing で解放すること。
2. 駒の移動時にインスタンスを再生成するのではなく、プロパティ(X, Y)の書き換えで済むよう設計すること。
3. 盤面の状態を「スナップショット」として保存したい場合は、クラスの複製を行う「ディープコピー」の実装を検討すること。
特に、AI(コンピュータ思考)を実装する場合、何手先まで読むかによって数万回単位の計算が行われます。クラスのインスタンス生成コストは決して低くないため、頻繁に生成・破棄を繰り返すのではなく、固定のオブジェクトプールを利用するか、あるいは単純な構造体(Type)とメソッドの組み合わせに切り替える判断も必要です。
拡張性の確保:ポリモーフィズムの活用
さらに高度な実装を目指すのであれば、インターフェースの実装を検討してください。例えば「IMoveable」というインターフェースを定義し、すべての駒クラスにこれを実装させます。これにより、将棋盤側は「駒が何であるか」を知らなくても、「動けるかどうか」を尋ねるだけで処理を完結させることができます。
これは、将来的に「持ち駒」や「盤外」の概念を導入する際にも非常に強力です。持ち駒のリストもまた、駒オブジェクトのコレクションとして管理すれば、持ち駒を盤上に配置する(打つ)という動作も、オブジェクトの移動という統一されたインターフェースで処理できるからです。
まとめ
VBAで将棋プログラムを作成するということは、単にExcel上で駒を動かすことではありません。それは、オブジェクト指向という強力な設計手法を用いて、現実世界の複雑なルールを論理的にコードへ落とし込む訓練です。
今回作成した「駒クラス」は、プログラム全体の心臓部です。ここが堅牢に設計されていれば、以降の「盤面制御」「対局ロジック」「AI思考ルーチン」の実装は驚くほどスムーズに進みます。まずは、歩・香・桂・銀・金・角・飛・玉の8種類の動きをクラス内で定義し、それぞれの移動判定をテストすることから始めてください。
Excelという身近なツールを使いながら、プロフェッショナルなソフトウェア開発の基礎を学ぶ。この将棋プログラム開発の過程こそが、あなたのVBAエンジニアとしてのスキルを一段上のステージへと引き上げるはずです。次回は、これら駒オブジェクトを統合管理する「盤面制御クラス」の構築について深掘りしていきます。
