VBAサンプル集
オセロを作りながらマクロVBAを学ぼう№4

ExcelマクロVBAの実用サンプル、エクセルVBA集と解説
最終更新日:2020-12-08

オセロを作りながらマクロVBAを学ぼう№4


ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第4回です。


石を置ける場所の定義を、前回は文章で書きました、
今回は、それをもとにマクロVBAのプログラミングをしていきます。
考え方は決定しているので、後はVBAに翻訳(コーディング)していくだけです。

まずは、前回のまとめの確認です。

自分の石を置ける場所の判定の整理
・判定セルから、8方向に検査を進める
・8方向は、
 For i = -1 To 1
 For j = -1 To 1
 これをネストする
・1方向に向かって順に置かれている石を判定
 終了条件は、
  ・空白(石が置かれていない)
  ・自分の石が置かれている
 自分の石が置かれていて終了した時、それまでに相手の石があるか
・8方向のいずれか一つでも、上記条件を満たせば、自分の石が置ける


セルをダブルクリックした時、
そこに石が置けるかどうかを判定し、メッセージボックスを表示するようにしてみます。



シート「オセロ」のシートモジュールにダブルクリックのイベントプロシージャーを追加します。

マクロVBAの参考画像

Sheet1(オセロ)
ここをダブルクリックします。
または、右クリックから「コードの表示

マクロVBAの参考画像

この下にダブルクリックのイベントプロシージャーを追加します。

マクロVBAの参考画像

プロシージャーが追加されます。
左オブジェクト選択のドロップタ゜ウンを「Worksheet」を選択した時点で、
「Worksheet_SelectionChange」これが追加されてしまいます。
残したままでも特に問題はありませんが、削除しておきましょう。
以下のコードを追加してください。



Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
  Set TargetSheet = Sheet1
  Set 置く石 = Range("L2")
  Set 相手石 = Range("L3")
  If is置ける全方向(Target) Then
    MsgBox "置ける"
  Else
    MsgBox "置けない"
  End If
  Cancel = True
End Sub

引数の、
TargetはRangeオブジェクトです。
・Rangeオブジェクトを参照するためのプロパティ ・Rangeオブジェクトを返すRangeプロパティ ・Rangeオブジェクトのデータ型 ・全てのセルを表すCells ・Rangeオブジェクトの使用例 ・RangeとCellsの使い分け方 ・VBEの自動メンバ表示(インテリセンス) ・RowsとColumns ・Rangeオブジェクトのプロパティとメソッド ・Rangeオブジェクトは難しい ・RangeとCellsの関連記事
ダブルクリックしたセルになります。



標準モジュールに石が置けるかの判定を作ります。
マクロVBAの参考画像

Module1
ここをダブルクリック
または、右クリックから「コードの表示

Option Explicit
これだけが入っているはずなので、その下に以下のコードを追加してください。



Public TargetSheet As Worksheet
Public 置く石 As Range
Public 相手石 As Range

Function is置ける全方向(ByVal Target As Range) As Boolean
  Dim i As Long
  Dim j As Long
  '既に石が置いてある場合は置けない
  If Target.Value <> "" Then
    is置ける全方向 = False
    Exit Function
  End If
  '8方向を順に判定
  For i = -1 To 1
    For j = -1 To 1
      If is置ける1方向(Target, i, j) Then
        is置ける全方向 = True
      End If
    Next
  Next
End Function

Function is置ける1方向(ByVal Target As Range, _
      ByVal i As Long, _
      ByVal j As Long) As Boolean
  Dim r As Long
  Dim c As Long
  Dim is置く石 As Boolean
  Dim is相手石 As Boolean
  '石を置くセルの行列位置
  r = Target.Row
  c = Target.Column
  With TargetSheet
    '空白or置く石と同じ石が出てくるまで判定
    Do
      r = r + i
      c = c + j
      '空白(石が置かれていない)
      If .Cells(r, c) = "" Then
        Exit Do
      End If
      '自分の石が置かれている
      If .Cells(r, c).Font.Color = 置く石.Font.Color Then
        is置く石 = True
        Exit Do
      End If
      '相手の石が置かれている
      If .Cells(r, c).Font.Color <> 置く石.Font.Color Then
        is相手石 = True
      End If
    Loop
  End With
  '自分の石が置かれていて終了した時、それまでに相手の石があるか
  If is置く石 = True And is相手石 = True Then
    is置ける1方向 = True
  End If
End Function

良く使うオブジェクトを
オブジェクト変数
・オブジェクト変数 ・個有のオブジェクト型とは ・Setステートメント ・Setステートメントの使用例 ・WithとSetの使い分け方 ・Setステートメントの実践的な使い方 ・Is演算子によるオブジェクトの比較 ・最後に

パプリック変数
・プロシージャーレベル変数 ・・・ プロシージャー内でのみ使用可能 ・モジュールレベル変数 ・・・ モジュール内でのみ使用可能 ・パブリック変数 ・・・ 全てのモジュールの全てのプロシージャーで使用可能 ・変数の適用範囲について簡単にまとめてると ・定数(Const)の適用範囲について ・変数の重複について ・変数は、極力狭いスコープで使う事が望ましいとされます。
として定義しています。

Public TargetSheet As Worksheet ・・・ オセロ盤があるシート
Public 置く石 As Range ・・・ 置く石が設定されているセル
Public 相手石 As Range ・・・ 相手の石が設定されているセル

Worksheet_BeforeDoubleClick
この中で、パブリック変数を設定してから、 「is置ける全方向」を呼び出します。
Cancel = True
これは、ダブルクリックの後にセル編集状態にならないように、イベントを終了させるためのものです。

Functionプロシージャー
プログラム(マクロVBA)内で特定の処理を実行し値を返すプロシージャーです。これはつまり、Functionプロシージャーで独自の関数をつくれるということです。Subプロシージャーとの違いは、値を返すか返さないかの違いです。
プログラム内で特定の作業を実行し、値を返すプロシージャです。
Functionプロシージャーの括弧()の中に引数が指定されています。
これは、プロシージャーに引数を渡しています。
・引数の構文 ・引数の使用例 ・引数について

is置ける全方向
これで8方向を判定できるようにしています。
実際には3×3=9方向なのですがも行0列0の移動は石を置きたい場所なので、
既に石が置いてある場合は置けない判定で直ぐに判定が終了しています。
If is置ける1方向(Target, i, j) Then
これで、1方向でも「置ける」判定であれば、「置ける」と返すようにしています。

is置ける1方向
ここでは、「is置ける全方向」から渡された方向について判定をします。
If is置く石 = True And is相手石 = True Then
これで、相手の石があって、その先に置く石があることを判定しています。

.Font.Color
この違いで判定しているので、少しわかりずらいかもしれませんが、
個々のステートメントは極めて基本的なものだけとなっています。

変数の型として、Boolean(ブール型)を多用しています。
ブール型は、True,Falseの2値をとる変数です。
つまり、ON,OFFや有,無等々の状態判定に使います。

判定に必要な項目の状態を、その項目ごとにTrue,Falseを先に判定し設定しておくことで、
その後に、複数の項目の状態を判定し、全体として条件を満たしているかどうかを判定しています。
これは、判定が複雑な場合に良く使う手法ですので、ぜひマスターして下さい。



「自分の石を置ける場所の判定の整理」
この文章と、VBAコードを見比べて下さい。
参考程度ではありますが、VBA内にコメントを書いておきました。

実際に、オセロ盤をダブルクリックして動作確認してみて下さい。
石の配置を変更する場合は、シート保護を解除してからコピペで石を配置してください。


今回は、文章をVBAコードにする部分に注力しました。
これで、オセロゲームの根本的な部分のロジックができましたので、
次回からは、ゲームとしての機能を一つずつ追加していきます。

№5へ続きます。
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第5回です。前回で石を置ける場所の判定が完成しましたので、これからは、ゲームとしての機能を一つずつ追加していきます。まずは、石を置ける場所の色を変更してわかりやすくしてみます。

全体の目次
はじめに
ExcelマクロVBAでオセロ(リバーシ)を作っていきながら、マクロVBAを学んで行きましょう。目的は、マクロVBAの学習であり、思考を整理しVBAでプログラミングする学習です。従って、強いソフトを作ることが目的ではありませんので、最近流行のAIなんちゃら…なんていうのは考えるつもりはありません。
№1.シートの用意と標準モジュールの挿入
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第1回です。まずはシートを用意しなければなりません、このシートの作り方で、その後の手間が随分と変わってきますので、しっかりと作ります。とはいえ、まずは一般的な感じで作ってみます、今後必要に応じて追加・変更していきます。
№2.ブックを開いたときの処理と初期配置
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第2回です。前回でシートの準備と標準モジュールを挿入しましたので、今回からは、マクロVBAをどんどん書き足していきます。まずは、イベントプロシージャーを作っていきます。
№3.自分の石を置ける場所の判定の整理
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第3回です。いよいよ自分の石を置いて、相手の石をひっくり返す処理に進むのですが、その前に、そもそも自分の石を置ける場所はどこなのか…。クリックしたセルは、自分の石を置いて良いセルなのかの判定が必要です。
№4.自分の石を置ける場所の判定の実装
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第4回です。石を置ける場所の定義を、前回は文章で書きました、今回は、それをもとにマクロVBAのプログラミングをしていきます。考え方は決定しているので、後はVBAに翻訳(コーディング)していくだけです。
№5.シート機能を拡張して今後の準備
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第5回です。前回で石を置ける場所の判定が完成しましたので、これからは、ゲームとしての機能を一つずつ追加していきます。まずは、石を置ける場所の色を変更してわかりやすくしてみます。
№6.黒石白石を交互に打って相手の石をひっくり返す
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第6回です。いよいよ今回は、黒石白石を交互に打てるようにします。もちろん、相手の石を挟んでいる場所は、自分の石に取り替えます。
№7.パス確認、終局確認、石数取得
マクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第7回です。前回までで、黒石白石を交互に打つことができるようになりましたが、まだまた不都合な点があります。石を打つ場所がない時に、パスが出来ないから先に進まない… 全部石が埋まっても、何も変化がない… そもそも、どっちが勝っているのかもわからない……
№8.石を置ける場所の表示とアニメーション
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第8回です。前回までで大分ゲームらしくなってきました。そろそろ、PC対戦の機能を入れたいところですが、今回は、はPC対戦の機能を入れる前に、気になる細かい部分を変更しておきます。
№9.PC対戦の実装
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第9回です。前回までで人が打つのであれば不自由のない機能が実装できたと思います。さて、ここからはPC対戦の機能を入れていきます。
№10.置く場所に重みを付けて少しだけ強く
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第10回です。前回は、PCが自動で打つ機能を実装しました。強さはともかく、とにかくPCが勝手に売ってくれるようになりました。
№11.相手の応手を評価してさらに強く
マクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第11回です。前回の石を置く場所に重みを付けることで、超々初心者なら勝てるかもしれないというレベルにはなりました。ですが、ある程度オセロをやった事のある人なら、まあ負けることはないでしょう 今回は、自分の打つ場所ではなく、
№12.PC対PCの対戦で強さを確認
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第12回です。前回は、相手の応手を判定して、自分の置く場所を決められるようにしました。オセロソフトとしては、そこそこの強さになりました。
№13.パラメーターと重みを調整してさらに強く
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第12回です。前回は、PC1からPC5までの5段階の状態で、総当り対戦で強さを判定しましたが、PC5が最も強い事が確認出来ました。それでもPC5では、まだまだ、ある程度オセロをやった事のある人には勝てないレベルです。
№14.やはり「待った」が欲しい
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第14回です。前回で、6段階の強さのPCオセロが完成しました、一番強いPC6でも、まだまだそれほどの強さとは言えませんが、初心者の人なら苦戦するでしょうし、私も油断すれば負けてしまうくらいの強さにはなっています。
№15.棋譜で対局を再現
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第15回です。棋譜が扱えるようになり、「待った」の実装も出来ました。棋譜が扱えるようになったので、今回は、対局を再現できるようにします。
№16.これまでを振り返りつつ全体のまとめ
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第16回です。15回に渡って、オセロ作成をしてきました、マクロVBAコードはかなりの量になっています。今回は最終回として、これまでを振り返ってみます。


ここまでのサンプルファイルのダウンロード




新着記事NEW ・・・新着記事一覧を見る

抜けている数値を探せ|エクセル雑感(2022-07-01)
.Net FrameworkのSystem.Collectionsを利用|VBA技術解説(2022-06-29)
迷路ネコが影分身の術を体得したら…|エクセル雑感(2022-06-27)
迷路にネコが挑戦したら、どうなるかな…|エクセル雑感(2022-06-26)
サロゲートペアに対応した自作関数(Len,Left,Mid,Right)|エクセル雑感(2022-06-24)
「マクロの登録」で登録できないプロシージャーは?|エクセル雑感(2022-06-23)
オブジェクトのByRef、ByVal、Variant|エクセル雑感(2022-06-22)
コメントから特定形式の年月を取り出す|エクセル雑感(2022-06-19)
4,9を使わない連番作成|エクセル雑感(2022-06-17)
連番を折り返して出力|エクセル雑感(2022-06-16)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.Excelショートカットキー一覧|Excelリファレンス
7.マクロって何?VBAって何?|VBA入門
8.並べ替え(Sort)|VBA入門
9.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
10.エクセルVBAでのシート指定方法|VBA技術解説




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ