概要
Excel VBAを用いたオセロ開発プロジェクトも、いよいよ中盤のハイライトを迎えます。これまでは盤面の描画やプレイヤーの入力を制御するGUIの構築が中心でしたが、今回の№13では、オセロゲームの「心臓部」とも言える「石の反転判定アルゴリズム」を深掘りします。なぜある場所に石を置けるのか、どこまでが反転の対象となるのか。この複雑なロジックをいかにして効率的かつバグの少ないコードに落とし込むか。プログラミングの基礎体力とも言える配列処理と再帰的思考、そしてフラグ管理の妙技を解説します。
詳細解説
オセロのルールにおいて、石を置いた際に反転が発生する条件は「自分の石と置いた石の間に、相手の石が一つ以上並んでいること」です。これをVBAで実装する場合、単純な条件分岐の羅列ではコードが肥大化し、メンテナンスが困難になります。
ここで重要なのは「8方向のベクトル」をいかに計算するかという点です。オセロの盤面において、ある座標(r, c)から見て、上、下、左、右、そして斜め四方向の計8方向に対して、相手の石が連続しているかを探索する必要があります。
具体的なロジックのステップは以下の通りです。
1. 探索方向の定義:dx, dyという配列を用いて、8方向の増分を管理します。
2. 相手の石の走査:定義した方向に対して、相手の石が存在するかをループで判定します。
3. 自分の石の確認:相手の石が途切れた先に、自分の石が存在するかを確認します。
4. 確定と更新:条件が満たされた場合のみ、その経路上にある石の情報を書き換えます。
この処理を行う際、最も陥りやすい罠が「盤面の境界外参照」です。VBAでは配列のインデックスが範囲外になると即座にエラーとなります。これを防ぐために、境界チェック用の関数を別途用意するか、ループの条件式で厳密に制御することが不可欠です。
サンプルコード
以下は、特定の方向に石が反転可能かを判定し、実際に裏返す処理のコア部分です。
' 指定した方向に石を反転できるか判定し、可能なら反転させる関数
Function FlipDirection(ByVal row As Integer, ByVal col As Integer, _
ByVal dr As Integer, ByVal dc As Integer, _
ByVal playerColor As Integer) As Boolean
Dim r As Integer, c As Integer
Dim opponentColor As Integer
Dim stonesToFlip As Collection
Set stonesToFlip = New Collection
opponentColor = IIf(playerColor = 1, 2, 1)
r = row + dr
c = col + dc
' 探索開始
Do While r >= 1 And r <= 8 And c >= 1 And c <= 8
If Cells(r, c).Value = opponentColor Then
' 相手の石ならリストに追加
stonesToFlip.Add Array(r, c)
ElseIf Cells(r, c).Value = playerColor Then
' 自分の石に到達した場合、反転確定
If stonesToFlip.Count > 0 Then
Dim item As Variant
For Each item In stonesToFlip
Cells(item(0), item(1)).Value = playerColor
Next item
FlipDirection = True
Exit Function
End If
Exit Do
Else
' 空白セルに当たれば終了
Exit Do
End If
r = r + dr
c = c + dc
Loop
FlipDirection = False
End Function
実務アドバイス
このロジックを実装する際、実務的な観点から特に意識すべきポイントが「可読性と保守性」です。VBAのコードは往々にしてスパゲッティ化しがちです。今回のように「8方向」という同じ処理を繰り返す必要がある場合、今回示したように「方向ベクトル(dr, dc)」を引数として渡す関数設計にすることで、コードの重複を劇的に減らすことができます。
また、デバッグの際は「イミディエイトウィンドウ」をフル活用してください。Debug.Printを使用して、現在探索している座標と、現在保持している石の色を出力させることで、プログラムの進行状況をリアルタイムに監視できます。複雑なループ処理では、どこで判定が落ちているのかを視覚的に追うことが、早期解決の鍵となります。
さらに、パフォーマンス面でのアドバイスです。Excelのセル(Cellsプロパティ)へのアクセスは非常に低速です。本格的なゲーム開発を行う場合は、盤面の情報を一度メモリ上の2次元配列に読み込み、計算終了後に一括でセルへ書き戻す手法を強く推奨します。これにより、マクロの動作速度は劇的に向上します。
まとめ
今回の講座で学んだ「ベクトルを用いた探索」と「コレクションによる状態保持」は、オセロだけでなく、あらゆるボードゲームや、複雑なデータ解析ツールにも応用できる強力な武器となります。VBAは単なる事務作業の自動化ツールではありません。論理的思考を鍛え、プログラムの構造を設計する力を養うための最高の学習環境です。
コードが複雑になればなるほど、関数を小さく分け、役割を明確にすることが成功への近道です。次回の№14では、今回作成した判定ロジックを統合し、コンピュータの思考ルーチン(AI)の基礎となる「評価関数」の考え方について解説していきます。まずは、今回のコードを自身の環境で動かし、盤面の石が意図通りに反転するかを徹底的に検証してみてください。バグと向き合い、それを解決するプロセスこそが、あなたを真のVBAエンジニアへと成長させるのです。
