【VBAリファレンス】Excel VBAで実現する本格将棋エンジン開発 第10回:駒の奪取と持ち駒再利用のロジック構築

スポンサーリンク

概要:将棋ゲーム開発における「持ち駒」という概念の重要性

Excel VBAを用いて将棋という複雑なボードゲームを再現する際、最もプログラミング的な面白さと難しさが同居するのが「駒の奪取」と「持ち駒の再利用」というプロセスです。単なる移動(Move)だけでなく、盤面上のオブジェクトを削除し、別のデータ構造(配列やコレクション)へと移動させるこの一連の流れは、データ管理の精髄と言えます。今回は、将棋プログラムの心臓部とも言える「持ち駒システム」の実装について、実務レベルのコードと共に深く解説していきます。

詳細解説:駒の奪取とステータス管理のアルゴリズム

将棋において「相手の駒を取る」という行為は、単に移動先のセルを上書きするだけでは不十分です。以下のステップを厳密に踏む必要があります。

1. ターゲットの特定:移動先に相手の駒が存在するか判定する。
2. 駒の変換(裏返り):取った駒が「成駒」であった場合、「成り」を解除して元の駒に戻す。
3. 持ち駒の更新:取った側の持ち駒リスト(変数または専用のセル範囲)に駒を追加する。
4. 盤面のクリア:元の位置から駒を削除し、新しい位置に自分の駒を配置する。

このプロセスにおいて、特に重要なのが「持ち駒のデータ構造」です。VBAでは、持ち駒の数を管理するために、各プレイヤーごとに「歩、香、桂、銀、金、角、飛」という7種類の駒の個数を格納する配列を用いるのが最も効率的です。また、これらを視覚的にExcelシート上で表現するために、持ち駒専用のセル範囲を定義し、そこへ動的に画像を配置、あるいは文字を表示させる設計が求められます。

サンプルコード:駒取りと持ち駒への移動処理

以下は、駒を取る際のロジックと、持ち駒を盤面に打ち込む際の基本処理を実装したサンプルコードです。


' 持ち駒を管理するための構造体
Public Type Komadai
    Fu As Integer
    Kyo As Integer
    Kei As Integer
    Gin As Integer
    Kin As Integer
    Kaku As Integer
    Hi As Integer
End Type

Public Player1_Komadai As Komadai

' 相手の駒を取る処理の核となる関数
Sub CapturePiece(TargetRow As Integer, TargetCol As Integer, ByRef Komadai As Komadai)
    Dim CapturedPiece As String
    CapturedPiece = Cells(TargetRow, TargetCol).Value
    
    ' 成り駒を元の状態に戻す処理(例:と金 → 歩)
    Dim BasePiece As String
    BasePiece = GetBasePiece(CapturedPiece)
    
    ' 持ち駒配列を更新
    Select Case BasePiece
        Case "歩": Komadai.Fu = Komadai.Fu + 1
        Case "香": Komadai.Kyo = Komadai.Kyo + 1
        Case "桂": Komadai.Kei = Komadai.Kei + 1
        Case "銀": Komadai.Gin = Komadai.Gin + 1
        Case "金": Komadai.Kin = Komadai.Kin + 1
        Case "角": Komadai.Kaku = Komadai.Kaku + 1
        Case "飛": Komadai.Hi = Komadai.Hi + 1
    End Select
    
    ' 盤面の更新ロジックをここに記述
    MsgBox "相手の" & BasePiece & "を取って持ち駒に加えました。"
End Sub

' 持ち駒を盤面に打つ処理
Sub DropPiece(PieceName As String, TargetRow As Integer, TargetCol As Integer, ByRef Komadai As Komadai)
    ' 持ち駒の在庫チェック
    If Not HasPiece(PieceName, Komadai) Then
        MsgBox "その駒は持ち駒にありません。"
        Exit Sub
    End If
    
    ' 盤面に配置
    Cells(TargetRow, TargetCol).Value = PieceName
    
    ' 持ち駒を減らす処理
    ' (ここでは省略しますが、各変数から-1する処理を実装します)
    
    ' 持ち駒表示の更新(画面描画処理)
    UpdateKomadaiDisplay
End Sub

実務アドバイス:メンテナンス性を高める設計のコツ

Excel VBAでゲームを開発する際、陥りやすい罠が「シート上のセル位置と変数の値が同期しなくなること」です。これを防ぐために、以下の設計指針を推奨します。

第一に、「シングルソース・オブ・トゥルース(単一の真実源)」を徹底してください。シート上のセルの値を参照してロジックを組むのではなく、常に「メモリ上の配列」が正であるとし、シートはあくまでその結果を「表示する媒体」として割り切ることです。これにより、バグが発生した際のデバッグが格段に容易になります。

第二に、駒の種類を定数(Enum)で管理することです。文字列で「歩」「金」などを比較するのは、タイプミスの温床となります。`Public Enum PieceType` を使用し、数値で駒を管理することで、コードの堅牢性が劇的に向上します。

第三に、イベントハンドラの活用です。Excelの `Worksheet_SelectionChange` や `Worksheet_BeforeDoubleClick` を上手く利用することで、クリック操作だけで駒取りや配置ができる直感的なUIを実現できます。ただし、イベントが多重に発火しないよう、処理の冒頭で `Application.EnableEvents = False` を記述し、終了時に `True` に戻すことを忘れないでください。

まとめ:将棋エンジン開発から学ぶオブジェクト指向の考え方

今回解説した「駒を取る」「持ち駒を打つ」という処理は、小規模なVBAプログラムであっても、立派なオブジェクト指向プログラミングの練習台になります。駒という「オブジェクト」が盤面という「コンテナ」から別のコンテナへと移動する様をコード化することは、プログラミングにおけるデータの持ち運び、状態遷移の管理能力を飛躍的に高めてくれます。

Excel VBAは単なる事務処理ツールではありません。このように論理的な思考を積み重ねることで、将棋のような複雑な思考ゲームさえも再現可能な強力な開発環境へと変貌します。今回紹介したロジックを基盤に、次は「二歩」や「打ち歩詰め」といった将棋特有の反則判定ロジックを実装し、より本格的なエンジンへとブラッシュアップさせてみてください。あなたのVBAスキルは、このプロジェクトを通して確実に次のステージへと到達するはずです。

次回の記事では、いよいよ「王手」の判定ロジックと「詰み」の検出アルゴリズムについて、さらに踏み込んで解説します。盤面上のすべての駒の利き(支配領域)を計算する、VBAエンジニアにとっての登竜門的課題です。ぜひ、今回の実装を完璧にした状態で次回の講義に臨んでください。

タイトルとURLをコピーしました