オセロを作りながらマクロVBAを学ぼう№4
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第4回です。
今回は、それをもとにマクロVBAのプログラミングをしていきます。
考え方は決定しているので、後はVBAに翻訳(コーディング)していくだけです。
・8方向は、
For i = -1 To 1
For j = -1 To 1
これをネストする
・1方向に向かって順に置かれている石を判定
終了条件は、
・空白(石が置かれていない)
・自分の石が置かれている
自分の石が置かれていて終了した時、それまでに相手の石があるか
・8方向のいずれか一つでも、上記条件を満たせば、自分の石が置ける
セルをダブルクリックした時、
そこに石が置けるかどうかを判定し、メッセージボックスを表示するようにしてみます。

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


左オブジェクト選択のドロップタ゜ウンを「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オブジェクトです。

ここをダブルクリック
または、右クリックから「コードの表示」
これだけが入っているはずなので、その下に以下のコードを追加してください。
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
良く使うオブジェクトを
オブジェクト変数
パプリック変数
Public 置く石 As Range ・・・ 置く石が設定されているセル
Public 相手石 As Range ・・・ 相手の石が設定されているセル
この中で、パブリック変数を設定してから、 「is置ける全方向」を呼び出します。
Cancel = True
これは、ダブルクリックの後にセル編集状態にならないように、イベントを終了させるためのものです。
Functionプロシージャーの括弧()の中に引数が指定されています。
これは、プロシージャーに引数を渡しています。
「is置ける全方向」
これで8方向を判定できるようにしています。
実際には3×3=9方向なのですがも行0列0の移動は石を置きたい場所なので、
既に石が置いてある場合は置けない判定で直ぐに判定が終了しています。
If is置ける1方向(Target, i, j) Then
これで、1方向でも「置ける」判定であれば、「置ける」と返すようにしています。
ここでは、「is置ける全方向」から渡された方向について判定をします。
If is置く石 = True And is相手石 = True Then
これで、相手の石があって、その先に置く石があることを判定しています。
この違いで判定しているので、少しわかりずらいかもしれませんが、
個々のステートメントは極めて基本的なものだけとなっています。
ブール型は、True,Falseの2値をとる変数です。
つまり、ON,OFFや有,無等々の状態判定に使います。
その後に、複数の項目の状態を判定し、全体として条件を満たしているかどうかを判定しています。
これは、判定が複雑な場合に良く使う手法ですので、ぜひマスターして下さい。
この文章と、VBAコードを見比べて下さい。
参考程度ではありますが、VBA内にコメントを書いておきました。
石の配置を変更する場合は、シート保護を解除してからコピペで石を配置してください。
これで、オセロゲームの根本的な部分のロジックができましたので、
次回からは、ゲームとしての機能を一つずつ追加していきます。
全体の目次
ここまでのサンプルファイルのダウンロード
新着記事NEW ・・・新着記事一覧を見る
セル値でパス・ブック・シート名を指定|Power Query(M言語)入門(2023-02-07)
別ブックのシートを列可変で取り込む|Power Query(M言語)入門(2023-02-06)
ExcelとVBAの入門解説|エクセルの神髄(2022-12-14)
文字列のプロパティ名でオブジェクトを操作する方法|VBA技術解説(2022-12-14)
数字(1~50)を丸付き数字に変換するVBA|VBA技術解説(2022-11-15)
TEXTAFTER関数(テキストの指定文字列より後ろの部分を返す)|エクセル入門(2022-11-14)
TEXTBEFORE関数(テキストの指定文字列より前の部分を返す)|エクセル入門(2022-11-14)
TEXTSPLIT関数(列と行の区切り記号で文字列を分割)|エクセル入門(2022-11-12)
LAMBDA以降の新関数はVBAで使えるか|VBA技術解説(2022-11-11)
WRAPCOLS関数(1次元配列を指定数の列で折り返す)|エクセル入門(2022-11-08)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.繰り返し処理(For Next)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.マクロって何?VBAって何?|VBA入門
7.並べ替え(Sort)|VBA入門
8.Excelショートカットキー一覧|Excelリファレンス
9.エクセルVBAでのシート指定方法|VBA技術解説
10.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
- ホーム
- マクロVBA応用編
- マクロVBAサンプル集
- オセロを作りながらマクロVBAを学ぼう№4
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。