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

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

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


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


前回までで、黒石白石を交互に打つことができるようになりましたが、まだまた不都合な点があります。

石を打つ場所がない時に、パスが出来ないから先に進まない・・・
全部石が埋まっても、何も変化がない・・・
そもそも、どっちが勝っているのかもわからない・・・


つまり、

・パス確認
・終局確認
・石数取得


今回は、これらの機能を追加していきます。
先に、石数を表示するようにシートを少し変更しておきます。

シートの変更
シート保護の解除をしてください。

マクロVBA参考画像

スクロールエリアを解除します。

マクロVBA参考画像

この「ScrollArea」の値を消去してください。

N2 : 黒石の数を表示するセル、フォントと罫線を設定してください。
N3 : 黒石の数を表示するセル、フォントと罫線を設定してください。
M4 : 「残り」と入力して、、フォントを設定してください。。
N4 : 数式を設定してください。「=64-N2-N3」

マクロVBA参考画像



パス確認
パスとはどのような状態かを定義します。

手番の石(黒石or白石)がどこにも置けない状態
つまり、盤面の全てのセルで、
プロシージャー「is置ける全方向」の戻り値がFalseの状態

以下を標準モジュールに追加してください。



Sub パス確認()
  Dim myRng As Range
  Dim isPass As Boolean
  With TargetSheet
    isPass = True
    For Each myRng In .Range("盤面")
      If is置ける全方向(myRng, True) Then
        isPass = False
        Exit For
      End If
    Next
    If isPass = True Then
      If .Range("手番石").Font.Color = .Range("先番石").Font.Color Then
        MsgBox "●先手番「" & Sheet1.cmb1.Text & "」" & vbLf & vbLf & "パス"
      Else
        MsgBox "○後手番「" & Sheet1.cmb2.Text & "」" & vbLf & vbLf & "パス"
      End If
      Call 手番交代
      Call 置ける場所表示
      Call 終局確認
    End If
  End With
End Sub

For Each myRng In .Range("盤面")
・・・
Next
これで、盤面の全てのセルを処理するようにして、
一つでもTrueが戻されれば石が置けるということです。
つまり、一つもTrueが返されない場合は、石を置く場所が無いという事です。

isPass
石を置く場所が無くパスの状態を、True
石を置く場所がある状態を、Flase
として使っています。



終局確認
終局とはどういう状態なのかを定義します。

・64マス全てに石が置かれた状態
・黒石白石、どちらも置く場所がない状態

以下を標準モジュールに追加してください。

Sub 終局確認()
  Dim myRng As Range
  Dim isPass As Boolean
  With TargetSheet
    If WorksheetFunction.CountA(.Range("盤面")) = 64 Then
      Call 終局処理
      End
    End If
    isPass = True
    For Each myRng In .Range("盤面")
      If is置ける全方向(myRng, True) Then
        isPass = False
      End If
    Next
    If isPass = True Then
      isPass = True
      Set 置く石 = 相手石
      For Each myRng In .Range("盤面")
        If is置ける全方向(myRng, True) Then
          isPass = False
        End If
      Next
      If isPass = True Then
        Call 終局処理
        End
      End If
    End If
  End With
  Call 共通変数設定
End Sub

Sub 終局処理()
  With TargetSheet
    Select Case True
      Case .Range("先番石").Offset(, 2).Value > .Range("後番石").Offset(, 2).Value
        MsgBox "終局" & vbLf & vbLf & "●先手番「" & Sheet1.cmb1.Text & "」の勝ちです。"
      Case .Range("先番石").Offset(, 2).Value < .Range("後番石").Offset(, 2).Value
        MsgBox "終局" & vbLf & vbLf & "○後手番「" & Sheet1.cmb2.Text & "」の勝ちです。"
      Case Else
        MsgBox "終局" & vbLf & vbLf & "引き分けです。"
    End Select
    .Range("手番石").Clear
    .Range("手番石").Offset(, 1).ClearContents
  End With
End Sub

実際には、
「黒石白石、どちらも置く場所がない状態」というのは、
「64マス全てに石が置かれた状態」この状態も含んでいるので、
「黒石白石、どちらも置く場所がない状態」これだけの判定でもよいのですが、
形式的にも、全て打ち終わった場合の判定を入れておいた方が良いだろうと思って入れています。

全ての石の数の取得は、
WorksheetFunction.CountA
・ワークシート関数の使い方 ・WorksheetFunctionで使用できる関数 ・個別の関数の使い方 ・関数の結果(戻り値) ・WorksheetFunctionの使用例. ・検索系の関数での日付の扱い ・WorksheetFunctionのエラー対処 ・最後に
これを使っています。



    For Each myRng In .Range("盤面")
      If is置ける全方向(myRng, True) Then
        isPass = False
      End If
    Next

これで、盤面のどこにも石が置けない状態を判定できますので、
黒石と白石の両方で検査すれば良いという事です。

終局処理
メッセージと手番石のクリア部分を別のプロシージャーにしているのは、
2箇所で必要になっているので、
無駄のないように別プロシージャーにしています。
勝敗の判定は、石数取得で設定しているセル数値数値を使っています。
L2セルL3セルに名前定義をしているので、そこから2列右ということで、
Offsetプロパティを使って、右に2列移動して取得しています。
・Offsetプロパティの構文 ・Offsetの使用例 ・Offsetの注意点 ・Offsetのまとめ


石数取得

石数の取得は、単純に黒石と白石のカウントをするだけです。

Sub 石数取得()
  Dim myRng As Range
  Dim cnt先番 As Long
  Dim cnt後番 As Long
  With TargetSheet
    For Each myRng In .Range("盤面")
      If myRng <> "" Then
        If myRng.Font.Color = .Range("先番石").Font.Color Then
          cnt先番 = cnt先番 + 1
        Else
          cnt後番 = cnt後番 + 1
        End If
      End If
    Next
    .Range("先番石").Offset(, 2) = cnt先番
    .Range("後番石").Offset(, 2) = cnt後番
  End With
End Sub

L2セルL3セルに名前定義をしているので、そこから2列右ということで、
Offsetプロパティを使って、右に2列移動したセルに設定しています。



大分ゲームらしくなってきました。
そろそろ、PC対戦の機能を入れたいところですが、
PC対戦となると、結構複雑になります。
そこで、次回はPC対戦の機能を入れる前に、
気になる細かい部分を変更しておきます。


№8へ続きます。
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第8回です。前回までで大分ゲームらしくなってきました。そろそろ、PC対戦の機能を入れたいところですが、今回は、はPC対戦の機能を入れる前に、気になる細かい部分を変更しておきます。

全体の目次
はじめに
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」をお願いいたします。
本文下部へ