【VBAリファレンス】VBAサンプル集オセロを作りながらマクロVBAを学ぼう№4

スポンサーリンク

VBAで構築するオセロゲーム:盤面管理と石の配置ロジックの実装

オセロというゲームは、プログラミング学習において非常に優れた教材です。なぜなら、単なるグラフィック表示だけでなく、二次元配列によるデータ構造、条件分岐による判定処理、そしてループ処理による再帰的な探索など、エンジニアとして必須となるロジックが凝縮されているからです。本稿では、オセロ開発の第4段階として、盤面のデータ管理と、実際に石を置いた際に周囲の石を裏返す「反転ロジック」の実装に焦点を当てます。

盤面管理の設計とデータ構造

オセロの盤面は8×8のマス目で構成されています。Excel VBAにおいてこれを表現する最も効率的な方法は、二次元配列を用いることです。ワークシート上のセルを直接参照することも可能ですが、処理速度とコードの可読性を考慮すると、メモリ上で配列を操作し、最終結果をシートに反映させる「データ駆動型」の設計を推奨します。

具体的には、8×8のInteger型配列を用意し、0を「空」、1を「黒」、2を「白」と定義します。この配列をグローバル変数として定義することで、複数のプロシージャ間での状態共有が可能になります。

石の反転ロジックのアルゴリズム

オセロの核心となるのは、石を置いた地点から8方向(上下左右および斜め)を探索し、相手の石を挟み込んでいる場合にのみ、その間の石を自分の色に書き換えるという処理です。このロジックを実装する際は、以下のステップを踏む必要があります。

1. 配置対象のマスが空であるかを確認する。
2. 8方向それぞれに対して、順次隣のセルを探索する。
3. 相手の石が連続しているかを確認し、その先に自分の石があるかを判定する。
4. 挟み込んでいることが確定した場合のみ、間の石を自分の色で上書きする。

この処理において、方向を制御するために「方向ベクトル」という概念を導入します。これは、行方向(dy)と列方向(dx)の変化量を定義した配列を用いる手法です。これにより、8つの方向を個別に書くのではなく、ループ内で方向を切り替えて処理を統合できるため、コードの保守性が飛躍的に向上します。

実務に即したサンプルコード

以下に、盤面を管理する配列と、石を置いた際の反転ロジックを統合したサンプルコードを提示します。このコードは標準モジュールに記述してください。


' グローバル変数定義
Public Board(1 To 8, 1 To 8) As Integer
Public Const EMPTY As Integer = 0
Public Const BLACK As Integer = 1
Public Const WHITE As Integer = 2

' 石を置くメイン処理
Sub PlaceStone(row As Integer, col As Integer, player As Integer)
    Dim dRow As Integer, dCol As Integer
    Dim i As Integer, j As Integer
    Dim canFlip As Boolean
    
    ' 方向ベクトル定義(8方向)
    Dim dr As Variant, dc As Variant
    dr = Array(-1, -1, -1, 0, 0, 1, 1, 1)
    dc = Array(-1, 0, 1, -1, 1, -1, 0, 1)
    
    If Board(row, col) <> EMPTY Then Exit Sub
    
    ' 各方向の探索
    For i = LBound(dr) To UBound(dr)
        If CheckAndFlip(row, col, dr(i), dc(i), player, False) Then
            Call CheckAndFlip(row, col, dr(i), dc(i), player, True)
        End If
    Next i
    
    Board(row, col) = player
    Call UpdateSheet ' シートへの反映処理(別途定義)
End Sub

' 再帰的またはループによる探索と反転
Function CheckAndFlip(r As Integer, c As Integer, dr As Integer, dc As Integer, player As Integer, doFlip As Boolean) As Boolean
    Dim nr As Integer, nc As Integer
    Dim opponent As Integer
    opponent = IIf(player = BLACK, WHITE, BLACK)
    
    nr = r + dr
    nc = c + dc
    
    ' 範囲外チェック
    If nr < 1 Or nr > 8 Or nc < 1 Or nc > 8 Then Exit Function
    ' 相手の石がない場合は挟めない
    If Board(nr, nc) <> opponent Then Exit Function
    
    ' 相手の石を飛び越えて自分の石があるか探索
    Do
        nr = nr + dr
        nc = nc + dc
        If nr < 1 Or nr > 8 Or nc < 1 Or nc > 8 Then Exit Function
        If Board(nr, nc) = EMPTY Then Exit Function
        
        If Board(nr, nc) = player Then
            ' 挟み込み成功
            If doFlip Then
                Dim fr As Integer, fc As Integer
                fr = r + dr: fc = c + dc
                Do While fr <> nr Or fc <> nc
                    Board(fr, fc) = player
                    fr = fr + dr: fc = fc + dc
                Loop
            End If
            CheckAndFlip = True
            Exit Function
        End If
    Loop
End Function

実務アドバイス:コードの保守性とパフォーマンス

実務の現場でVBAを扱う際、最も重要視されるのは「可読性」と「修正の容易さ」です。上記のサンプルコードでは、方向ベクトルを配列で定義し、探索ロジックを関数化しています。これにより、「斜めの判定だけ条件を変えたい」といった仕様変更が発生した場合でも、特定の箇所を修正するだけで全体に反映させることが可能です。

また、Excel VBAにおける描画処理(シートの更新)は重い動作です。そのため、計算が終わるまでは`Application.ScreenUpdating = False`を使い、画面描画を停止させてから処理を実行し、最後に`True`に戻すというテクニックを必ず組み込んでください。これにより、実行速度が劇的に向上します。

さらに、プロフェッショナルな設計としては、バリデーション(入力チェック)を徹底することも重要です。ユーザーが誤って盤面外をクリックしたり、既に石がある場所に置こうとした際の挙動を制御する「ガード節」を先頭に配置することで、意図しないエラーを防ぐ堅牢なアプリケーションとなります。

まとめ

今回のステップでは、オセロの核となる「石の反転ロジック」を実装しました。このロジックを理解することは、二次元配列の操作やループ処理におけるフラグ制御をマスターすることと同義です。

1. 二次元配列を用いて盤面の状態をメモリ上で管理する。
2. 方向ベクトルを用いて8方向の探索を簡潔に記述する。
3. 判定ロジックと実行ロジックを分離し、保守性を高める。
4. シート反映のタイミングを制御し、パフォーマンスを最適化する。

これらの技術は、オセロだけでなく、業務における複雑なデータ処理やシミュレーションツールを作成する際にもそのまま応用できる強力な武器となります。次回のステップでは、この盤面ロジックに「AI(思考ルーチン)」を組み込み、コンピュータと対戦できる環境を構築していきます。VBAの可能性は、単なる事務処理の自動化に留まりません。論理的な思考をコードに落とし込む訓練を続け、より高度なシステム開発を目指しましょう。

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