オセロ開発で習得するVBAの極意:データ構造と盤面描画の最適化
VBAでゲームを開発することは、単なる趣味の範疇を超えた、非常に高度なプログラミングスキルの訓練となります。特に「オセロ」のようなボードゲームは、配列、条件分岐、ループ処理、そしてイベント駆動型プログラミングの要素が凝縮されており、実務で求められる「構造化されたコードを書く力」を養うのに最適な題材です。本稿では、オセロ開発の第16回目として、最も重要かつ基礎となる「盤面のデータ構造の設計」と「Excelシート上への描画ロジック」に焦点を当てて解説します。
1. なぜオセロ開発がエンジニアの成長に寄与するのか
多くのVBAユーザーは、記録や集計といった「一方通行のデータ処理」には慣れています。しかし、ゲーム開発は「状態の管理」と「ユーザー入力による状態の変化」をリアルタイムで制御する必要があります。オセロの盤面は8×8の64マスです。これをどうVBAで表現し、どう管理するか。この設計思想こそが、今後の拡張性(AIの実装や対戦履歴の保存など)を左右します。
優れたコードは、データ(モデル)と表示(ビュー)が明確に分離されています。VBAにおいてこれを実現するには、グローバル変数やモジュールレベル変数を適切に管理し、盤面情報を保持する「二次元配列」を活用することが不可欠です。
2. 盤面データ構造の設計と実装
オセロの盤面状態を管理するために、最も効率的なのは「二次元配列」です。今回は、空の状態を0、黒を1、白を2として定義します。
まず、標準モジュールに盤面を保持するための変数を宣言します。
' 標準モジュール:modGameData
Public Const BOARD_SIZE As Integer = 8
Public BoardState(1 To BOARD_SIZE, 1 To BOARD_SIZE) As Integer
' 盤面の初期化ルーチン
Public Sub InitializeBoard()
Dim i As Integer, j As Integer
' 全マスを0(空)にリセット
For i = 1 To BOARD_SIZE
For j = 1 To BOARD_SIZE
BoardState(i, j) = 0
Next j
Next i
' 初期配置(中央の4マス)
BoardState(4, 4) = 2 ' 白
BoardState(5, 5) = 2 ' 白
BoardState(4, 5) = 1 ' 黒
BoardState(5, 4) = 1 ' 黒
End Sub
この設計のポイントは、盤面を「Excelのセル」と直結させないことです。セル自体をデータとして扱うと、再描画のたびにシートへのアクセスが発生し、処理速度が極端に低下します。必ず「メモリ上の配列」で計算を行い、最終結果のみをシートに反映させるのがプロの作法です。
3. Excelシートへの高速描画テクニック
Excelのセルに一つずつ色を塗る処理を繰り返すと、画面のちらつきが発生し、非常に遅くなります。これを回避するためには、Shapeオブジェクトの操作や、条件付き書式の活用、あるいはセル範囲を一括で塗りつぶす手法を組み合わせます。
ここでは、セルの背景色を動的に変更する「描画エンジン」のサンプルを紹介します。
' 標準モジュール:modDrawing
Public Sub RefreshBoardView()
Dim ws As Worksheet
Dim i As Integer, j As Integer
Dim cellRange As Range
Set ws = ThisWorkbook.Sheets("OthelloBoard")
' 画面更新を一時停止して高速化
Application.ScreenUpdating = False
For i = 1 To BOARD_SIZE
For j = 1 To BOARD_SIZE
Set cellRange = ws.Cells(i, j)
Select Case BoardState(i, j)
Case 0: ' 空
cellRange.Interior.Color = RGB(0, 128, 0) ' 緑
Case 1: ' 黒
cellRange.Interior.Color = RGB(0, 0, 0)
Case 2: ' 白
cellRange.Interior.Color = RGB(255, 255, 255)
End Select
Next j
Next i
Application.ScreenUpdating = True
End Sub
このコードのポイントは「Application.ScreenUpdating = False」です。これを記述するだけで、描画速度は数倍から数十倍に向上します。実務においても、大量のデータをシートに書き出す際は必須のテクニックです。
4. 実務で活かせるVBA設計のアドバイス
オセロ開発を通じて学ぶべきことは、単なるゲームの作り方ではありません。「疎結合なアーキテクチャ」の考え方です。
1. ロジックとUIの分離:今回のコードでは、`InitializeBoard`(論理)と `RefreshBoardView`(物理)が完全に分かれています。もし将来的に、Excelのセルではなくユーザーフォーム上で描画したくなった場合でも、`BoardState`という配列さえあれば、ロジックを書き直す必要はありません。
2. 名前付き定数の活用:`BOARD_SIZE`のようにマジックナンバー(直接書かれた数値)を排除することで、将来的な盤面の拡大(例:10×10など)にも柔軟に対応できるコードになります。
3. エラーハンドリングの意識:ゲームはユーザーが想定外の操作(盤面外のクリックなど)を行う可能性があります。常に境界値チェックを意識したコードを書くことは、堅牢な業務システム開発の基礎となります。
5. 次のステップへの展望
今回の実装で、盤面を表示し、初期状態をセットするところまでが完了しました。しかし、オセロの本質は「挟む」というルール判定にあります。次回以降は、どの方向に石を裏返せるかを探査する「探索アルゴリズム」の実装が必要です。
探索には、「方向ベクトル」という考え方を用います。上下左右、斜めを含む8方向を配列で定義し、ループ内で加算していく手法です。これについては、また別の機会に詳しく掘り下げますが、今回作成した「配列で管理する」という基盤があれば、その実装は驚くほどスムーズに進むはずです。
まとめ:VBAを「ツール」から「武器」へ
VBAは、単なるマクロ記録ツールではありません。今回のように、盤面データ構造を設計し、描画ロジックを最適化するプロセスを繰り返すことで、あなたは「Excelを動かす」段階から「Excelでアプリケーションを構築する」段階へとステップアップできます。
プログラミングにおいて、最も重要なのは「動けばいい」という考えを捨てることです。なぜその変数をそこに置くのか、なぜそのループ処理が必要なのか。論理的な裏付けを持ってコードを書く習慣こそが、あなたを真のVBAエキスパートへと導きます。
今回のオセロ開発を通じて、配列の扱いと画面更新の制御について深く理解できたはずです。ぜひ、このコードをベースに、自分なりのアレンジを加えてみてください。例えば、盤面の背景色を変えてみたり、石の配置を別の方法で表現してみるのも良い練習になります。エンジニアとしての探求心を持ち続け、一歩ずつ技術の階段を登っていきましょう。
