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

スポンサーリンク

オセロ開発で学ぶVBA:イベント駆動型プログラミングとゲームロジックの極意

Excel VBAは単なる事務処理の自動化ツールではありません。適切に設計すれば、複雑なロジックを持つゲームの開発さえ可能です。今回は「オセロ」という、盤面管理、判定ロジック、再帰的思考を必要とする高度なテーマを通じ、VBAエンジニアとして一歩先へ進むための技術を解説します。

オセロの核心は「8方向の探索」と「石の反転処理」にあります。これらを実装する過程で、オブジェクト指向の概念やイベント処理を深く理解することが可能です。

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

VBAでゲームを作る際、最も重要なのは「データの持ち方」です。セルを直接操作して盤面を管理することも可能ですが、処理速度とメンテナンス性を考慮すると、メモリ上の「二次元配列」を主軸にするのがプロの流儀です。

まず、8×8の盤面を定義するために、グローバル変数として配列を用意します。
Public Board(1 To 8, 1 To 8) As Integer
ここで、0を空き、1を黒、2を白と定義します。この定義を明確にすることで、条件分岐が簡潔になります。

次に、ユーザーがセルをクリックした際に反応する「Worksheet_SelectionChange」イベントを利用します。しかし、通常のセル選択だと操作性が悪いため、ダブルクリックイベントを使用するのが一般的です。

8方向探索ロジックの核心

オセロの判定ロジックで最も難易度が高いのは「相手の石を挟めるか」の判定です。これを力技で書くとif文がネストして地獄を見ることになります。ここで活用すべきは「方向ベクトル」の概念です。

方向ベクトルとは、{-1, 0, 1}の組み合わせで、上下左右斜めの8方向を表現する手法です。
dx = Array(-1, -1, -1, 0, 0, 1, 1, 1)
dy = Array(-1, 0, 1, -1, 1, -1, 0, 1)
この配列をループさせることで、8方向すべてに対して同一のロジックを適用できます。

サンプルコード:石の配置と反転処理

以下に、特定の場所に石を置いた際、周囲を探索して反転させるためのコアロジックを提示します。


' 指定位置に石を置いた際、反転可能な石をすべて反転させる処理
Sub PlaceDisk(row As Integer, col As Integer, color As Integer)
    Dim i As Integer, j As Integer, k As Integer
    Dim dx As Variant, dy As Variant
    Dim r As Integer, c As Integer
    Dim opponent As Integer
    
    opponent = IIf(color = 1, 2, 1)
    dx = Array(-1, -1, -1, 0, 0, 1, 1, 1)
    dy = Array(-1, 0, 1, -1, 1, -1, 0, 1)
    
    Board(row, col) = color
    
    ' 8方向を順次探索
    For i = 0 To 7
        r = row + dx(i)
        c = col + dy(i)
        
        ' 相手の石が連続しているか確認
        If r >= 1 And r <= 8 And c >= 1 And c <= 8 Then
            If Board(r, c) = opponent Then
                ' 相手の石を追いかけて、自分の石で挟めるかチェック
                Dim tempR As Integer, tempC As Integer
                tempR = r
                tempC = c
                
                Do While tempR >= 1 And tempR <= 8 And tempC >= 1 And tempC <= 8
                    If Board(tempR, tempC) = 0 Then Exit Do
                    If Board(tempR, tempC) = color Then
                        ' 挟めたので反転処理
                        Dim flipR As Integer, flipC As Integer
                        flipR = row + dx(i)
                        flipC = col + dy(i)
                        Do While flipR <> tempR Or flipC <> tempC
                            Board(flipR, flipC) = color
                            flipR = flipR + dx(i)
                            flipC = flipC + dy(i)
                        Loop
                        Exit Do
                    End If
                    tempR = tempR + dx(i)
                    tempC = tempC + dy(i)
                Loop
            End If
        End If
    Next i
    
    ' 画面描画の更新
    UpdateBoardUI
End Sub

実務におけるVBA設計の教訓

このオセロ開発を通じて学ぶべきは、単なるコードの書き方だけではありません。以下の3点が、実務でのVBA開発に直結します。

1. ロジックとUIの分離:
上記のコードでは、配列(Board)の更新と、Excel画面(UI)の描画を分離しています。実務でも、計算ロジックと表示ロジックを分けることで、バグの特定が容易になり、将来的な仕様変更にも耐えうるコードになります。

2. 定数の活用:
「1」「2」といったマジックナンバーをコード内に散りばめると、後から見た時に意味が分からなくなります。Enum(列挙型)を使用して、Color_Black = 1、Color_White = 2のように定義しましょう。これにより、コードの可読性が劇的に向上します。

3. エラーハンドリング:
ゲーム中、ユーザーが誤った操作をした場合、プログラムがクラッシュしてはなりません。境界条件チェック(r >= 1 And r <= 8など)を徹底することは、業務アプリにおける入力チェックの徹底と同じです。

高度な実装に向けたステップアップ

今回のサンプルは基本的な「置く・反転する」という動作に焦点を当てましたが、実用レベルのゲームにするには、以下の機能追加を検討してください。

・パス判定:置ける場所がない場合の自動パス処理。
・AIの実装:ミニマックス法を用いた、簡単な思考ルーチン。
・終了判定:盤面が埋まった、または双方が置けなくなった時のスコア集計。

特にAIの実装は、VBAの処理速度の限界に挑戦する良い機会です。再帰呼び出しを多用することになるため、スタックオーバーフローを防ぐためのメモリ管理や、計算量を減らすための枝刈り(Alpha-Beta法)といったアルゴリズムの基礎を学ぶことができます。

まとめ:VBAで「思考するコード」を書く

VBAは、単にセルをコピー・ペーストするだけの言語ではありません。今回作成したオセロのようなプログラムは、あなたの論理的思考力を鍛え、複雑な業務要件をコードに落とし込む際の「抽象化能力」を養ってくれます。

「8方向探索」というアルゴリズムは、実は業務システムにおける「階層データの検索」や「依存関係の解析」にも応用可能です。ゲーム開発という一見遊びのように見えるプロセスの中に、プロフェッショナルなエンジニアとして必要な技術的エッセンスが凝縮されています。

今日学んだ配列操作と方向ベクトルの考え方を、ぜひ次回の業務自動化プロジェクトに応用してみてください。複雑な条件分岐の山に悩まされることが減り、よりスマートで拡張性の高いツールが作れるようになるはずです。VBAという道具を、あなたの最強の武器へと昇華させましょう。

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