ExcelマクロVBAサンプル集 | オセロを作りながらマクロVBAを学ぼう8 | Excelマクロの実用サンプル、エクセルVBA集と解説



最終更新日:2017-12-06

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


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

前回までで大分ゲームらしくなってきました。

そろそろ、PC対戦の機能を入れたいところですが、
今回は、はPC対戦の機能を入れる前に、気になる細かい部分を変更しておきます。

追加・変更する機能は、
・石を置ける場所の色を変更するかどうかを選択できるようにする
・対戦途中で、「対戦開始」をクリックすると、いきなり初期配置になってしまうので、
 メッセージを出して確認するようにする。
・相手の石を自分の石に取り替える処理が速すぎて、ひっくり返している感じがないので、
 少しゆっくり石を取り換えて、アニメーションっぽくする。


シートの変更
シート保護の解除と、スクロールエリアの解除をしてください。



「置ける場所の色を変える」のチェックボックスを追加してください。



適当にドラッグして配置してください。

右クリックからプロパティで、
(オブジェクト名)

「chk置ける場所」
として下さい。



シートモジュール

「置ける場所の色を変える」のチェックボックスをクリックした時のイベントプロシージャーを挿入します。

以下を、シートモジュールに追加してください。
デザインモードで、チェックボックスをダブルクリックすると、空のイベントプロシージャーが作成されます。

Private Sub chk置ける場所_Click()
  If TargetSheet Is Nothing Then
    Exit Sub
  End If
  Unprotect
  If chk置ける場所.Value Then
    Call 置ける場所表示
  Else
    Range("盤面").Interior.Color = Range("ベース色").Interior.Color
  End If
  Protect
End Sub

チェックが付けられたときは、「置ける場所表示」をCallします。
チェックが外されたときは、盤面全体を初期色に設定します。



APIを使用する

Sleep(一定時間停止する)のAPIを使うために、標準モジュールの先頭にDeclareを追加します。

Option Explicit

Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

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

使う時は、
Sleep 200
ミリ秒で指定します。



対戦開始

以下の赤太字部分を追加してください。

Sub 対戦開始()
  With TargetSheet
    If WorksheetFunction.CountA(.Range("盤面")) > 4 Then
      If MsgBox("対局途中です。" & vbLf & vbLf & _
            "新規対局を開始してもよろしいですか?", _
            vbYesNo, "確認") = vbNo Then
        Exit Sub
      End If
    End If
    .Range("先番石").Copy Destination:=.Range("手番石")
    .Range("手番石").Offset(, 1) = "の番です。"
    .Range("盤面").ClearContents
    Call 共通変数設定
    Call 石を置く(.Range("盤面").Cells(4, 4), 置く石)
    Call 石を置く(.Range("盤面").Cells(5, 5), 置く石)
    Call 石を置く(.Range("盤面").Cells(4, 5), 相手石)
    Call 石を置く(.Range("盤面").Cells(5, 4), 相手石)
    Call 置ける場所表示
  End With
End Sub

WorksheetFunction.CountAで置かれている石の数を取得し、
4より多ければ確認メッセージを表示して確認しています。



置ける場所表示

以下の赤太字部分を追加してください。

Sub 置ける場所表示()
  Dim myRng As Range
  With TargetSheet
    If Not Sheet1.chk置ける場所.Value Then
      Exit Sub
    End If
    .Range("盤面").Interior.Color = .Range("ベース色").Interior.Color
    For Each myRng In .Range("盤面")
      If is置ける全方向(myRng, True) Then
        myRng.Interior.Color = .Range("置ける場所色").Interior.Color
      End If
    Next
  End With
End Sub

chk置ける場所のチェックがついていない時は、Subプロシージャーを抜けています。



石を置くときの処理 ・・・ is置ける1方向

以下の赤太字部分が変更箇所です。

Function is置ける1方向(ByVal Target As Range, _
      ByVal i As Long, _
      ByVal j As Long, _
      ByVal isTry As Boolean) As Boolean
  Dim r As Long
  Dim c As Long
  Dim is置く石 As Boolean
  Dim is相手石 As Boolean
  Dim myRng As Range
  Dim myRng2 As Range
  '石を置くセルの行列位置
  r = Target.Row
  c = Target.Column
  Set myRng = Nothing
  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
        If myRng Is Nothing Then
          Set myRng = .Cells(r, c)
        Else
          Set myRng = Union(myRng, .Cells(r, c))
        End If
      End If
    Loop
  End With
  '自分の石が置かれていて終了した時、それまでに相手の石があるか
  If is置く石 = True And is相手石 = True Then
    is置ける1方向 = True
    If Not isTry Then
      Call 石を置く(Target, 置く石)
      Sleep 200
      For Each myRng2 In myRng
        Sleep 100
        Call 石を置く(myRng2, 置く石)
      Next
    End If
  End If
End Function

手番の石を置いた後、200ミリ秒待ちます。
相手の石を取り換える時は、まとめてではなく、一つずつ取り替えます。
そしてその都度、100ミリ秒待ちます。

待ち時間のミリ秒は適当に設定しています。
長すぎると遅く感じるし、短すぎると効果が分からなくなっしまいます。



さて、これでPC対戦の準備が出来ました。
いよいよ、次回からは、PC対戦を実現します。
まずは強さは考えずに、
とにかくPCが自動で打つ機能を実現していきます。


9へ続きます。

全体の目次


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




同じテーマ「ExcelマクロVBAサンプル集」の記事

アメブロの記事本文をVBAでバックアップする1
数独(ナンプレ)を解くVBAに挑戦1
数独(ナンプレ)を解くアルゴリズムの要点とパフォーマンスの検証1
ナンバーリンク(パズル)を解くVBAに挑戦1
ナンバーリンクを解くVBAのパフォーマンス改善1

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

大量VlookupをVBAで高速に処理する方法について|ExcelマクロVBA技術解説(12月12日)
オセロを作りながらマクロVBAを学ぼう|ExcelマクロVBAサンプル集(11月26日)
ScreenUpdating=False時にエラー停止後にシートが固まったら|ExcelマクロVBA技術解説(11月21日)
データクレンジングと名寄せ|ExcelマクロVBA技術解説(10月20日)
SUMIFの間違いによるパフォーマンスの低下について|エクセル関数超技(6月17日)
条件式のいろいろな書き方:TrueとFalseの判定とは|ExcelマクロVBA技術解説(6月15日)
空白セルを正しく判定する方法2|ExcelマクロVBA技術解説(5月6日)
フルパスをディレクトリ、ファイル名、拡張子に分ける|ExcelマクロVBA技術解説(4月15日)
テキストボックスの各種イベント|Excelユーザーフォーム入門(4月9日)
フォルダ(サブフォルダも全て)削除する、Optionでファイルのみ削除|ExcelマクロVBAサンプル集(4月4日)

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

1.最終行の取得(End,Rows.Count)|ExcelマクロVBA入門
2.RangeとCellsの使い分け方|ExcelマクロVBA入門
3.変数とデータ型(Dim)|ExcelマクロVBA入門
4.Range以外の指定方法(Cells,Rows,Columns)|ExcelマクロVBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|ExcelマクロVBA入門
6.定数と型宣言文字(Const)|ExcelマクロVBA入門
7.マクロって何?VBAって何?|ExcelマクロVBA入門
8.CSVの読み込み方法|ExcelマクロVBAサンプル集
9.徹底解説(VLOOKUP,MATCH,INDEX,OFFSET)|エクセル関数超技
10.ひらがな⇔カタカナの変換|エクセル基本操作



  • >
  • >
  • >
  • オセロを作りながらマクロVBAを学ぼう8

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


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

    ↑ PAGE TOP