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の可能性は、単なる事務処理の自動化に留まりません。論理的な思考をコードに落とし込む訓練を続け、より高度なシステム開発を目指しましょう。
